The HTTP server, also referred to as httpd, handles HTTP requests
as described in
The server implements numerous features, such as:
The configuration of the server is provided as an Erlang property list. For backwards compatibility, a configuration file using apache-style configuration directives is supported.
As of
Almost all server functionality has been implemented using an especially crafted server API, which is described in the Erlang Web Server API. This API can be used to enhance the core server functionality, for example with custom logging and authentication.
The following is to be put in the Erlang node application configuration file to start an HTTP server at application startup:
[{inets, [{services, [{httpd, [{proplist_file,
"/var/tmp/server_root/conf/8888_props.conf"}]},
{httpd, [{proplist_file,
"/var/tmp/server_root/conf/8080_props.conf"}]}]}]}].
The server is configured using an Erlang property list.
For the available properties, see
The available configuration properties are as follows:
httpd_service() -> {httpd, httpd()}
httpd() -> [httpd_config()]
httpd_config() -> {file, file()} |
{proplist_file, file()}
{debug, debug()} |
{accept_timeout, integer()}
debug() -> disable | [debug_options()]
debug_options() -> {all_functions, modules()} |
{exported_functions, modules()} |
{disable, modules()}
modules() -> [atom()]
Here:
If you use an old apace-like configuration file.
File containing an Erlang property list, followed by a full stop, describing the HTTP server configuration.
Can enable trace on all functions or only exported functions on chosen modules.
Sets the wanted time-out value for the server to set up a request connection.
Start
1 > inets:start().
ok
Start an HTTP server with minimal required configuration.
If you specify port
2 > {ok, Pid} = inets:start(httpd, [{port, 0},
{server_name,"httpd_test"}, {server_root,"/tmp"},
{document_root,"/tmp/htdocs"}, {bind_address, "localhost"}]).
{ok, 0.79.0}
Call
3 > httpd:info(Pid).
[{mime_types,[{"html","text/html"},{"htm","text/html"}]},
{server_name,"httpd_test"},
{bind_address, {127,0,0,1}},
{server_root,"/tmp"},
{port,59408},
{document_root,"/tmp/htdocs"}]
Reload the configuration without restarting the server:
4 > httpd:reload_config([{port, 59408},
{server_name,"httpd_test"}, {server_root,"/tmp/www_test"},
{document_root,"/tmp/www_test/htdocs"},
{bind_address, "localhost"}], non_disturbing).
ok.
5 > httpd:info(Pid, [server_root, document_root]).
[{server_root,"/tmp/www_test"},{document_root,"/tmp/www_test/htdocs"}]
6 > ok = inets:stop(httpd, Pid).
Alternative:
6 > ok = inets:stop(httpd, {{127,0,0,1}, 59408}).
Notice that
Web server users without server administrative privileges
that need to manage authentication of web pages that are local
to their user can use the per-directory runtime configurable
user-authentication scheme
In every directory under
Syntax:
Default:
Same as directive
Syntax:
Default:
If only one access file exists, setting this parameter to
Syntax:
Default:
GroupName: Member1 Member2 .... MemberN
Syntax:
Default:
Same as directive
Syntax:
Default:
Syntax:
Default:
UserName:Password UserName:Password
Syntax:
Context: Limit
Same as directive
Syntax:
Default:
Example:
<Limit POST GET HEAD> order allow deny require group group1 allow from 123.145.244.5 </Limit>
Syntax:
Default:
If the order is set to
If the order is set to
Syntax:
Default:
Context: Limit
For more information, see directive
Common Gateway Interface (CGI) scripts can be written in any programming language. CGI scripts are standardized and supported by most web servers. The drawback with CGI scripts is that they are resource-intensive because of their design. CGI requires the server to fork a new OS process for each executable it needs to start.
Erlang Server Interface (ESI) functions provide a tight and efficient
interface to the execution of Erlang functions. This interface,
on the other hand, is
The module
The CGI script response comprises a message header and a message body, separated by a blank line. The message header contains one or more header fields. The body can be empty.
Example:
"Content-Type:text/plain\nAccept-Ranges:none\n\nsome very
plain text"
The server interprets the message headers and most of them are transformed into HTTP headers and sent back to the client together with the message-body.
Support for CGI-1.1 is implemented in accordance with
The Erlang server interface is implemented by
module
The erl scheme is designed to mimic plain CGI, but without
the extra overhead. An URL that calls an Erlang
http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)
*** depends on how the ErlScriptAlias config directive has been used.
The module
The eval scheme is straight-forward and does not mimic the
behavior of plain CGI. An URL that calls an Erlang
http://your.server.org/***/Mod:Func(Arg1,...,ArgN)
*** depends on how the ErlScriptAlias config directive has been used.
The module
The eval scheme can seriously threaten the integrity of the Erlang node housing a web server, for example:
http://your.server.org/eval?httpd_example:print(atom_to_list(apply(erlang,halt,[])))
This effectively closes down the Erlang node. Therefore, use the erl scheme instead, until this security breach is fixed.
Today there are no good ways of solving this problem
and therefore the eval scheme can be removed in future
release of
Three types of logs are supported: transfer logs, security logs, and error logs. The de-facto standard Common Logfile Format is used for the transfer and security logging. There are numerous statistics programs available to analyze Common Logfile Format. The Common Logfile Format looks as follows:
remotehost rfc931 authuser [date] "request" status bytes
Here:
Internal server errors are recorded in the error log file. The format of this file is a more unplanned format than the logs using Common Logfile Format, but conforms to the following syntax:
[date] access to path failed for remotehost, reason: reason
The process of handling an HTTP request involves several steps, such as:
To provide customization and extensibility of the request
handling of the HTTP servers, most of these steps are handled by
one or more modules. These modules can be replaced or removed at
runtime and new ones can be added. For each request, all modules are
traversed in the order specified by the module directive in the
server configuration file. Some parts, mainly the communication-
related steps, are considered server core functionality and are
not implemented using the Erlang web server API. A description of
functionality implemented by the Erlang webserver API is described
in
A module can use data generated by previous modules in the Erlang webserver API module sequence or generate data to be used by consecutive Erlang Web Server API modules. This is possible owing to an internal list of key-value tuples, referred to as interaction data.
Interaction data enforces module dependencies and is to be avoided if possible. This means that the order of modules in the modules property is significant.
Each module that implements server functionality using the Erlang web server API is to implement the following call back functions:
The latter functions are needed only when new config
directives are to be introduced. For details, see
The convention is that
all modules implementing some web server functionality has the
name
This module runs CGI scripts whenever a file of a
certain type or HTTP method (see
Uses the following Erlang Web Server API interaction data:
Exports the following Erlang Web Server API interaction data, if possible:
The
Exports the following Erlang Web Server API interaction data, if possible:
The
Uses the following Erlang Web Server API interaction data:
Exports the following Erlang Web Server API interaction data:
If Mnesia is used as storage method, Mnesia must be
started before the HTTP server. The first time Mnesia is
started, the schema and the tables must be created before
Mnesia is started. A simple example of a module with two
functions that creates and start Mnesia is provided
here. Function
-module(mnesia_test).
-export([start/0,load_data/0]).
-include_lib("mod_auth.hrl").
first_start() ->
mnesia:create_schema([node()]),
mnesia:start(),
mnesia:create_table(httpd_user,
[{type, bag},
{disc_copies, [node()]},
{attributes, record_info(fields,
httpd_user)}]),
mnesia:create_table(httpd_group,
[{type, bag},
{disc_copies, [node()]},
{attributes, record_info(fields,
httpd_group)}]),
mnesia:wait_for_tables([httpd_user, httpd_group], 60000).
start() ->
mnesia:start(),
mnesia:wait_for_tables([httpd_user, httpd_group], 60000).
To create the Mnesia tables, we use two records defined in
This module handles invoking of CGI scripts.
This module generates an HTML directory listing (Apache-style) if a client sends a request for a directory instead of a file. This module must be removed from the Modules config directive if directory listings is unwanted.
Uses the following Erlang Web Server API interaction data:
Exports the following Erlang Web Server API interaction data:
Standard logging using the "Common Logfile Format" and
Uses the following Erlang Web Server API interaction data:
The
Uses the following Erlang web server API interaction data:
Exports the following Erlang web server API interaction data:
This module is responsible for handling GET requests to regular
files. GET requests for parts of files is handled by
Uses the following Erlang web server API interaction data:
This module is responsible for handling HEAD requests to regular files. HEAD requests for dynamic content is handled by each module responsible for dynamic content.
Uses the following Erlang Web Server API interaction data:
This module provides per-directory user configurable access control.
Uses the following Erlang Web Server API interaction data:
Exports the following Erlang Web Server API interaction data:
Standard logging using the "Common Logfile Format" and text files.
Uses the following Erlang Web Server API interaction data:
This module responses to requests for one or many ranges of a file. This is especially useful when downloading large files, as a broken download can be resumed.
Notice that request for multiple parts of a document report a size of zero to the log file.
Uses the following Erlang Web Server API interaction data:
This module controls that the conditions in the requests are fulfilled. For example, a request can specify that the answer only is of interest if the content is unchanged since the last retrieval. If the content is changed, the range request is to be converted to a request for the whole file instead.
If a client sends more than one of the header fields that
restricts the servers right to respond, the standard does not
specify how this is to be handled.
Uses the following Erlang Web Server API interaction data:
Exports the following Erlang Web Server API interaction data:
The
There is also an API to block or unblock users manually. This API can also list blocked users or users who have been authenticated within a configurable amount of time.