# httpd

### MODULE

httpd

### MODULE SUMMARY

An implementation of an HTTP 1.1 compliant Web server, as defined in RFC 2616.

### DESCRIPTION

Mainly specifies the Erlang Webserver callback API but also provide some test and admin. functionality.

### DATA TYPES

          ModData = #mod{}

          -record(mod, {
                    data = [],
                    socket_type = ip_comm,
                    socket,
                    config_db,
                    method,
                    absolute_uri,
                    request_uri,
                    http_version,
                    request_line,
                    parsed_header = [],
                    entity_body,
                    connection
                   }).

The fields of the `mod` record has the following meaning:

`data`
  Type `[{InteractionKey,InteractionValue}]` is used to propagate data between modules. Depicted `interaction_data()` in function type declarations.
`socket_type`
  `socket_type()`, Indicates whether it is a ip socket or a ssl socket.
`socket`
  The actual socket in `ip_comm` or `ssl` format depending on the `socket_type`.
`config_db`
  The config file directives stored as key-value tuples in an ETS-table. Depicted `config_db()` in function type declarations.
`method`
  Type `"GET" | "POST" | "HEAD" | "TRACE"`, that is the HTTP metod.
`absolute_uri`
  If the request is a HTTP/1.1 request the URI might be in the absolute URI format. In that case httpd will save the absolute URI in this field. An Example of an absolute URI could be`"http://ServerName:Part/cgi-bin/find.pl?person=jocke"`
`request_uri`
  The `Request-URI` as defined in RFC 1945, for example `"/cgi-bin/find.pl?person=jocke"`
`http_version`
  The `HTTP` version of the request, that is "HTTP/0.9", "HTTP/1.0", or "HTTP/1.1".
`request_line`
  The `Request-Line` as defined in RFC 1945, for example `"GET /cgi-bin/find.pl?person=jocke HTTP/1.0"`.
`parsed_header`
  Type `[{HeaderKey,HeaderValue}]`, `parsed_header` contains all HTTP header fields from the HTTP-request stored in a list as key-value tuples. See RFC 2616 for a listing of all header fields. For example the date field would be stored as: `{"date","Wed, 15 Oct 1997 14:35:17 GMT"}. RFC 2616 defines that HTTP is a case insensitive protocol and the header fields may be in lowercase or upper case. Httpd will ensure that all header field names are in lowe case`.
`entity_body`
  The `Entity-Body` as defined in RFC 2616, for example data sent from a CGI-script using the POST method.
`connection`
  `true | false` If set to true the connection to the client is a persistent connections and will not be closed when the request is served.

### Erlang Webserver API Callback Functions

### EXPORTS

`Module:do(ModData)-> {proceed, OldData} | {proceed, NewData} | {break, NewData} | done`

Types:

`OldData = list()`
`NewData = [{response,{StatusCode,Body}}] | [{response,{response,Head,Body2}}] | [{response,{already_sent,Statuscode,Size}]`
`StausCode = integer()`
`Body = io_list() | nobody | {Fun, Arg}`
`Head = [HeaderOption]`
`HeaderOption = {Key, Value} | {code, StatusCode}`
`Key = allow | cache_control | content_MD5 | content_encoding | content_encoding | content_language | content_length | content_location | content_range | content_type | date | etag | expires | last_modified | location | pragma | retry_after | server | trailer | transfer_encoding`
`Value = string()`
`Fun = fun( Arg ) -> sent| close | Body`
`Arg = [term()]`

When a valid request reaches httpd it calls `do/1` in each module defined by the Modules configuration directive. The function may generate data for other modules or a response that can be sent back to the client.

The field `data` in ModData is a list. This list will be the list returned from the from the last call to `do/1`.

`Body` is the body of the http-response that will be sent back to the client an appropriate header will be appended to the message. `StatusCode` will be the status code of the response see RFC2616 for the appropriate values.

`Head` is a key value list of HTTP header fields. the server will construct a HTTP header from this data. See RFC 2616 for the appropriate value for each header field. If the client is a HTTP/1.0 client then the server will filter the list so that only HTTP/1.0 header fields will be sent back to the client.

If `Body2` is returned and equal to `{Fun,Arg}` The Web server will try `apply/2`. on `Fun` with `Arg` as argument and excpect that the fun either returns a list `(Body)` that is a HTTP-repsonse or the atom sent if the HTTP-response is sent back to the client. If close is returned from the fun something has gone wrong and the server will signal this to the client by closing the connection.

`Module:load(Line, Context)-> eof | ok | {ok, NewContext} | {ok, NewContext, Directive} | {ok, NewContext, DirectiveList} | {error, Reason}`

Types:

`Line = string()`
`Context = NewContext = DirectiveList = [Directive]`
`Directive = {DirectiveKey , DirectiveValue}`
`DirectiveKey = DirectiveValue = term()`
`Reason = term()`

`load/2` takes a row `Line` from the configuration file and tries to convert it to a key value tuple. If a directive is dependent on other directives, the directive may create a context. If the directive is not dependent on other directives return `{ok, [], Directive}`, otherwise return a new context, that is `{ok, NewContext}` or {ok, Context Directive}. If `{error, Reason}` is returned the configuration directive is assumed to be invalid.

`Module:store({DirectiveKey, DirectiveValue}, DirectiveList)-> {ok, {DirectiveKey, NewDirectiveValue}} | {ok, [{ok, {DirectiveKey, NewDirectiveValue}} | {error, Reason}`

Types:

`DirectiveList = [{DirectiveKey, DirectiveValue}]`
`DirectiveKey = DirecitveValue = term()`
`Context = NewContext = DirectiveList = [Directive]`
`Directive = {Key , Value}`
`Reason = term()`

When all rows in the configuration file is read the function `store/2` is called for each configuration directive. This makes it possible for a directive to alter other configuration directives. `DirectiveList` is a list of all configuration directives read in from load. If a directive may update other configuration directives then use this function.

`Module:remove(ConfigDB)-> ok | {error, Reason}`

Types:

`ConfigDB = ets_table()`
`Reason = term()`

When httpd shutdown it will try to execute `remove/1` in each ewsapi module. The ewsapi programmer may use this to close ets tables, save data, or close down background processes.

### Erlang Webserver API Help Functions

### EXPORTS

`parse_query(QueryString) -> ServerRet`

Types:

`QueryString = string()`
`ServerRet = [{Key,Value}]`
`Key = Value = string()`

`parse_query/1` parses incoming data to `erl` and `eval` scripts (See mod_esi(3)) as defined in the standard URL format, that is '+' becomes 'space' and decoding of hexadecimal characters (`%xx`).

### Erlang Webserver Test and Admin Functions

### EXPORTS

`start()`
`start(Config) -> ServerRet`
`start_link()`
`start_link(Config) -> ServerRet`

Types:

`Config = string() | HttpdOptions`
`ServerRet = {ok,Pid} | ignore | {error,EReason} | {stop,SReason}`
`Pid = pid()`
`EReason = {already_started, Pid} | term()`
`SReason = string()`
`HttpdOptions = {file,string()} , {debug,Debug}? , {accept_timeout,integer()}?`
`Debug = disable | [DebugOptions]`
`DebugOptions = {all_functions,Modules} | {exported_functions,Modules} | {disable,Modules}`
`Modules = [atom()]`

`start/1` and `start_link/1` starts a server as specified in the given `ConfigFile`. The `ConfigFile` supports a number of config directives specified below.

`start/0` and `start/0` starts a server as specified in a hard-wired config file, that is `start("/var/tmp/server_root/conf/8888.conf")`. Before utilizing `start/0` or `start_link/0`, copy the example server root (`UNIX: $INETS_ROOT/examples/server_root/, Windows: %INETS_ROOT%\examples\server_root\`) to a specific installation directory (`UNIX: /var/tmp/, Windows: X:\var\tmp\`) and you have a server running in no time.

If you copy the example server root to the specific installation directory it is furthermore easy to start an SSL enabled server, that is `start("/var/tmp/server_root/conf/ssl.conf")`.

`restart()`
`restart(Port) -> ok | {error,Reason}`
`restart(ConfigFile) -> ok | {error,Reason}`
`restart(Address,Port) -> ok | {error,Reason}`

Types:

`Port = integer()`
`Address = {A,B,C,D} | string() | undefined`
`ConfigFile = string()`
`Reason = term()`

`restart` restarts the server and reloads its config file.

The follwing directives cannot be changed: BindAddress, Port and SocketType. If these should be changed, then a new server should be started instead.

| Before the `restart` function can be called the server must be blocked. After `restart` has been called, the server must be unblocked.

`stop()`
`stop(Port) -> ServerRet`
`stop(ConfigFile) -> ServerRet`
`stop(Address,Port) -> ServerRet`

Types:

`Port = integer()`
`Address = {A,B,C,D} | string() | undefined`
`ConfigFile = string()`
`ServerRet = ok | not_started`

`stop/2` stops the server which listens to the specified `Port` on `Address`. `stop(integer())` stops a server which listens to a specific `Port`. `stop(string())` extracts `BindAddress` and `Port` from the config file and stops the server which listens to the specified `Port` on `Address`. `stop/0` stops a server which listens to port 8888, that is `stop(8888)`.

`block() -> ok | {error,Reason}`
`block(Port) -> ok | {error,Reason}`
`block(ConfigFile) -> ok | {error,Reason}`
`block(Address,Port) -> ok | {error,Reason}`
`block(Port,Mode) -> ok | {error,Reason}`
`block(ConfigFile,Mode) -> ok | {error,Reason}`
`block(Address,Port,Mode) -> ok | {error,Reason}`
`block(ConfigFile,Mode,Timeout) -> ok | {error,Reason}`
`block(Address,Port,Mode,Timeout) -> ok | {error,Reason}`

Types:

`Port = integer()`
`Address = {A,B,C,D} | string() | undefined`
`ConfigFile = string()`
`Mode = disturbing | non_disturbing`
`Timeout = integer()`
`Reason = term()`

This function is used to block a server. The blocking can be done in two ways, disturbing or non-disturbing.

By performing a disturbing block, the server is blocked forcefully and all ongoing requests are terminated. No new connections are accepted. If a timeout time is given then on-going requests are given this much time to complete before the server is forcefully blocked. In this case no new connections is accepted.

A non-disturbing block is more gracefull. No new connections are accepted, but the ongoing requests are allowed to complete. If a timeout time is given, it waits this long before giving up (the block operation is aborted and the server state is once more not-blocked)

Default mode is disturbing.

Default port is 8888

`unblock() -> ok | {error,Reason}`
`unblock(Port) -> ok | {error,Reason}`
`unblock(ConfigFile) -> ok | {error,Reason}`
`unblock(Address,Port) -> ok | {error,Reason}`

Types:

`Port = integer()`
`Address = {A,B,C,D} | string() | undefined`
`ConfigFile = string()`
`Reason = term()`

Unblocks a server. If the server is already unblocked this is a no-op. If a block is ongoing, then it is aborted (this will have no effect on ongoing requests).

### AUTHORS

Joakim Grebenö - support@erlang.ericsson.se
Torbjörn Törnkvist - support@erlang.ericsson.se
Joe Armstrong - support@erlang.ericsson.se
Ingela Anderton Andin - support@erlang.ericsson.se

inets 4.7.8
Copyright © 1991-2007 Ericsson AB