inets

v9.7

Inets Release Notes

Inets 9.7

Fixed Bugs and Malfunctions

A call to httpd:reload_config/2 now validates the new configuration before removing the old one, leaving the server running in case of faulty config, instead of putting it in an unrecoverable state.

Own Id: OTP-20128 Aux Id: PR-11079, ERIERL-1314

Improvements and New Features

A new option max_connections_open has been added to the httpc HTTP client profile configuration. It limits the maximum number of concurrent HTTP handler processes that can be open simultaneously.

When the limit is reached, new requests are queued internally and started automatically as existing handlers complete. This prevents bandwidth exhaustion in high-load scenarios where too many parallel connections cause remote servers to close sockets before transfers finish (the socket_closed_remotely error).

The option can be set via httpc:set_options([{max_connections_open, 10}], Profile).

The default value is infinity (unlimited), preserving backward compatibility. The value must be a positive integer or infinity and must be greater than or equal to max_sessions.

Own Id: OTP-19587 Aux Id: GH-8841, PR-9712

The legacy and and or operators have been replaced with other language constructs.

Own Id: OTP-19744 Aux Id: PR-10114, PR-10554, PR-10568, PR-10579, PR-10585, PR-10598, PR-10710, PR-10718, PR-10580, PR-10730

Added support for -unsafe attributes, which is used to mark functions as unsafe to use.

This is similar to but separate from deprecation, and the compiler will by default now generate warnings for calls to functions in Erlang/OTP that are known to be always unsafe.

Furthermore, xref can now be used to find calls to functions in another application that lack a -doc attribute (undocumented_function_calls), calls to functions in another application marked -doc false. (private_function_calls), as well as calls to unsafe functions (unsafe_function_calls).

Own Id: OTP-20066 Aux Id: PR-10839

The mod_cgi and mod_actions modules are now deprecated and are scheduled to be removed in OTP 30.

Own Id: OTP-20071 Aux Id: PR-10950

There is a new Hardening guide with advice for configuring Inets to be more secure.

Own Id: OTP-20133 Aux Id: PR-11073

Inets 9.6.2.1

Fixed Bugs and Malfunctions

A call to httpd:reload_config/2 now validates the new configuration before removing the old one, leaving the server running in case of faulty config, instead of putting it in an unrecoverable state.

Own Id: OTP-20128 Aux Id: PR-11079, ERIERL-1314

Inets 9.6.2

Fixed Bugs and Malfunctions

Fixed authentication bypass in httpd when script_alias maps a URL to a directory outside document_root with mod_auth directory-based access controls. The mod_alias:which_alias/1 function now includes script_alias entries so authorization is evaluated against the correct path before CGI execution. CVE-2026-28808.

Own Id: OTP-20068

Improvements and New Features

Fixed typo in http_server.md guide

Own Id: OTP-20044 Aux Id: GH-10785, PR-10867

Expected error accept_socket_timeout in httpd_request_handler now exits gracefully, without generating a crash and supervisor reports.

Own Id: OTP-20052 Aux Id: ERIERL-1310, PR-10893

Inets 9.6.1

Fixed Bugs and Malfunctions

The httpd server now rejects HTTP requests containing multiple Content-Length headers with different values, returning a 400 Bad Request response. This prevents potential HTTP request smuggling attacks. Thanks Luigino Camastra at Aisle Research for responsibly disclosing this vulnerability

Own Id: OTP-20007 Aux Id: PR-10833, CVE-2026-23941

Inets 9.6

Improvements and New Features

Release applications, tests, and documentation are now placed in their respective directories. Source SBOM with more packages.

A make release application places only the necessary code in the release folder. The main change is that the documentation and examples are not part of the release folder anymore.

make release_docs places the documentation in the released code under the doc folder.

make release_tests places the tests in their own directory. It used to be the case that some source code was mixed with the tests, and this should not happen anymore.

The Software Bill of Materials places the examples folders as if they are part of the SPDX-otp-<app>-doc packge, instead of placing examples as if they were running source code.

Overall, this change cleans up many things that were not quite correct by definition, and everything should still continue to work as expected. To test a release, one can still run ./Install -minimal \pwd`and add the release to thePATH. After that, one can run tests as usual, going into the released tests directory, enteringtest_server` and running the emulator.

Improves the source Software-Bill-of-Materials

The improvements adds new SPDX relations for asmjit and zlib to be optional_components_of the Erlang/OTP project.

The autoconf scripts in make and erts have now been categorised as build_tool_of the Erlang/OTP project.

All remaining configure, configure.ac, config.h.in, Makefile.in, Makefile.src, EMakefile, and GNUMakefile are now part of a specific SPDX package with relation build_tool_of the Erlang/OTP project.

Own Id: OTP-19886 Aux Id: PR-10434

Added a new HttpOption {autoretry, timeout()} to httpc:request/4,5. This option allows the client to decide how to act upon receiving a Retry-After response header. The default behavior changes, as now only one retry is made before returning the error code, instead of retrying infinitely.

POTENTIAL INCOMPATIBILITY

Own Id: OTP-19892 Aux Id: ERIERL-1283, PR-10469

Httpc will not add a Content-Length header for requests, that do not have defined semantics for request content in RFC9110 and do not include content. The list includes methods: [GET, HEAD, OPTIONS, TRACE, DELETE]. The behavior for headers_as_is option remains unchanged.

Own Id: OTP-19928 Aux Id: PR-10521, GH-10513

Improved documentation and specs for do/1 callback in httpd module.

Own Id: OTP-19952 Aux Id: PR-10602, GH-10501

Inets 9.5

Fixed Bugs and Malfunctions

Fixed uri_string:uri_string() to string() type specs inside httpc.erl module.

Own Id: OTP-19835 Aux Id: PR-10242

Fixed a bug where request options were not applied to a https proxy connection.

Own Id: OTP-19875 Aux Id: PR-10369, GH-10368

Improvements and New Features

The usages of slave module in inets were removed. The httpd_bench_suite has been updated for SSL testing and is not skipped anymore. The httpd_load_test example has been removed completely as outdated.

Own Id: OTP-19717 Aux Id: PR-10064

Replace a call to application:which_applications() in httpc:set_options/2 with try...catch to reduce bottleneck.

Own Id: OTP-19884 Aux Id: GH-10282, PR-10307

Inets 9.4.2

Fixed Bugs and Malfunctions

Fixed a RFC 2616 violation, where a http request, made by httpc, without providing any options, would be sent with an empty TE header, without also having a TE value in the connection header. Now the default request doesn't send a TE header at all.

Own Id: OTP-19760 Aux Id: PR-10120, GH-10065

Inets 9.4.1

Fixed Bugs and Malfunctions

Fixed a bug where a request sent to httpd server which is using CGI script to generate a response, would pollute server's environment variable - HTTP_PROXY for that request. This bug is also known as httpoxy. More information: CVE-2016-1000107

Own Id: OTP-19729 Aux Id: PR-6223, GH-3392, CVE-2016-1000107

Inets 9.4

Fixed Bugs and Malfunctions

Replaced calls to deprecated crypto:start() with application:start(crypto).

Own Id: OTP-19485 Aux Id: PR-8592

Enhance specs of timeout for improving documentation and dialyzer analysis.

Own Id: OTP-19604 Aux Id: PR-9574

Improvements and New Features

Enhanced http client documentation.

Own Id: OTP-19520 Aux Id: PR-9516

Enhance made to mod_esi documentation

Own Id: OTP-19521 Aux Id: PR-9472

The license and copyright header has changed format to include an SPDX-License-Identifier. At the same time, most files have been updated to follow a uniform standard for license headers.

Own Id: OTP-19575 Aux Id: PR-9670

Inets Makefiles now create and use dependencies files for .erl files

Own Id: OTP-19624 Aux Id: PR-9101

Inets 9.3.2.5

Fixed Bugs and Malfunctions

A call to httpd:reload_config/2 now validates the new configuration before removing the old one, leaving the server running in case of faulty config, instead of putting it in an unrecoverable state.

Own Id: OTP-20128 Aux Id: PR-11079, ERIERL-1314

Inets 9.3.2.4

Fixed Bugs and Malfunctions

Fixed authentication bypass in httpd when script_alias maps a URL to a directory outside document_root with mod_auth directory-based access controls. The mod_alias:which_alias/1 function now includes script_alias entries so authorization is evaluated against the correct path before CGI execution. CVE-2026-28808.

Own Id: OTP-20068

Inets 9.3.2.3

Fixed Bugs and Malfunctions

The httpd server now rejects HTTP requests containing multiple Content-Length headers with different values, returning a 400 Bad Request response. This prevents potential HTTP request smuggling attacks. Thanks Luigino Camastra at Aisle Research for responsibly disclosing this vulnerability

Own Id: OTP-20007 Aux Id: PR-10833, CVE-2026-23941

Inets 9.3.2.2

Fixed Bugs and Malfunctions

Fixed uri_string:uri_string() to string() type specs inside httpc.erl module.

Own Id: OTP-19835 Aux Id: PR-10242

Inets 9.3.2.1

Fixed Bugs and Malfunctions

Fixed a bug where a request sent to httpd server which is using CGI script to generate a response, would pollute server's environment variable - HTTP_PROXY for that request. This bug is also known as httpoxy. More information: CVE-2016-1000107

Own Id: OTP-19729 Aux Id: PR-6223, GH-3392

Fixed a RFC 2616 violation, where a http request, made by httpc, without providing any options, would be sent with an empty TE header, without also having a TE value in the connection header. Now the default request doesn't send a TE header at all.

Own Id: OTP-19760 Aux Id: PR-10120, GH-10065

Inets 9.3.2

Fixed Bugs and Malfunctions

Improved robustness of httpd startup procedure.

Own Id: OTP-19486 Aux Id: ERIERL-1190, PR-9408

Inets 9.3.1

Fixed Bugs and Malfunctions

The HTTP client now correctly takes into account the full_result option when returning an asynchronous request.

POTENTIAL INCOMPATIBILITY

Own Id: OTP-19158

A synchronous httpc:request now timeouts after the Timeout specified in HttpOption {timeout, Timeout}.

Own Id: OTP-19221 Aux Id: ERIERL-1091, PR-8788, PR-8801

Fixed a bug where calling httpc:set_options/2 when one of keys: ipfamily or unix_socket, was not present, would cause the other value to get overriden by the default value. The validation of these options was also improved.

Own Id: OTP-19379 Aux Id: PR-8878, GH-8829

Improvements and New Features

The variable Env in the mod_esi callback will now have an additional property {connect_addr, Addr} indicating on which address the server received a connection.

Own Id: OTP-19377 Aux Id: ERIERL-1152, PR-9127

Inets 9.3

Improvements and New Features

The documentation for the httpd module has been improved, along with correction of headings and types.

Own Id: OTP-19171 Aux Id: PR-8578

Userinfo is now properly percent-decoded before usage in headers.

Own Id: OTP-19172 Aux Id: PR-8575

Inets 9.2

Improvements and New Features

Introduced a default value for httpd_server name configuration to improve ease of use.

POTENTIAL INCOMPATIBILITY

Own Id: OTP-18641 Aux Id: PR-7316

The httpd module has been extended with an API for simple serving directory content over HTTP. With this change, the current working directory can be served like this:

erl -S httpd

An arbitrary directory can be served like this:

erl -S httpd serve path/to/dir

Own Id: OTP-18727 Aux Id: PR-7299

Added -callback attributes to httpd, mod_esi, and mod_security.

Own Id: OTP-18786 Aux Id: PR-7700

Inets now uses a relative redirect with an absolute path to prevent whoever is running Inets from having to configure the ServerName to match the network-reachable host name of the server.

Own Id: OTP-18809 Aux Id: GH-7617, PR-7678

inets processes now use proc_lib:set_label/1 to improve observeability.

Own Id: OTP-18927 Aux Id: PR-8029

The documentation has been migrated to use Markdown and ExDoc.

Own Id: OTP-18955 Aux Id: PR-8026

The implementations of http_uri:encode/1 and http_uri:decode/1 are now replaced with their equivalent, but bug free versions from module uri_string, namely uri_string:quote/1 and uri_string:unquote/1.

POTENTIAL INCOMPATIBILITY

Own Id: OTP-19022

With this change, the API specs are updated.

Own Id: OTP-19033

Inets 9.1.0.7

Fixed Bugs and Malfunctions

A call to httpd:reload_config/2 now validates the new configuration before removing the old one, leaving the server running in case of faulty config, instead of putting it in an unrecoverable state.

Own Id: OTP-20128 Aux Id: PR-11079, ERIERL-1314

Inets 9.1.0.6

Fixed Bugs and Malfunctions

Fixed authentication bypass in httpd when script_alias maps a URL to a directory outside document_root with mod_auth directory-based access controls. The mod_alias:which_alias/1 function now includes script_alias entries so authorization is evaluated against the correct path before CGI execution. CVE-2026-28808.

Own Id: OTP-20068

Inets 9.1.0.5

Fixed Bugs and Malfunctions

The httpd server now rejects HTTP requests containing multiple Content-Length headers with different values, returning a 400 Bad Request response. This prevents potential HTTP request smuggling attacks. Thanks Luigino Camastra at Aisle Research for responsibly disclosing this vulnerability

Own Id: OTP-20007 Aux Id: PR-10833, CVE-2026-23941

Inets 9.1.0.4

Fixed Bugs and Malfunctions

Fixed uri_string:uri_string() to string() type specs inside httpc.erl module.

Own Id: OTP-19835 Aux Id: PR-10242

Inets 9.1.0.3

Fixed Bugs and Malfunctions

Fixed a bug where a request sent to httpd server which is using CGI script to generate a response, would pollute server's environment variable - HTTP_PROXY for that request. This bug is also known as httpoxy. More information: CVE-2016-1000107

Own Id: OTP-19729 Aux Id: PR-6223, GH-3392

Fixed a RFC 2616 violation, where a http request, made by httpc, without providing any options, would be sent with an empty TE header, without also having a TE value in the connection header. Now the default request doesn't send a TE header at all.

Own Id: OTP-19760 Aux Id: PR-10120, GH-10065

Inets 9.1.0.2

Fixed Bugs and Malfunctions

Fixed a bug where calling httpc:set_options/2 when one of keys: ipfamily or unix_socket, was not present, would cause the other value to get overriden by the default value. The validation of these options was also improved.

Own Id: OTP-19379 Aux Id: PR-8878, GH-8829

Inets 9.1.0.1

Fixed Bugs and Malfunctions

With this change, HTTP client, when returning an asynchronous request, now correctly takes into account `OptionRequest - full_result`

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-19158

With this change, synchronous httpc:request now timeouts after `Timeout` specified in `HttpOption {timeout, Timeout}`

Own Id: OTP-19221 Aux Id: ERIERL-1091, PR-8788, PR-8801

Inets 9.1

Fixed Bugs and Malfunctions

Replaced unintentional Erlang Public License 1.1 headers in some files with the intended Apache License 2.0 header.

Own Id: OTP-18815 Aux Id: PR-7780

Correct IP protocol handling so that redirects always uses correct IP-family options and not fails.

Own Id: OTP-18855

Improvements and New Features

inets app starts ssl by default

Own Id: OTP-18735 Aux Id: PR-7596, GH-7580

Avoid httpd returning 500 internal server error when unable to open a file. 404 or 503 will be returned instead.

Own Id: OTP-18882

Properly handle documented option mime_type, for backwards compatibility fallback to undocumented option default_type if mime_type is not set.

Own Id: OTP-18891 Aux Id: PR-7843, GH-7827

Inets 9.0.2

Fixed Bugs and Malfunctions

With this change, re_write httpd works as expected and does not return error.

Own Id: OTP-18582 Aux Id: GH-6074,PR-6892

Fixed a bug so httpd does not crash when stopped at the wrong time during TLS connection negotiation, or any other theoretically as slow connection setup.

Own Id: OTP-18688 Aux Id: ERIERL-962

Enhance error handling and avoid that the HTTP client hangs on headers provided on the wrong format.

Own Id: OTP-18694 Aux Id: GH-7482

With this change, error report generated by httpd during connection setup contains socket type information.

Own Id: OTP-18704 Aux Id: ERIERL-962, PR-7513, OTP-18688

Stop and restart of the httpd server in the Inets application has been refactored to a more synchronous and OTP supervisor friendly approach.

This should increase stability and for example avoid a supervisor report from httpd_connection_sup about killed child process(es) in some cases when stopping or restarting httpd.

Own Id: OTP-18708 Aux Id: ERIERL-962, OTP-18688

Inets 9.0.1

Fixed Bugs and Malfunctions

Do not make the default ssl options by calling httpc:ssl_verify_host_options(true) if ssl options are supplied by the user.

Own Id: OTP-18604 Aux Id: PR-7306 GH-7303

Inets 9.0

Fixed Bugs and Malfunctions

Correct timing related pipelining/keepalive queue bug, that could result in unexpected "socket_remotly_closed" errors.

Own Id: OTP-18476 Aux Id: GH-6380

Improvements and New Features

By default ssl connections will use options from ssl_default_options(true)

Own Id: OTP-18167

Runtime dependencies have been updated.

Own Id: OTP-18350

Deprecates dbg:stop_clear/0 because it is simply a function alias to dbg:stop/0

Own Id: OTP-18478 Aux Id: GH-6903

The implementation has been fixed to use proc_lib:init_fail/2,3 where appropriate, instead of proc_lib:init_ack/1,2.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-18490 Aux Id: OTP-18471, GH-6339, PR-6843

IP display string will now always be in lower case, effects ipv6 addresses.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-18530

Removed deprecated functions

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-18536

Update the code in the inets example directory to reflect the latest implementation

Own Id: OTP-18544 Aux Id: GH-5276

Inets 8.3.1.5

Fixed Bugs and Malfunctions

Fixed a bug where calling httpc:set_options/2 when one of keys: ipfamily or unix_socket, was not present, would cause the other value to get overriden by the default value. The validation of these options was also improved.

Own Id: OTP-19379 Aux Id: PR-8878, GH-8829

Inets 8.3.1.4

Fixed Bugs and Malfunctions

With this change, HTTP client, when returning an asynchronous request, now correctly takes into account `OptionRequest - full_result`

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-19158

With this change, synchronous httpc:request now timeouts after `Timeout` specified in `HttpOption {timeout, Timeout}`

Own Id: OTP-19221 Aux Id: ERIERL-1091, PR-8788, PR-8801

Inets 8.3.1.3

Fixed Bugs and Malfunctions

Fixed runtime dependencies.

Own Id: OTP-19064

Inets 8.3.1.2

Fixed Bugs and Malfunctions

With this change, error report generated by httpd during connection setup contains socket type information.

Own Id: OTP-18704 Aux Id: ERIERL-962, PR-7513, OTP-18688

Stop and restart of the httpd server in the Inets application has been refactored to a more synchronous and OTP supervisor friendly approach.

This should increase stability and for example avoid a supervisor report from httpd_connection_sup about killed child process(es) in some cases when stopping or restarting httpd.

Own Id: OTP-18708 Aux Id: ERIERL-962, OTP-18688

Inets 8.3.1.1

Fixed Bugs and Malfunctions

Fixed a bug so httpd does not crash when stopped at the wrong time during TLS connection negotiation, or any other theoretically as slow connection setup.

Own Id: OTP-18688 Aux Id: ERIERL-962

Inets 8.3.1

Fixed Bugs and Malfunctions

Correct timing related pipelining/keepalive queue bug, that could result in unexpected "socket_remotly_closed" errors.

Own Id: OTP-18509 Aux Id: OTP-18476

With this change, upon remote socket closure current request is added to a retried queue (either pipeline or keep_alive, but not both).

Own Id: OTP-18545 Aux Id: OTP-18509, ERIERL-937, ERIERL-928

Inets 8.3

Fixed Bugs and Malfunctions

With this change, handling of URI to a folder, with missing trailing / and a query component present is fixed.

Own Id: OTP-18472 Aux Id: DAFH-1592

Improvements and New Features

Adds more type information to the inets app, thus improving the errors that static analysis tools can detect.

The addition of type information to records and the updates to function heads help static analysis tools to understand that some values in the records cannot be 'undefined', thus making static tools to type check correctly more modules in the inets app

Own Id: OTP-18390 Aux Id: PR-6661

Replace size/1 with either tuple_size/1 or byte_size/1

The size/1 BIF is not optimized by the JIT, and its use can result in worse types for Dialyzer.

When one knows that the value being tested must be a tuple, tuple_size/1 should always be preferred.

When one knows that the value being tested must be a binary, byte_size/1 should be preferred. However, byte_size/1 also accepts a bitstring (rounding up size to a whole number of bytes), so one must make sure that the call to byte_size/ is preceded by a call to is_binary/1 to ensure that bitstrings are rejected. Note that the compiler removes redundant calls to is_binary/1, so if one is not sure whether previous code had made sure that the argument is a binary, it does not harm to add an is_binary/1 test immediately before the call to byte_size/1.

Own Id: OTP-18432 Aux Id: GH-6672,PR-6793,PR-6784,PR-6787,PR-6785,PR-6682,PR-6800,PR-6797,PR-6798,PR-6799,PR-6796,PR-6813,PR-6671,PR-6673,PR-6684,PR-6694,GH-6677,PR-6696,PR-6670,PR-6674

Inets 8.2.2

Fixed Bugs and Malfunctions

Ensure graceful shutdown

Own Id: OTP-18461 Aux Id: ERIERL-890

Return type of the type specification for function httpc:cookie_header/{1,2,3} has been fixed from -spec cookie_header(url()) -> [{ field(), value() }] | {error, Reason} to -spec cookie_header(url()) -> { field(), value() } | {error, Reason}

Own Id: OTP-18462 Aux Id: GH-6846

Inets 8.2.1

Fixed Bugs and Malfunctions

fixes a missing case of the type specification for httpd:info/2/3/4

Own Id: OTP-18362 Aux Id: GH-6558, ERIERL-895

Inets 8.2

Improvements and New Features

This change allows body requests to httpc:request/5 be an iolist/0

Own Id: OTP-18250

addition of type specs in httpc.erl

Own Id: OTP-18251 Aux Id: GH-6245

httpc: Add support for HTTP 308 status code

Own Id: OTP-18280 Aux Id: GH-6290, PR-6291

Inets 8.1

Improvements and New Features

Add httpc:ssl_verify_host_options/1 to help setting default ssl options for the https client.

Own Id: OTP-18118

This change fixes dialyzer warnings generated for inets/httpd examples (includes needed adjustment of spec for ssh_sftp module).

Own Id: OTP-18178 Aux Id: ERIERL-833, ERIERL-834, ERIERL-835

Remove documentation of no longer supported callback.

Own Id: OTP-18193 Aux Id: GH-6122

Inets 8.0

Fixed Bugs and Malfunctions

Adjust uri_string:normalize behavior for URIs with undefined port (URI string with a port colon but no port value or URI map with port => undefined).

Remove redundant normalization from http_request module.

Before this change, normalize would not remove port subcomponent in such cases and could for example return "http://localhost:" URI.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-17627

Fixed typo in Reason term returned from httpc_handler:handle_http_body.

After this change, could_not_establish_ssl_tunnel atom is returned within Reason term.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-17889

With this change, inet6fb4 option is documented for inets/httpc. Option can be used when IP family needs to be discovered by a connection attempt.

Own Id: OTP-18063 Aux Id: ERIERL-798

Improvements and New Features

This change removes deprecated functions: http_uri:parse/1, http_uri:parse/2 and http_uri:scheme_defaults/0.

This change delays until OTP-26 removal of deprecated functions: http_uri:encode/1 and http_uri:decode/1.

This change marks httpd_util:decode_hex/1 and httpd_util:encode_hex/1 as deprecated.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-17866

After this change, connect_timeout value is re-used when upgrading TCP connection to TLS over a proxy.

Own Id: OTP-17997 Aux Id: GH-5782

Remove reference to unsupported Apache-like config file from httpd manual.

Own Id: OTP-18088 Aux Id: GH-5276

Inets 7.5.3.4

Fixed Bugs and Malfunctions

With this change, upon remote socket closure current request is added to a retried queue (either pipeline or keep_alive, but not both).

Own Id: OTP-18545 Aux Id: OTP-18509, ERIERL-937, ERIERL-928

Inets 7.5.3.3

Fixed Bugs and Malfunctions

Correct timing related pipelining/keepalive queue bug, that could result in unexpected "socket_remotly_closed" errors.

Own Id: OTP-18509 Aux Id: OTP-18476

Inets 7.5.3.2

Fixed Bugs and Malfunctions

With this change, handling of URI to a folder, with missing trailing / and a query component present is fixed.

Own Id: OTP-18472 Aux Id: DAFH-1592

Inets 7.5.3.1

Improvements and New Features

Remove documentation of no longer supported callback.

Own Id: OTP-18193 Aux Id: GH-6122

Inets 7.5.3

Fixed Bugs and Malfunctions

Fix handling of erl_script_script option in httpd when atom 'all' is used as AllowedModule.

Own Id: OTP-18069 Aux Id: ERIERL-805

Inets 7.5.2

Fixed Bugs and Malfunctions

The compilation time is no longer recorded in BEAM files. There remained several undocumented functions that attempted to retrieve compilation times. Those have now been removed.

Own Id: OTP-17962

Improvements and New Features

Documentation fix for inets:services_info/0, which now describes that Info might be a Reason term() in case when {error, Reason} is returned as service info.

Own Id: OTP-17931 Aux Id: ERIERL-761

Inets 7.5.1

Fixed Bugs and Malfunctions

Avoid intermediate ungraceful shutdown of the HTTP server.

Own Id: OTP-17922 Aux Id: ERIERL-743

Inets 7.5

Fixed Bugs and Malfunctions

Correct HTTP server URI handling to fully rely on uri_string. The server could mistreat some URI paths that in turn could result in incorrect responses being generated.

Own Id: OTP-17818 Aux Id: ERIERL-731

Improvements and New Features

Extend header values to httpc:request/5 to allow binary() as well. Make error detection of invalid arguments to httpc:request/5 be more precise so an error is returned in more cases instead of causing a hang or function_clause. Be more precise in documentation regarding the types of arguments being accepted.

Own Id: OTP-17579 Aux Id: GH-5074

Inets 7.4.2

Fixed Bugs and Malfunctions

Before this change hrefs in dir listing page contained percentage encoded forward slashes which did not work properly with httpd.

Own Id: OTP-17383 Aux Id: GH-4677

Restored HTTP headers handling in inets/mod_esi.

Own Id: OTP-17600

inets/httpd dir listing icons and other improvements

Own Id: OTP-17624 Aux Id: GH-4855

Improvements and New Features

httpc: Improve performance by removing redundant URI handling

Own Id: OTP-17460

Inets 7.4.1

Fixed Bugs and Malfunctions

Improved user input handling in inets/mod_esi preventing unnecessary atom creation.

Own Id: OTP-17490

Inets 7.4

Improvements and New Features

Drop all support for ftp and tftp in inets code.

Own Id: OTP-16722

Deprecate following functions in httpd_util module: flatlength/1, lhexlist_to_integer/1, integer_to_hexlist/1, strip/1, and suffix/1.

Own Id: OTP-16723

Remove support of HTTP 0.9 in httpd.

Own Id: OTP-16724

Remove support of HTTP 0.9 in httpc.

Own Id: OTP-16725

Fixed warnings in code matching on underscore prefixed variables.

Own Id: OTP-17385 Aux Id: OTP-17123

Inets 7.3.2.3

Improvements and New Features

Remove documentation of no longer supported callback.

Own Id: OTP-18193 Aux Id: GH-6122

Inets 7.3.2.2

Fixed Bugs and Malfunctions

Restored HTTP headers handling in inets/mod_esi.

Own Id: OTP-17600

Inets 7.3.2.1

Fixed Bugs and Malfunctions

Improved user input handling in inets/mod_esi preventing unnecessary atom creation.

Own Id: OTP-17490

Inets 7.3.2

Fixed Bugs and Malfunctions

Solves CVE-2021-27563, that is make sure no form of relative path can be used to go outside webservers directory.

Own Id: OTP-17205 Aux Id: ERIERL-608

Make sure HEAD requests rejects directory links

Own Id: OTP-17220

Inets 7.3.1

Fixed Bugs and Malfunctions

Fix an issue about HTML-escaped filename in inets.

Own Id: OTP-16873 Aux Id: ERL-330

Inets 7.3

Fixed Bugs and Malfunctions

Clarify the handling of percent encoded characters in http client.

Own Id: OTP-16650 Aux Id: ERL-1215, PR-2629

fix crash for undefined port in uri.

Own Id: OTP-16663 Aux Id: ERL-1241

Avoid timing issue when setting active once on a socket that is being closed by the peer.

Own Id: OTP-16735 Aux Id: OTP-16697, ERIERL-496

Handle message body of response with 1XX status code as next http message.

Own Id: OTP-16746 Aux Id: ERL-1268

Fix a crash in http server when setopts is called on a socket closed by the peer.

Own Id: OTP-16775 Aux Id: ERIERL-519

A vulnerability in the httpd module (inets application) regarding directory traversal that was introduced in OTP 22.3.1 and corrected in OTP 22.3.4.6. It was also introduced in OTP 23.0 and corrected in OTP 23.1 The vulnerability is registered as CVE-2020-25623

The vulnerability is only exposed if the http server (httpd) in the inets application is used. The vulnerability makes it possible to read arbitrary files which the Erlang system has read access to with for example a specially prepared http request.

Own Id: OTP-16790 Aux Id: ERIERL-522

Improvements and New Features

Add support of PATCH method in mod_esi.

Own Id: OTP-16591 Aux Id: ERIERL-484

Inets 7.2

Improvements and New Features

Remove support for deprecated functionality. Support for mod_esi eval scheme, mod_htacess, mod_browser, apache config files and deprecated httpd_conf functions are dropped. Module http_uri is deprecated.

Own Id: OTP-16252

Refactored the internal handling of deprecated and removed functions.

Own Id: OTP-16469

Inets 7.1.3.3

Fixed Bugs and Malfunctions

Corrected an error regarding decode of percent encoded URLs introduced in inets-7.1.3.

Own Id: OTP-16790 Aux Id: ERIERL-522

Inets 7.1.3.2

Fixed Bugs and Malfunctions

Fix a crash in http server when setopts is called on a socket closed by the peer.

Own Id: OTP-16775 Aux Id: ERIERL-519

Inets 7.1.3.1

Fixed Bugs and Malfunctions

Avoid timing issue when setting active once on a socket that is being closed by the peer.

Own Id: OTP-16735 Aux Id: OTP-16697, ERIERL-496

Inets 7.1.3

Fixed Bugs and Malfunctions

Remove use of http_uri and mod_esi eval API.

This is a backport from OTP 23 that improves the check of URIs to ensure that invalid URIs does not cause vulnerabilities. This will render the deprecated mod_esi eval API unusable as it used URI that does not conform to valid URI syntax.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-16556

Inets 7.1.2

Fixed Bugs and Malfunctions

Inets will honor that valid HTTP headers can not have white space between field-name and the colon.

Own Id: OTP-16169 Aux Id: ERL-1053

Changed error propagation in httpc:request/1 to return expected error tuple instead of crashing.

Own Id: OTP-16290 Aux Id: PR-2437, ERL-1083

Fix handling of HEAD request with chunked transfer-encoding (httpc).

Own Id: OTP-16300 Aux Id: ERL-1090

Inets 7.1.1

Improvements and New Features

Add HTTP server error logging vi logger

Own Id: OTP-16019

Inets 7.1

Improvements and New Features

httpd - Accept single LF as line terminator

Own Id: OTP-15893 Aux Id: PR-2206

mod_esi will now always propagate the actual HTTP status code that it answered with, to later mod-modules, and not in some cases hardcode 200.

Own Id: OTP-16049 Aux Id: ERIERL-395

Inets 7.0.9

Fixed Bugs and Malfunctions

Fix a regression in http client that causes a crash when request URI has no scheme.

Own Id: OTP-15930 Aux Id: ERL-969

Inets 7.0.8

Fixed Bugs and Malfunctions

All incorrect (that is, all) uses of "can not" has been corrected to "cannot" in source code comments, documentation, examples, and so on.

Own Id: OTP-14282 Aux Id: PR-1891

Inets 7.0.7.2

Improvements and New Features

Add HTTP server error logging vi logger

Own Id: OTP-16019

Inets 7.0.7.1

Improvements and New Features

mod_esi will now always propagate the actual HTTP status code that it answered with, to later mod-modules, and not in some cases hardcode 200.

Own Id: OTP-16049 Aux Id: ERIERL-395

Inets 7.0.7

Fixed Bugs and Malfunctions

Fix the internal handling of the option erl_script_timeout in httpd. If explicit erl_script_timeout value was supplied in seconds it was not correctly converted to millisecond units for internal usage.

This change fixes the handling of erl_script_timeout in all possible configuration scenarios.

Own Id: OTP-15769 Aux Id: ERIERL-345

Inets 7.0.6

Fixed Bugs and Malfunctions

Fix the internal handling of the option erl_script_timeout in httpd. When httpd was started with explicit erl_script_timeout, the value of the option was converted to milliseconds before storage. Subsequent calls to httpd:info/1 returned the input value multiplied by 1000.

This change fixes the handing of erl_script_timeout by storing the timeout in seconds and converting to milliseconds before usage.

Own Id: OTP-15669 Aux Id: ERIERL-321

Improvements and New Features

Enhance documentation

Own Id: OTP-15508 Aux Id: ERL-816

Inets 7.0.5

Fixed Bugs and Malfunctions

Fixed bug that causes a crash in http client when using hostnames (e.g. localhost) with the the option ipv6_host_with_brackets set to true.

This change also fixes a regression: httpc:request fails with connection error (nxdomain) if option ipv6_host_with_brackets set to true and host component of the URI is an IPv6 address.

Own Id: OTP-15554 Aux Id: ERIERL-289

Inets 7.0.4

Fixed Bugs and Malfunctions

Make sure ipv6 addresses with brackets in URIs are converted correctly before passing to lower level functions like gen_tcp and ssl functions. Could cause connection to fail.

Own Id: OTP-15544 Aux Id: ERIERL-289

Inets 7.0.3

Fixed Bugs and Malfunctions

Fixed http client to not send 'content-length' header in chunked encoded requests.

Own Id: OTP-15338 Aux Id: ERL-733

Fixed http client to not drop explicit 'Content-Type' header in requests without a body such as requests with the 'Content-Type' of application/x-www-form-urlencoded.

Own Id: OTP-15339 Aux Id: ERL-736

Inets 7.0.2

Fixed Bugs and Malfunctions

Enhance error handling, that is mod_get will return 403 if a path is a directory and not a file.

Own Id: OTP-15192

Do not use chunked-encoding with 1xx, 204 and 304 responses when using mod_esi. Old behavior was not compliant with HTTP/1.1 RFC and could cause clients to hang when they received 1xx, 204 or 304 responses that included an empty chunked-encoded body.

Own Id: OTP-15241

Add robust handling of chunked-encoded HTTP responses with an empty body (1xx, 204, 304). Old behavior could cause the client to hang when connecting to a faulty server implementation.

Own Id: OTP-15242

Inets 7.0.1

Fixed Bugs and Malfunctions

Change status code for no mod found to handle request to 501

Own Id: OTP-15215

Inets 7.0

Fixed Bugs and Malfunctions

Fixed HTTP content injection bug in httpc (ERL-456).

Own Id: OTP-14726

Fixed support for URI-references in HTTP 'Location' header (ERL-333).

Own Id: OTP-14729

Fix broken 'Content-Type' handling in httpc (ERL-536).

Own Id: OTP-15006

Fix handling of relative paths in the script_alias property of httpd (ERL-574).

Own Id: OTP-15021

Fix httpd:reload_config/2 with path() as the first argument (ERL-578).

Own Id: OTP-15025

Improved gracefulness.

Own Id: OTP-15042

Improvements and New Features

Split inets and create separate ftp and tftp apps.

Own Id: OTP-14113

Inets 6.5.2.4

Fixed Bugs and Malfunctions

Do not use chunked-encoding with 1xx, 204 and 304 responses when using mod_esi. Old behavior was not compliant with HTTP/1.1 RFC and could cause clients to hang when they received 1xx, 204 or 304 responses that included an empty chunked-encoded body.

Own Id: OTP-15241

Add robust handling of chunked-encoded HTTP responses with an empty body (1xx, 204, 304). Old behavior could cause the client to hang when connecting to a faulty server implementation.

Own Id: OTP-15242

Inets 6.5.2.3

Fixed Bugs and Malfunctions

Change status code for no mod found to handle request to 501

Own Id: OTP-15215

Inets 6.5.2.2

Fixed Bugs and Malfunctions

Enhance error handling, that is mod_get will return 403 if a path is a directory and not a file.

Own Id: OTP-15192

Inets 6.5.2.1

Improvements and New Features

Options added for setting low-level properties on the underlying TCP connections. The options are: sock_ctrl, sock_data_act and sock_data_pass. See the manual for details.

Own Id: OTP-15120 Aux Id: ERIERL-192

Inets 6.5.2

Fixed Bugs and Malfunctions

inets: httpd - Gracefully handle bad headers

The option max_headers operated on the individual header length instead of the total length of all headers. Also headers with empty keys are now discarded.

Own Id: OTP-15092

Inets 6.5.1

Fixed Bugs and Malfunctions

Fix broken options handling in httpc (ERL-441).

Own Id: OTP-15007

Inets 6.5

Fixed Bugs and Malfunctions

httpc_manager crashes when a long running request is sent on a persistent HTTP connection (keep-alive). Fixed httpc_manager to use proper timeouts on keep-alive connections.

Own Id: OTP-14908

Improvements and New Features

Add support for unix domain sockets in the http client.

Own Id: OTP-14854

Inets 6.4.5

Fixed Bugs and Malfunctions

CGI environment variable CONTENT_LENGTH shall be a string

Own Id: OTP-14679

In relaxed mode disregard Content-Length header if there is also a Transfer-Encoding header.

Own Id: OTP-14727

Eliminated race condition, that could cause http request to sporadically fail to complete successfully, when keep-alive connections are used.

Own Id: OTP-14783

Inets 6.4.4

Fixed Bugs and Malfunctions

Correct the handling of location headers so that the status code is not hard coded. This should have been fixed by commit 2cc5ba70cbbc6b3ace81a2a0324417c3b65265bb but unfortunately was broken during a code refactoring and unnoticed due to a faulty placed test case.

Own Id: OTP-14761

Inets 6.4.3

Improvements and New Features

Fix broken handling of POST requests

New chunk mechanism of body data in POST requests added in 5d01c70ca399edf28e99dc760506329689fab6ba broke handling of POST body data not using the new mechanism.

Own Id: OTP-14656

Make sure ints:stop/2 of the service httpd is synchronous

Own Id: OTP-14696

Honor status code returned by ESI script and modernize "location" header handling.

Own Id: OTP-14716

Inets 6.4.2

Fixed Bugs and Malfunctions

Make sure mod_log uses the correct status code

Own Id: OTP-14510

Correct behaviour of mod_disk_log to proparly handle repair options

Own Id: OTP-14530

Inets 6.4.1

Fixed Bugs and Malfunctions

http_uri aligned to follow RFC 3986 and not convert "+" to space when decoding URIs.

Own Id: OTP-14573

Improvements and New Features

Added new option max_client_body_chunk to httpd server to allow chunked delivery of PUT and POST data to mod_esi callback. Note, new mod_esi callback implementation is required.

Also correct value provided by server_name environment variable

Own Id: OTP-14450

Inets 6.4

Fixed Bugs and Malfunctions

httpd_util:rfc1123_date/1 gracefully handle invalid DST dates by returning the original time in the expected rfc1123 format.

Own Id: OTP-14394

Improvements and New Features

Add unicode binary support to http_uri functions

Own Id: OTP-14404

httpc - Change timeout handling so the redirects cause a new timer to be set. This means that a simple redirected request could return after 2*timeout milliseconds.

Own Id: OTP-14429

Inets 6.3.9

Fixed Bugs and Malfunctions

The close of a chunked file reception crashed in a certain timing sequence.

Own Id: OTP-14391 Aux Id: seq13306

Inets 6.3.8

Improvements and New Features

Added missing release note for inets-6.3.7

Own Id: OTP-14383

Inets 6.3.7

Fixed Bugs and Malfunctions

Fixed a bug in ftp that made further operations after a recv_chunk operation impossible.

Own Id: OTP-14242

Make default port, 80 and 443, implicit in automatic redirection.

Own Id: OTP-14301

Inets 6.3.6

Fixed Bugs and Malfunctions

Chunk size decoding could fail. The symptom was that chunk decoding sometimes failed depending on timing of the received stream. If chunk size was split into two different packets decoding would fail.

Own Id: OTP-13571 Aux Id: ERL-116

Prevent httpc user process to hang if httpc_handler process terminates unexpectedly

Own Id: OTP-14091

Correct Host header, to include port number, when redirecting requests.

Own Id: OTP-14097

Shutdown gracefully on connection or TLS handshake errors

Own Id: OTP-14173 Aux Id: seq13262

Inets 6.3.5

Fixed Bugs and Malfunctions

Correct mistakes in ftp client introduced in inets-6.3.4

Own Id: OTP-14203 Aux Id: OTP-13982

Inets 6.3.4

Fixed Bugs and Malfunctions

Fixes a bug that makes the ftp client end up in bad state if there is a multi line response from the server and the response number is in the message being sent.

Own Id: OTP-13960 Aux Id: PR1196

The ftp client could stop consuming messages when the multiline response handling was corrected.

Own Id: OTP-13967

Fix keep-alive https through proxy connections so that all requests, following the first one, will run as expected instead of failing.

Own Id: OTP-14041

Fix bug from commit fdfda2fab0921d409789174556582db28141448e that could make listing of group members in mod_auth callbacks fail.

Own Id: OTP-14082

Improvements and New Features

Update behavior of httpc:request to match RFC-7231

Own Id: OTP-13902

Fixed dialyzer warnings as well as some white-space issues. Thanks to Kostis.

Own Id: OTP-13982 Aux Id: PR-1207

Inets 6.3.3

Fixed Bugs and Malfunctions

The legacy option 'inet6fb4' for inets had stopped working. This bug has now been corrected. Fix by Edwin Fine in bugs.erlang.org ERL-200 and Github PR#1132.

Own Id: OTP-13776 Aux Id: ERL-200 PR-1132

Inets 6.3.2

Improvements and New Features

PUT and DELETE support has been added to mod_esi

Own Id: OTP-13688 Aux Id: seq13149

Inets 6.3.1

Fixed Bugs and Malfunctions

A debug message was accidentally left enabled in the ftp client.

Own Id: OTP-13712 Aux Id: seq13143

Inets 6.3

Fixed Bugs and Malfunctions

Ftp client fixes: 1) Corrected a bug that the ftp client gen_server crashed if the listening data socket was closed.

Corrections of ftp client error codes so they are as defined in the reference manual

Own Id: OTP-13644

Improvements and New Features

Remove usage of erlang:now().

Own Id: OTP-12441

Add handling of DELETE Body to http client.

Own Id: OTP-13383 Aux Id: PR-972

Removed references to mod_include and webtool from examples and tests.

Own Id: OTP-13445 Aux Id: PR-988

Remove module inets_regexp. Module re should be used instead.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-13561

Inets 6.2.4

Improvements and New Features

Handle multiple \t in mime types file

Own Id: OTP-13663 Aux Id: seq13132

Inets 6.2.3

Improvements and New Features

Put back unused module inets_regexp and remove it in OTP 19 instead as it is an incompatibility, although it is an undocumented module and should not affect other applications.

Own Id: OTP-13533

Inets 6.2.2

Improvements and New Features

Add environment information item peer_cert to mod_esi

Own Id: OTP-13510

Inets 6.2.1

Fixed Bugs and Malfunctions

Mend ipv6_host_with_brackets option in httpc

Own Id: OTP-13417

Inets 6.2

Fixed Bugs and Malfunctions

The TFTP client/server has been fixed to allow file sizes larger than 32MB block by allowing the 16 bit block counter to wrap. Since this is a commonly accepted behavior we regard it as a bug fix.

Own Id: OTP-13403

Improvements and New Features

Handle HTTP PATCH method in client.

Own Id: OTP-13286

Expected termination should not be logged as an application error.

Own Id: OTP-13389

Inets 6.1.1.1

Fixed Bugs and Malfunctions

Mend ipv6_host_with_brackets option in httpc

Own Id: OTP-13417

Inets 6.1.1

Fixed Bugs and Malfunctions

mod_alias now traverses all aliases picking the longest match and not the first match.

Own Id: OTP-13248

Inets 6.1

Fixed Bugs and Malfunctions

Replace obs-folds with spaces instead of failing

Own Id: OTP-13069

Add validation fun for URI scheme to http_uri API

Own Id: OTP-13071

Handle stream bodies as documented.

Own Id: OTP-13093

Correct error handling of mod_esi generated chunks. Send warning headers in chunk trailers instead of generating an unexpected additional 500 request response, when problems, such as a timeout occurs.

Own Id: OTP-13110

HTTP client terminates gracefully when an invalid chunked length header is encountered.

Own Id: OTP-13117

Improvements and New Features

Add default for SNI (Server Name Indication) when running https using the inets HTTP-client.

Own Id: OTP-12985

Be forgiving to chunked sizes that have trailing whitespaces as prior implementation was. Also some legacy embedded devices does actually have trailing whitespaces even though this in not according to the spec.

Own Id: OTP-13116

Inets 6.0.3

Fixed Bugs and Malfunctions

Improved error handling and gracfully termination when an invalid chunked length header is encountered.

Own Id: OTP-13061

Improvements and New Features

Add possibility to set socket options, such as nodelay, for httpd. Also phase out legacy option value inet6bf4 for the ipfamily option. This value will be translated to the value inet.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-13062

Inets 6.0.2

Fixed Bugs and Malfunctions

Avoid crash in mod_auth_server and mod_security_server due to using an atom instead of a string when creating a name.

Own Id: OTP-13022

Improvements and New Features

Add function response_default_headers/0 to httpd customize API, to allow user to specify default values for HTTP response headers.

Own Id: OTP-13013

Inets 6.0.1

Fixed Bugs and Malfunctions

Fix broken socket feature, that is on Linux systems a socket may be opened before starting Erlang and then passed to Erlang's httpd daemon. This is useful as the wrap program can open a privileged port and Erlang does not have to be run as root.

Own Id: OTP-12875 Aux Id: seq12878

Fix broken socket feature, that is on Linux systems a socket may be opened before starting Erlang and then passed to Erlangs tftp daemon. This is useful as the wrap program can open a privileged port and Erlang does not have to be run as root.

Own Id: OTP-12898 Aux Id: seq12900

httpc_handler should react properly to cancel requests even when the request to be canceled was already finished but httpc_manager did not get notified about that yet.

Own Id: OTP-12922

Improvements and New Features

Added format_status function to httpd process to avoid sensitive information to be printed in supervisor logs.

Own Id: OTP-12976

Return meaningful error reason disregarding whether a http proxy is used or not.

Own Id: OTP-12984

Inets 6.0

Fixed Bugs and Malfunctions

Fix race condition in httpc. If the socket is closed by the peer do not try to close it again.

Own Id: OTP-11845

Avoid process leak by gracefully terminating httpc request handler process when send operation fails.

Own Id: OTP-12362

Reject messages with a Content-Length less than 0

Own Id: OTP-12739 Aux Id: seq12860

Let gen_tcp:controlling_process/2 and inet_sctp:connect/[45] propagate prim_inet:setopt/3 errors instead of having them generate badmatch exceptions.

Own Id: OTP-12798

Improvements and New Features

Remove Server Side Include support from inets, as this is an old technique that has security issues and was not well tested.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-12156

New value in server_tokens config for limiting banner grabbing attempts.

By setting {server_tokens, none} in ServiceConfig for inets:start(httpd, ServiceConfig), the "Server:" header will not be set in messages from the server.

Own Id: OTP-12661 Aux Id: seq12840

To enable the HTTP server to run in a virtualized environment, where there can be more that one server that has the same ip-address and port, we add a new option profile.

Own Id: OTP-12674

httpc: Fix implementation of graceful shudown to work as intended for keep alive connections not using pipelining.

Own Id: OTP-12803

Correct handling of proxy options when using persistent connections.

Own Id: OTP-12822

Inets 5.10.9

Improvements and New Features

Add behaviour with optional callbacks to customize the inets HTTP server.

Own Id: OTP-12776

Inets 5.10.8

Fixed Bugs and Malfunctions

Reject messages with a Content-Length less than 0

Own Id: OTP-12739 Aux Id: seq12860

Inets 5.10.7

Improvements and New Features

New value in server_tokens config for limiting banner grabbing attempts.

By setting {server_tokens, none} in ServiceConfig for inets:start(httpd, ServiceConfig), the "Server:" header will not be set in messages from the server.

Own Id: OTP-12661 Aux Id: seq12840

Inets 5.10.6

Fixed Bugs and Malfunctions

inets: parse correctly 'Set-Cookie' header with empty value

httpc_cookie should parse cookies with empty values and no attributes set in the 'Set-Cookie' headers.

Own Id: OTP-12455

Improvements and New Features

Add parsing of URI fragments to http_uri:parse

This fixes a bug in httpc where redirection URIs could lead to bad requests if they contained fragments.

Own Id: OTP-12398

httpc: http client now ignores invalid set-cookie headers

Own Id: OTP-12430

Inets 5.10.5

Fixed Bugs and Malfunctions

mod_alias now handles https-URIs properly

Consistent view of configuration parameter keep_alive_timeout, should be presented in the httpd:info/[1,2] function in the same unit as it is inputted.

Own Id: OTP-12436 Aux Id: seq12786

Improvements and New Features

Gracefully handle invalid content-length headers instead of crashing in list_to_integer.

Own Id: OTP-12429

Inets 5.10.4

Fixed Bugs and Malfunctions

Fixed a spelling mistake in httpc documentation.

Own Id: OTP-12221

Improvements and New Features

Add option {ftp_extension, boolean} to enable use of extended commands EPSV and EPRT, as specified in RFC 2428, for IPv4 instead of using the legacy commands. Ipv6 cannot be supported without the extended commands.

Own Id: OTP-12255

Inets 5.10.3

Fixed Bugs and Malfunctions

Fix some spelling mistakes in documentation

Own Id: OTP-12152

Improvements and New Features

httpd: Separate timeout for TLS/SSL handshake from keepalive timeout

Own Id: OTP-12013

Warning: this is experimental and may disappear or change without previous warning.

Experimental support for running Quickcheck and PropEr tests from common_test suites is added to common_test. See the reference manual for the new module ct_property_testing.

Experimental property tests are added under lib/{inet,ssh}/test/property_test. They can be run directly or from the commont_test suites inet/ftp_property_test_SUITE.erl and ssh/test/ssh_property_test_SUITE.erl.

See the code in the test directories and the man page for details.

(Thanks to Tuncer Ayaz for a patch adding Triq)

Own Id: OTP-12119

Inets 5.10.2

Fixed Bugs and Malfunctions

httpc: Fix streaming bugs when handling small responses

Own Id: OTP-11992

Inets 5.10.1

Fixed Bugs and Malfunctions

Correct distirbing mode for httpd:reload_config/2

Own Id: OTP-11914

Improvements and New Features

Improved handling of invalid strings in the HTTP request line.

Impact: May improve memory consumption

Own Id: OTP-11925 Aux Id: Sequence 12601

Inets 5.10

Fixed Bugs and Malfunctions

Fixed a spelling mistake in httpc doc (Thanks to Wasif Riaz Malik)

Own Id: OTP-11538

Application upgrade (appup) files are corrected for the following applications:

asn1, common_test, compiler, crypto, debugger, dialyzer, edoc, eldap, erl_docgen, et, eunit, gs, hipe, inets, observer, odbc, os_mon, otp_mibs, parsetools, percept, public_key, reltool, runtime_tools, ssh, syntax_tools, test_server, tools, typer, webtool, wx, xmerl

A new test utility for testing appup files is added to test_server. This is now used by most applications in OTP.

(Thanks to Tobias Schlager)

Own Id: OTP-11744

ftp now sanitize file name, user name and passwords from <CR> and <LF> tags (Thanks to Sergei Golovan)

Own Id: OTP-11750

Corrected error handling in the HTTP client, making it behave more graceful.

Thanks to Kirilll Zaborsky

Own Id: OTP-11794

Support identity transfer-encoding in httpc.

Thanks to Anthony Ramine

Own Id: OTP-11802

Ignore empty Set-Cookie headers to increase interoperability with servers that violate the RFC.

Thanks to Kirilll Zaborsky

Own Id: OTP-11803

Improvements and New Features

The commit 6189bc07 "inets: httpc improve pipelining" has been reverted, as it turned out to break things rather than improve pipelining utilization. It is instead up to the user to configure httpc and use it wisely to be able to get the most out of pipelining.

Own Id: OTP-11756

Handle all response codes in httpd_util:message/3

Own Id: OTP-11838

Inets 5.9.8

Improvements and New Features

Mend max_clients check that was broken and avoid too extensive logging that could cause memory problems.

Own Id: OTP-11557 Aux Id: seq12478

Inets 5.9.7

Fixed Bugs and Malfunctions

Fix httpd config option 'script_timeout' and fixed httpd config option 'keep_alive_timeout'. Thanks to Johannes Weissl.

Own Id: OTP-11276

Make httpc:request_cancel/[1,2] asynchronous. Previously these functions tried to guarantee request answer would not reach the client, which only worked for some of the use cases. Now these functions are totally asynchronous which makes it the clients responsibility to disregard possible answers to canceled requests.

Also pipelining implementation has been changed to improve the utilization factor. Further investigation of possible enhancements in this area are planned for later.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-11312

[httpd] Add handling of new response for mod_head (otherwise causing case_clause crash). Also updated logging: Removed logging for keep-alive connections timeout (this is a normal occurrence and not an error) and some access-log body size corrections.

Own Id: OTP-11328

Improvements and New Features

The ftp client now supports ftp over tls (ftps).

Own Id: OTP-11037

Inets 5.9.6

Improvements and New Features

httpc: Allow content body in DELETE requests. Thanks to James Wheare.

Own Id: OTP-11190

Add missing brackets to report formatting on ftp_progress process exit. Thanks to Artur Wilniewczyc.

Own Id: OTP-11202

Fix some errors in the inets documentation. Thanks to Johannes Weissl.

Own Id: OTP-11210

Fix various typos in httpd, inets. Thanks to Tomohiko Aono.

Own Id: OTP-11226

Fix httpd config option 'erl_script_nocache'. Thanks to Johannes Weissl.

Own Id: OTP-11260

Inets 5.9.5

Fixed Bugs and Malfunctions

Reverted incorrect commit that broke cookie handling when using httpc-profiles.

Own Id: OTP-10956

Improvements and New Features

Fix http_request:http_headers/1 to send content-length when length is zero. Thanks to CA Meijer.

Own Id: OTP-10934

Integrate elliptic curve contribution from Andreas Schultz

In order to be able to support elliptic curve cipher suites in SSL/TLS, additions to handle elliptic curve infrastructure has been added to public_key and crypto.

This also has resulted in a rewrite of the crypto API to gain consistency and remove unnecessary overhead. All OTP applications using crypto has been updated to use the new API.

Impact: Elliptic curve cryptography (ECC) offers equivalent security with smaller key sizes than other public key algorithms. Smaller key sizes result in savings for power, memory, bandwidth, and computational cost that make ECC especially attractive for constrained environments.

Own Id: OTP-11009

Fix {stream, {self, once}} in httpc to work as expected. Thanks to Masatake Daimon

Own Id: OTP-11122

Inets 5.9.4

Improvements and New Features

httpd: The modules option now defaults to the documented value.

Own Id: OTP-10844

httpc: Fixed persistent connection implementation that was broken by a patch to R13. The patch made persistent connections behaved the same way as pipelining.

Own Id: OTP-10845

httpd: Simplified configuration of ssl in httpd, this also enables all ssl options to be configured. The old and limited way is no longer documented but will be supported for backwards comatibility for some time.

Own Id: OTP-10846

Handle correctly the "No files found or file unavailable" error code. Thanks to Serge Aleynikov

Own Id: OTP-10886

Inets 5.9.3

Improvements and New Features

httpc: The HTTP client now supports HTTPS through proxies

Own Id: OTP-10256 Aux Id: kunagi-2 [ce2e800e-c99f-4050-a1c4-f47023d9c7aa-1]

Some examples overflowing the width of PDF pages have been corrected.

Own Id: OTP-10665

Fix autoredirect for POST requests responding 303. Thanks to Hans Svensson.

Own Id: OTP-10765

Inets 5.9.2.2

Improvements and New Features

Make log_alert configurable as option in ssl, SSLLogLevel added as option to inets conf file

Own Id: OTP-11259

Inets 5.9.2.1

Improvements and New Features

Fixed obsolete error report in inets.

Own Id: OTP-11185 Aux Id: seq12357

Inets 5.9.2

Improvements and New Features

Minimum bytes per second

New option to http server, {minimum_bytes_per_second, integer()}, for a connection, if it is not reached the socket will close for that specific connection. Can be used to prevent hanging requests from faulty clients.

Own Id: OTP-10392

Inets 5.9.1

Improvements and New Features

Better handling of errorI(s) during update of the session database.

Also added and updated some debugging functions which_sessions/0,1 and info/0.

Own Id: OTP-10093

Aux Id: Seq 12062

Removed R14B compatible version of (inets-service and tftp) behaviour definition.

Own Id: OTP-10095

[httpc] Documentation of KeepAlive and Pipeline timeout options have been improved.

Own Id: OTP-10114

Fixed Bugs and Malfunctions

[httpc] Cancel request does not work due to incorrect handler table creation (wrong keypos).

Vyacheslav Vorobyov

Own Id: OTP-10092

Incompatibilities

-

Inets 5.9

Improvements and New Features

[httpd] Make the server header configurable with new config option server_tokens. The value of the server header, which was previously hard-coded (at compile time), is now possible to manipulate through the means of the server_tokens config option.

Own Id: OTP-9805

Improve inets support for inets as an included application.

inets_app calls supervisor:start_link/3 directly rather than calling the root supervisor function inets_sup:start_link/0. This precludes using included_applications to start inets without having a wrapper function.

Jay Nelson

Own Id: OTP-9960

[httpc] Add function for retrieving current options, get_options/1,2.

Own Id: OTP-9979

Utility module http_uri now officially supported.

Also, the http_uri:parse function has been extended with more scheme support and a way to provide your own scheme info.

Own Id: OTP-9983

Aux Id: Seq 12022

Fixed Bugs and Malfunctions

-

Inets 5.8.1

Improvements and New Features

-

Fixed Bugs and Malfunctions

[ftp] Fails to open IPv6 connection due to badly formatted IPv6 address in EPRT command. The address part of the command incorrectly contained decimal elements instead of hexadecimal.

Own Id: OTP-9827

Aux Id: Seq 11970

[httpc] Bad Keep Alive Mode. When selecting a session, the "state" of the session (specifically if the server has responded) was not taken into account.

Own Id: OTP-9847

[httpc] The client incorrectly streams 404 responses. The documentation specifies that only 200 and 206 responses shall be streamed.

Shane Evens

Own Id: OTP-9860

Inets 5.8

Improvements and New Features

[ftpc] Add a config option to specify a data connect timeout. That is how long the ftp client will wait for the server to connect to the data socket. If this timeout occurs, an error will be returned to the caller and the ftp client process will be terminated.

Own Id: OTP-9545

[httpc] Wrong Host header in IPv6 HTTP requests. When a URI with a IPv6 host is parsed, the brackets that encapsulates the address part is removed. This value is then supplied as the host header. This can cause problems with some servers. A workaround for this is to use headers_as_is and provide the host header with the request call. To solve this a new option has been added, ipv6_host_with_brackets. This option specifies if the host value of the host header shall include the brackets or not. By default, it does not (as before).

Own Id: OTP-9628

Fixed Bugs and Malfunctions

[httpd] Fix logging of content length in mod_log.

Garrett Smith

Own Id: OTP-9715

[httpd] Sometimes entries in the transfer log was written with the message size as list of numbers. This list was actually the size as a string, e.g. "123", written with the control sequence ~w. This has now been corrected so that any string is converted to an integer (if possible).

Own Id: OTP-9733

Fixed various problems detected by Dialyzer.

Own Id: OTP-9736

Incompatibilities

[httpc] Deprecated interface module http has been removed. It has (long) been replaced by http client interface module httpc.

Own Id: OTP-9359

[httpc|httpd] The old ssl implementation (based on OpenSSL), has been deprecated. The config option that specified usage of this version of the ssl app, ossl, has been removed.

Own Id: OTP-9522

Inets 5.7.2

Improvements and New Features

-

Fixed Bugs and Malfunctions

[httpd] XSS prevention did not work for hex-encoded URL's.

Own Id: OTP-9655

[httpd] GET request with malformed header date caused server crash (non-fatal) with no reply to client. Will now result in a reply with status code 400.

Own Id: OTP-9674

Aux Id: seq11936

Inets 5.7.1

Improvements and New Features

-

Fixed Bugs and Malfunctions

[httpc] Parsing of a cookie expire date should be more forgiving. That is, if the parsing fails, the date should be ignored. Also added support for (yet another) date format: "Tue Jan 01 08:00:01 2036 GMT".

Own Id: OTP-9433

[httpc] Rewrote cookie parsing. Among other things solving cookie processing from www.expedia.com.

Own Id: OTP-9434

[httpd] Fix httpd directory traversal on Windows. Directory traversal was possible on Windows where backward slash is used as directory separator.

András Veres-Szentkirályi.

Own Id: OTP-9561

Inets 5.7

Improvements and New Features

[httpc|httpd] Added support for IPv6 with ssl.

Own Id: OTP-5566

Fixed Bugs and Malfunctions

[httpc] Remove unnecessary usage of iolist_to_binary when processing body (for PUT and POST).

Filipe David Manana

Own Id: OTP-9317

[ftp] FTP client doesn't work with IPv6 host.

Attila Rajmund Nohl

Own Id: OTP-9342 Aux Id: seq11853

[httpd] Peer/sockname resolv doesn't work with IPv6 addrs in HTTP.

Attila Rajmund Nohl.

Own Id: OTP-9343

[httpc] Clients started stand-alone not properly handled. Also it was not documented how to use them, that is that once started, they are represented by a pid/0 and not by their profile().

Own Id: OTP-9365

Inets 5.6

Improvements and New Features

[httpc] Add support for upload body streaming (PUT and POST).

For more info, see the definition of the Body argument of the request/4,5 function.

Filipe David Manana

Own Id: OTP-9094

[ftp] Added (type) spec for all exported functions.

Own Id: OTP-9114 Aux Id: seq11799

[httpd] mod_esi:deliver/2 made to accept binary data.

Bernard Duggan

Own Id: OTP-9123

[httpd] Prevent XSS in error pages. Prevent user controlled input from being interpreted as HTML in error pages by encoding the reserved HTML characters.

Michael Santos

Own Id: OTP-9124

[httpd] Improved error messages.

Ricardo Catalinas Jiménez

Own Id: OTP-9157

[httpd] Extended support for file descriptors. In order to be able to bind to a privileged port without running the erlang VM as root, the support for using file descriptors has been improved. It is now possible to add the file descriptor to the config (option fd) when calling the inets:start(httpd, ...) function.

Attila Rajmund Nohl

Own Id: OTP-9202

Aux Id: seq11819

The default ssl kind has now been changed to essl.

ossl will work for as long as the ssl application supports it.

See the httpd socket_type communication property or the httpc request/4,5 function for more info.

Own Id: OTP-9230

* POTENTIAL INCOMPATIBILITY *

Fixed Bugs and Malfunctions

[httpd] Wrong security property names used in documentation.

security_data_file used instead of data_file.

security_max_retries used instead of max_retries.

security_block_time used instead of block_time.

security_fail_expire_time used instead of fail_expire_time.

security_auth_timeout used instead of auth_timeout.

Garrett Smith

Own Id: OTP-9131

[httpd] Fix timeout message generated by mod_esi. When a mod_esi request times out, the code to send a timeout response was incorrect and generated an internal server error as well as an invalid response line.

Bernard Duggan

Own Id: OTP-9158

[httpc] httpc manager crashes. When a request results in a retry, the request id will be "reused" in the previous implementation a race condition could occur causing the manager to crash.

This is now avoided by using proc_lib:init_ack and gen_server:enter_loop to allow more advanced initialization of httpc_handlers without blocking the httpc_manger and eliminating extra processes that can cause race conditions.

Own Id: OTP-9246

[httpc] Issuing a request (httpc:request) to an host with the ssl option {ip, {127,0,0,1}} results in an handler crash. The reason was that the connect call resulted in an exit with reason badarg (this was the same for both ssl and gen_tcp).

Exits was not caught. This has now been improved.

Own Id: OTP-9289

Aux Id: seq11845

Inets 5.5.2

Improvements and New Features

-

Fixed Bugs and Malfunctions

[httpd] httpd_response:send_chunk handles empty list and empty binary - i.e. no chunk is sent, but it does not handle a list with an empty binary [<<>>]. This will be sent as an empty chunk - which in turn will be encoded by http_chunk to the same as a final chunk, which will make the http client believe that the end of the page is reached.

Own Id: OTP-8906

Inets 5.5.1

Improvements and New Features

Miscellaneous inet6 related problems.

Own Id: OTP-8927

Updated http-server to make sure URLs in error-messages are URL-encoded. Added support in http-client to use URL-encoding. Also added the missing include directory for the inets application.

Own Id: OTP-8940

Aux Id: seq11735

Fixed Bugs and Malfunctions

Fix format_man_pages so it handles all man sections and remove warnings/errors in various man pages.

Own Id: OTP-8600

[httpc] Pipelined and queued requests not processed when connection closed remotelly.

Own Id: OTP-8906

Inets 5.5

Fixed Bugs and Malfunctions

[httpc] If a request times out (not connect timeout), the handler process exited (normal) but neglected to inform the manager process. For this reason, the manager did not clean up the request table., resulting in a memory leak. Also the manager did not create a monitor for the handler, so in an unforeseen handler crash, this could also create a memory leak.

Own Id: OTP-8739

The service tftp was spelled wrong in documentation and in some parts of the code. It should be tftp.

Own Id: OTP-8741 Aux Id: seq11635

[httpc] Replaced the old http client api module (http) with the new, httpc in the users guide.

Own Id: OTP-8742

Improvements and New Features

Eliminated warnings for auto-imported BIF clashes.

Own Id: OTP-8840

Inets 5.4

Improvements and New Features

[httpc|httpd] - Now allow the use of the "new" ssl, by using the essl tag instead.

See the http_option option in the request/4,5 or the socket-type section of the Communication properties chapter for more info,

Own Id: OTP-7907

Deprecated functions designated to be removed in R14 has been removed. Also, some new functions has been marked as deprecated (the old http client api module).

Own Id: OTP-8564

* POTENTIAL INCOMPATIBILITY *

[httpd] - Improved mod_alias. Now able to do better URL rewrites.

See URL aliasing properties and the CGI properties section(s) for more info,

Own Id: OTP-8573

Fixed Bugs and Malfunctions

-

Inets 5.3.3

Improvements and New Features

-

Fixed Bugs and Malfunctions

[httpc] - Made cookie handling more case insensitive.

Own Id: OTP-8609

Nicolas Thauvin

[httpc|httpd] - Netscape cookie dates can also be given with a 2-digit year (e.g. 06 = 2006).

Own Id: OTP-8610

Nicolas Thauvin

[httpd] - Added support (again) for the documented debugging features. See the User's Guide Configuration chapter for more info.

Own Id: OTP-8624

Inets 5.3.2

Improvements and New Features

-

Fixed Bugs and Malfunctions

[httpc] - Memory leak plugged. The profile manager never cleaned up in its handler database. This meant that with each new request handler, another entry was created that was never deleted. Eventually the request id counter (used as a key) would wrap, but the machine would most likely run out of memory before that happened.

Own Id: OTP-8542

Lev Walkin

[httpc] - https requests with default port (443) not handled properly.

Own Id: OTP-8607

jebu ittiachen

Inets 5.3.1

Improvements and New Features

-

Fixed Bugs and Malfunctions

[httpc] - Badly formatted error reason for errors occurring during initial connect to a server. Also, the possible error reasons was not properly documented.

Own Id: OTP-8508

Aux Id: seq11407

[httpd] - Issues with ESI erl_script_timeout.

The erl_script_timeout config option is ducumented as a number of seconds. But when parsing the config, in the new format (not a config file), it was handled as if in number of milliseconds.

When the erl-script-timeout time was exceeded, the server incorrectly marked the answer as sent, thereby leaving client hanging (with an incomplete answer). This has been changed, so that now the socket will be closed.

Own Id: OTP-8509

Inets 5.3

Improvements and New Features

[httpc] - Allow users to pass socket options to the transport module when making requests.

See the socket_opts option in the request/4 or set_options/1,2 for more info,

Own Id: OTP-8352

[httpc] Fix bug crafting Host header when port is not 80.

The host header should include the port number as well as the host name when making a request to a server listening on a port other than the HTTP default of 80. Currently, only the host name is included. This is important to make the http client more compliant with the HTTP specification.

Own Id: OTP-8371

Kelly McLaughlin

[httpc|httpd] http_chunk data handling/passing improvement.

This is a modification to the http_chunk module to forward any full chunk received, regardless of whether the size field for the following chunk has been received yet. This allows http_chunk to be used in situations where a long term HTTP connection is used to send periodic status updates as individual chunks. Previously a given chunk would not be forwarded to the client process until the size for the next chunk had been read which rendered the module difficult to use for the scenario described.

Bernard Duggan

Own Id: OTP-8351

Include the inets test suite in the release of the application.

Own Id: OTP-8349

[httpc] - It is now possible to configure the client to deliver an async reply to more receivers then the calling process.

See the receiver option for more info,

Own Id: OTP-8106

[httpd] - Methods "PUT" and "DELETE" now allowed.

huntermorris@gmail.com

Own Id: OTP-8103

[httpc] Several more or less critical fixes:

Initial call between the httpc manager and request handler was synchronous.

When the manager starts a new request handler, this is no longer a synchronous operation. Previously, the new request handler made the connection to the server and issuing of the first request (the reason for starting it) in the gen_server init function. If the connection for some reason "took some time", the manager hanged, leaving all other activities by that manager also hanging.

As a side-effect of these changes, some modules was also renamed, and a new api module, httpc, has been introduced (the old module http is not removed, but is now just wrapper for httpc).

Own Id: OTP-8016

* POTENTIAL INCOMPATIBILITY *

Fixed Bugs and Malfunctions

[httpd] The server did not fully support the documented module callback api. Specifically, the load function should be able to return the atom ok, but this was not accepted.

Own Id: OTP-8359

Fixing various documentation-related bugs (bad quotes).

Own Id: OTP-8327

Fixing minor Dialyzer and copyright problem(s).

Own Id: OTP-8315

[httpc] - Added basic sanity check of option value combinations.

adam.kocoloski@gmail.com

Own Id: OTP-8056

Inets 5.2

Improvements and New Features

[ftpc] - Start of the FTP client has been changed in the following way:

It is now also possible to start a standalone FTP client process using the re-introduced ftp:open/2 function.

This is an alternative to starting the client using the inets service framework.

The old ftp:open/1, undocumented, function, caused the client to be hooken into the inets service supervision framework. This is no longer the case.

* POTENTIAL INCOMPATIBILITY *

Previously, the FTP client attempted to use IPv6, unless otherwise instructed (the ip_v6_disabled flag), and only used IPv4 if this did not work. This has now been changed.

A new option, ipfamily, has been introduced, with the default value inet (IPv4).

See ftp:open/2 for more info.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-8258

The documentation is now built with open source tools (xsltproc and fop) that exists on most platforms. One visible change is that the frames are removed.

Own Id: OTP-8249

Fixed Bugs and Malfunctions

[httpc] - Streaming to file did not work.

dizzyd@gmail.com

Own Id: OTP-8204

[ftpc] - The ftp:ls/2 function (LIST command) and the ftp:nlist/2 function (NLST command) with wildcards did not work properly.

These functions is documented as working on directories, but this is actually not according the standard. The LIST and NLST commands are specified to operate on a directory or other group of files, or a file.

Previously, an attempt was made to check if the listing returned by the server was actually an error message. This was done by changing remote directory (cd) into the (assumed) "directory". This may work if Pathname was actually a directory, but as this is not always the case, this test does not work. Instead, we now return the actual server result and leave the interpretation to the caller.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-8247

Aux Id: seq11407

[httpc] - Fixes various bugs in timeout and keep-alive queue handling.

When a queued request times, out the error mssage is sent the owner of the active request.

Requests in the keep-alive queue is forgotten when handler terminates.

Timeout out requests are retried.

Jean-Sébastien Pédron

Own Id: OTP-8248

[httpd] - Unnecessarily strict matching when handling closing sockets.

Own Id: OTP-8280

Inets 5.1.3

Improvements and New Features

-

Fixed Bugs and Malfunctions

[httpc] - Raise condition. When http:request is called and httpc_manager selects a session where there's already a pending request, then the connection handler for that session effectively resets its parser, readying it for the response to the second request. But if there are still some inbound packets for the response to the first request, things get confused.

tomas.abrahamsson@gmail.com

Own Id: OTP-8154

Inets 5.1.2

Improvements and New Features

[httpc] - Added http option connect_timeout for http client request. The connect_timeout option is used for the initial request, when the client connects to the server. Default value is that of the timeout option.

See the request/4,5 function for more info.

Own Id: OTP-7298

Fixed Bugs and Malfunctions

[httpd] - Failed to create listen socket with invalid option combo. The http-server failed to create its listen socket when the bind-address was an IPv4-address (a tuple of size 4) and the ipfamily option was inet6fb4.

Own Id: OTP-8118

Aux Id: seq11321

[httpd] - Removed documentation for non-existing function (httpd_util:header/2,3,4).

Own Id: OTP-8101

Inets 5.1.1

Improvements and New Features

[httpd] - When starting inets (the web-server) and supplying a descriptor on the command line (example: erl -httpd_8888 <descriptor>) it is now possible to specify which ip-family to use: inet | inet6 | inet6fb4.

Example: erl -httpd_8888 10|inet6

When starting the web-server either using a file with property list (the proplist_file) or a an property list, using the ipfamily option: {ipfamily, inet | inet6 | inet6fb4}.

Finally, when starting the web-server using the classical apache-style config file, the BindAddress directive has been augmented to allow the specification of the IpFamily: BindAddress blirk.ericsson.se|inet

Default is inet6fb4 which emulates the behaviour of the previous version.

See the Communication properties section for more info.

Own Id: OTP-8069

Aux Id: seq11086

Fixed Bugs and Malfunctions

[httpc] - Reception of unexpected data causes handler crash.

Own Id: OTP-8052

Inets 5.1

Improvements and New Features

[httpc] Added support for web services using only basic auth, with a token as the user part and no password part.

twoggle@gmail.com

Own Id: OTP-7998

[httpc] - Bind HTTP client to IP-addr. It is now possible to specify an alternate ip-address and port to be used when the client connects to the server.

As a side-effect of this, the option ipv6 has been removed and replaced by the ipfamily option.

See http:set_options/1,2 for more info.

* POTENTIAL INCOMPATIBILITY *

Own Id: OTP-8004

Fixed Bugs and Malfunctions

Updated guard tests (i.e. is_list(L) instead of list(L) and possibly andalso/orelse instead of ","/";").

Own Id: OTP-7994

[httpc] - Remove use of the deprecated regexp module.

Own Id: OTP-8001

[httpc] - The option max_keep_alive_length was not handled properly.

Own Id: OTP-8005

Introduction

Purpose

Inets is a container for Internet clients and servers including the following:

An HTTP client and server

The HTTP client and server are HTTP 1.1 compliant as defined in RFC 2616.

Prerequisites

It is assumed that the reader is familiar with the Erlang programming language, concepts of OTP, and has a basic understanding of and HTTP protocol.

Inets

Service Concept

Each client and server in Inets is viewed as a service. Services can be configured to be started at application startup or dynamically in runtime. To run Inets as a distributed application that handles application failover and takeover, configure the services to be started at application startup. When starting the Inets application, the Inets top supervisor starts a number of subsupervisors and worker processes for handling the provided services. When starting services dynamically, new children are added to the supervision tree, unless the service is started with the standalone option. In this case the service is linked to the calling process and all OTP application features, such as soft upgrade, are lost.

Services to be configured for startup at application startup are to be put into the Erlang node configuration file on the following form:

[{inets, [{services, ListofConfiguredServices}]}].

For details of what to put in the list of configured services, see the documentation for the services to be configured.

HTTP Client

Configuration

The HTTP client default profile is started when the Inets application is started and is then available to all processes on that Erlang node. Other profiles can also be started at application startup, or profiles can be started and stopped dynamically in runtime. Each client profile spawns a new process to handle each request, unless a persistent connection can be used with or without pipelining. The client adds a host header and an empty te header if there are no such headers present in the request.

The client supports IPv6 as long as the underlying mechanisms also do so.

The following is to be put in the Erlang node application configuration file to start a profile at application startup:

[{inets, [{services, [{httpc, PropertyList}]}]}]

For valid properties, see httpc.

Getting Started

Start Inets:

1> inets:start().
ok

The following calls use the default client profile. Use the proxy "www-proxy.mycompany.com:8000", except from requests to localhost. This applies to all the following requests.

Example:

2> httpc:set_options([{proxy, {{"www-proxy.mycompany.com", 8000},
["localhost"]}}]).
ok

The following is an ordinary synchronous request:

3> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
.. httpc:request(get, {"http://www.erlang.org", []}, [], []).

With all the default values presented, a get request can also be written as follows:

4> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
.. httpc:request("http://www.erlang.org").

The following is a https request and with verification of the host:

5> {ok, {{Version, 200, ReasonPhrase}, Headers, Body}} =
.. httpc:request(get, {"https://www.erlang.org", []}, [{ssl, httpc:ssl_verify_host_options(true)}], []).

The following is an ordinary asynchronous request:

6> {ok, RequestId} =
.. httpc:request(get, {"http://www.erlang.org", []}, [], [{sync, false}]).

The result is sent to the calling process as {http, {ReqestId, Result}}.

In this case, the calling process is the shell, so the following result is received:

7> receive {http, {RequestId, Result}} -> ok after 500 -> error end.
ok

This sends a request with a specified connection header:

8> {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
.. httpc:request(get, {"http://www.erlang.org", [{"connection", "close"}]},
.. [], []).

This sends an HTTP request over a unix domain socket (experimental):

9> httpc:set_options([{ipfamily, local}, {unix_socket,"/tmp/unix_socket/consul_http.sock"}]).
10> {ok, {{NewVersion, 200, NewReasonPhrase}, NewHeaders, NewBody}} =
 .. httpc:request(put, {"http:///v1/kv/foo", [], [], "hello"}, [], []).

Start an HTTP client profile:

10> {ok, Pid} = inets:start(httpc, [{profile, foo}]).
{ok, <0.45.0>}

The new profile has no proxy settings, so the connection is refused:

11> httpc:request("http://www.erlang.org", foo).
{error, econnrefused}

Stop the HTTP client profile:

12> inets:stop(httpc, foo).
ok

Alternative way to stop the HTTP client profile:

13> inets:stop(httpc, Pid).
ok

HTTP server

Configuration

The HTTP server, also referred to as httpd, handles HTTP requests as described in RFC 2616 with a few exceptions, such as gateway and proxy functionality. The server supports IPv6 as long as the underlying mechanisms also do so.

The server implements numerous features, such as:

Secure Sockets Layer (SSL)

Erlang Scripting Interface (ESI)

Common Gateway Interface (CGI)

User Authentication (using Mnesia, Dets or plain text database)

Common Logfile Format (with or without disk_log(3) support)

URL Aliasing

Action Mappings

Directory Listings

The configuration of the server is provided as an Erlang property list.

As of Inets 5.0 the HTTP server is an easy to start/stop and customize web server providing the most basic web server functionality. Inets is designed for embedded systems and if you want a full-fledged web server there are other erlang open source alternatives.

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 httpd.

The available configuration properties are as follows:

httpd_service() -> {httpd, httpd()}
httpd()         -> [httpd_config()]
httpd_config()  -> {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:

{proplist_file, file()} - File containing an Erlang property list, followed by a full stop, describing the HTTP server configuration.

{debug, debug()} - Can enable trace on all functions or only exported functions on chosen modules.

{accept_timeout, integer()} - Sets the wanted time-out value for the server to set up a request connection.

Getting Started

Start Inets:

1> inets:start().
ok

Start an HTTP server with minimal required configuration. If you specify port 0, an arbitrary available port is used, and you can use function info to find which port number that was picked:

2> {ok, Pid} = inets:start(httpd, [{port, 0}, {server_root,"/tmp"},
.. {document_root,"/tmp/htdocs"}, {bind_address, "localhost"}]).
{ok, 0.79.0}

Call info:

3> httpd:info(Pid).
[{mime_types,[{"html","text/html"},{"htm","text/html"}]},
 {server_name,"machine.local"},
 {bind_address, {127,0,0,1}},
 {server_root,"/tmp"},
 {port,59408},
 {document_root,"/tmp/htdocs"},
 {ipfamily,inet}]

Reload the configuration without restarting the server:

4> httpd:reload_config([{port, 59408},
.. {server_root,"/tmp/www_test"}, {document_root,"/tmp/www_test/htdocs"},
.. {bind_address, "localhost"}], non_disturbing).
ok.

Note

port and bind_address cannot be changed. Clients trying to access the server during the reload get a service temporary unavailable answer.

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 bind_address must be the IP address reported by function info and cannot be the hostname that is allowed when putting in bind_address.

Dynamic Web Pages

Inets HTTP server provides two ways of creating dynamic web pages, each with its own advantages and disadvantages:

CGI scripts (deprecated) - 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.

ESI-functions - Erlang Server Interface (ESI) functions provide a tight and efficient interface to the execution of Erlang functions. This interface, on the other hand, is Inets specific.

CGI Version 1.1, RFC 3875

Note

mod_cgi and mod_actions are deprecated since OTP 29 and will be removed in OTP 30. Use mod_esi instead for dynamic page generation.

The module mod_cgi enables execution of CGI scripts on the server. A file matching the definition of a ScriptAlias config directive is treated as a CGI script. A CGI script is executed by the server and its output is returned to the client.

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 RFC 3875.

ESI

The Erlang server interface is implemented by module mod_esi.

ERL Scheme

The erl scheme is designed to mimic plain CGI, but without the extra overhead. An URL that calls an Erlang erl function has the following syntax (regular expression):

http://your.server.org/***/Module[:/]Function(?QueryString|/PathInfo)

*** depends on how the ErlScriptAlias config directive has been used.

The module Module referred to must be found in the code path, and it must define a function Function with an arity of two or three. It is preferable to implement a function with arity three, as it permits to send chunks of the web page to the client during the generation phase instead of first generating the whole web page and then sending it to the client. The option to implement a function with arity two is only kept for backwards compatibility reasons. For implementation details of the ESI callback function, see mod_esi.

Logging

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:

remotehost - Remote hostname.

rfc931 - The client remote username (RFC 931).

authuser - The username used for authentication.

[date] - Date and time of the request (RFC 1123).

"request" - The request line exactly as it came from the client (RFC 1945).

status - The HTTP status code returned to the client (RFC 1945).

bytes - The content-length of the document transferred.

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

Erlang Web Server API

The process of handling an HTTP request involves several steps, such as:

Setting up connections, sending and receiving data.

URI to filename translation.

Authentication/access checks.

Retrieving/generating the response.

Logging.

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 Section Inets Web Server Modules.

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.

Note

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.

API Description

Each module that implements server functionality using the Erlang web server API is to implement the following call back functions:

do/1 (mandatory) - the function called when a request is to be handled

load/2

store/2

remove/1

The latter functions are needed only when new config directives are to be introduced. For details, see httpd.

Inets Web Server Modules

The convention is that all modules implementing some web server functionality has the name mod_*. When configuring the web server, an appropriate selection of these modules is to be present in the module directive. Notice that there are some interaction dependencies to take into account, so the order of the modules cannot be random.

mod_actions - Filetype/Method-Based Script Execution

Note

mod_cgi and mod_actions are deprecated since OTP 29 and will be removed in OTP 30. Use mod_esi instead for dynamic page generation.

This module runs CGI scripts whenever a file of a certain type or HTTP method (see RFC 1945) is requested.

Uses the following Erlang Web Server API interaction data:

real_name - from mod_alias.

Exports the following Erlang Web Server API interaction data, if possible:

{new_request_uri, RequestURI} - An alternative RequestURI has been generated.

mod_alias - URL Aliasing

The mod_alias module makes it possible to map different parts of the host file system into the document tree, that is, creates aliases and redirections.

Exports the following Erlang Web Server API interaction data, if possible:

{real_name, PathData} - PathData is the argument used for API function mod_alias:path/3.

mod_auth - User Authentication

The mod_auth module provides for basic user authentication using textual files, Dets databases as well as Mnesia databases.

Uses the following Erlang Web Server API interaction data:

real_name - from mod_alias

Exports the following Erlang Web Server API interaction data:

{remote_user, User} - The username used for authentication.

Mnesia As Authentication Database

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 first_start/0 is to be used the first time. It creates the schema and the tables. start/0 is to be used in consecutive startups. start/0 starts Mnesia and waits for the tables to be initiated. This function must only be used when the schema and the tables are already created.

-module(mnesia_test).
-export([start/0,load_data/0]).
-include_lib("inets/include/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 mod_auth.hrl, so that file must be included. first_start/0 creates a schema that specifies on which nodes the database is to reside. Then it starts Mnesia and creates the tables. The first argument is the name of the tables, the second argument is a list of options of how to create the table, see mnesia, documentation for more information. As the implementation of the mod_auth_mnesia saves one row for each user, the type must be bag. When the schema and the tables are created, function mnesia:start/0 is used to start Mnesia and waits for the tables to be loaded. Mnesia uses the directory specified as mnesia_dir at startup if specified, otherwise Mnesia uses the current directory. For security reasons, ensure that the Mnesia tables are stored outside the document tree of the HTTP server. If they are placed in the directory which it protects, clients can download the tables. Only the Dets and Mnesia storage methods allow writing of dynamic user data to disk. plain is a read only method.

mod_cgi - CGI Scripts

Note

mod_cgi and mod_actions are deprecated since OTP 29 and will be removed in OTP 30. Use mod_esi instead for dynamic page generation.

This module handles invoking of CGI scripts.

mod_dir - Directories

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:

real_name - from mod_alias

Exports the following Erlang Web Server API interaction data:

{mime_type, MimeType} - The file suffix of the incoming URL mapped into a MimeType.

mod_disk_log - Logging Using Disk_Log.

Standard logging using the "Common Logfile Format" and disk_log.

Uses the following Erlang Web Server API interaction data:

remote_user - from mod_auth

mod_esi - Erlang Server Interface

The mod_esi module implements the Erlang Server Interface (ESI) providing a tight and efficient interface to the execution of Erlang functions.

Uses the following Erlang web server API interaction data:

remote_user - from mod_auth

Exports the following Erlang web server API interaction data:

{mime_type, MimeType} - The file suffix of the incoming URL mapped into a MimeType

mod_get - Regular GET Requests

This module is responsible for handling GET requests to regular files. GET requests for parts of files is handled by mod_range.

Uses the following Erlang web server API interaction data:

real_name - from mod_alias

mod_head - Regular HEAD Requests

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:

real_name - from mod_alias

mod_log - Logging Using Text Files.

Standard logging using the "Common Logfile Format" and text files.

Uses the following Erlang Web Server API interaction data:

remote_user - from mod_auth

mod_range - Requests with Range Headers

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:

real_name - from mod_alias

mod_responsecontrol - Requests with If* Headers

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. httpd controls each field in the following order and if one of the fields does not match the current state, the request is rejected with a proper response:

If-modified

If-Unmodified

If-Match

If-Nomatch

Uses the following Erlang Web Server API interaction data:

real_name - from mod_alias

Exports the following Erlang Web Server API interaction data:

{if_range, send_file} - The conditions for the range request are not fulfilled. The response must not be treated as a range request, instead it must be treated as an ordinary get request.

mod_security - Security Filter

The mod_security module serves as a filter for authenticated requests handled in mod_auth. It provides a possibility to restrict users from access for a specified amount of time if they fail to authenticate several times. It logs failed authentication as well as blocking of users, and it calls a configurable callback module when the events occur.

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.

mod_trace - TRACE Request

mod_trace is responsible for handling of TRACE requests. Trace is a new request method in HTTP/1.1. The intended use of trace requests is for testing. The body of the trace response is the request message that the responding web server or proxy received.

Serving files from the command line

httpd includes functionality to quickly serve files from the command line. In its simplest form, erl -S httpd will serve files in the local directory on localhost.

--port - Sets the port to bind on. Defaults to 8000.

--bind - Sets the bind address to listen on. Defaults to 127.0.0.1.

DIRECTORY - Sets the directory to serve data from. Defaults to the current directory.

For example, to serve files from directory test_results on port 4000:

erl -S httpd serve --port 4000 test_results

For a full reference of all options, run erl -S httpd serve --help.

Hardening

Introduction

The Erlang/OTP inets application provides an HTTP client (httpc) and an HTTP server (httpd), intended to be used as libraries in other applications.

Different deployments have very different security requirements. A development tool running on localhost has different needs than a service exposed to the public internet. Because of this, inets ships with permissive defaults that prioritize ease of use. This guide describes how to tighten those defaults for production deployments.

This guide targets OTP 29. Where behavior differs from OTP 28 and earlier, the differences are noted inline. A summary of changes is provided in the Changes from OTP 28 section.

For general configuration, see the httpc and httpd reference manuals.

HTTP Client (httpc)

TLS Configuration

Since OTP 26.0, httpc verifies the server certificate by default when no {ssl, ...} option is given. The default is equivalent to calling httpc:ssl_verify_host_options(true), which enables verify_peer with the system CA store.

If you need to customize TLS settings (for example, to pin a specific CA or restrict protocol versions), pass them explicitly:

SslOpts = [{verify, verify_peer},
           {cacertfile, "/path/to/ca-bundle.crt"},
           {versions, ['tlsv1.2', 'tlsv1.3']}],
httpc:request(get, {"https://example.com", []}, [{ssl, SslOpts}], []).

Warning

Setting {ssl, [{verify, verify_none}]} disables certificate verification entirely. This makes the connection vulnerable to man-in-the-middle attacks and should only be used for testing.

Timeouts

The default value for both timeout and connect_timeout is infinity, meaning a request can hang indefinitely. Always set explicit timeouts in production:

HttpOpts = [{timeout, 30000},        %% 30 s total request timeout
            {connect_timeout, 5000}], %% 5 s TCP connect timeout
httpc:request(get, {"https://example.com", []}, HttpOpts, []).

timeout - Maximum time for the entire request (connect + send + receive). Default: infinity.

connect_timeout - Maximum time for the TCP connection setup. Defaults to the value of timeout.

autoretry (since OTP 28.4) - Controls how long the client honors a server's Retry-After header before retrying. The client automatically retries the request once on a 503 response with a Retry-After header. Default: infinity (always honor the server's value). Set to 0 to disable automatic retries, or to a finite number of milliseconds to cap the wait. If the server's Retry-After value exceeds the configured limit, no retry is performed. Before OTP 28.4, the retry behavior was hardcoded to only honor Retry-After values of 99 seconds or less.

HttpOpts = [{timeout, 30000},
            {connect_timeout, 5000},
            {autoretry, 10000}].  %% Wait at most 10 s for Retry-After

Redirect Following

By default, httpc follows HTTP redirects automatically ({autoredirect, true}). This can be exploited for Server-Side Request Forgery (SSRF) if the client is used to fetch user-supplied URLs, because a redirect can point to internal hosts or services.

For requests to untrusted URLs, disable automatic redirects and validate the target manually. Check that the redirect target does not resolve to a private network address (10.x, 127.x, 169.254.x, etc.) before following it:

httpc:request(get, {UserUrl, []},
              [{autoredirect, false}, {timeout, 10000}], []).

Client Connection Limits

Profile-level options control how many connections httpc keeps open. The per-host defaults are conservative, but the global limit defaults to infinity:

max_connections_open (since OTP 29) - Maximum total number of open handlers across all hosts. Default: infinity. Set a finite value to prevent unbounded resource consumption:

httpc:set_options([{max_connections_open, 100}]).

max_sessions - Maximum persistent connections per host:port. Default: 2.

max_keep_alive_length - Maximum queued requests on a keep-alive connection. Default: 5.

max_pipeline_length - Maximum pipelined requests per connection. Default: 2.

pipeline_timeout - Idle time before closing a pipelined connection, in milliseconds. Default: 0 (pipelining disabled). Pipelining is only used when this is set to a positive value.

keep_alive_timeout - Idle time before closing a persistent connection. Default: 120000 ms (2 minutes).

For a service making requests to many different hosts, set max_connections_open to a value appropriate for your system's file descriptor limits.

Cookie Handling

Cookies are disabled by default ({cookies, disabled}). If you enable them, prefer verify mode, which lets you inspect cookies before they are stored via httpc:store_cookies/3:

httpc:set_options([{cookies, verify}]).

Proxy Configuration

When using a proxy, ensure that the no_proxy list excludes internal hosts that should not be routed through the proxy:

httpc:set_options([
    {proxy, {{"proxy.example.com", 8080},
             ["localhost", "*.internal.example.com"]}}
]).

For HTTPS traffic through a proxy, configure https_proxy separately. The client uses the HTTP CONNECT method to establish a tunnel through the proxy. By default, https_proxy inherits the value of proxy.

Sensitive Options

Warning

The following options can introduce injection, file overwrite, or data leakage vulnerabilities if misused.

Per-request options:

{socket_opts, Opts} - Passed directly to the transport layer without validation. Avoid exposing this to untrusted input.

{headers_as_is, true} - Bypasses header normalization. This can enable header injection if header values come from untrusted sources.

{stream, {self, once}} or {stream, Filename} - Streaming to a file path could overwrite files. Validate paths before use.

Per-profile options:

{verbose, debug | trace} - May log sensitive data such as headers containing authorization tokens.

HTTP Server (httpd)

Enable TLS

By default, httpd listens in plaintext ({socket_type, ip_comm}). For any deployment beyond localhost, enable TLS:

httpd:start_service([{port, 8443},
                     {server_root, "/var/www"},
                     {document_root, "/var/www/htdocs"},
                     {socket_type, {ssl, [{cert_keys, [#{certfile => "/path/to/cert.pem",
                                                          keyfile => "/path/to/key.pem"}]},
                                          {versions, ['tlsv1.2', 'tlsv1.3']}]}}]).

Bind Address

The default {bind_address, any} listens on all network interfaces. Restrict this to the intended interface:

{bind_address, {127, 0, 0, 1}}   %% Localhost only

or

{bind_address, "192.168.1.10"}    %% Specific interface

Request Size Limits

Several size limits default to nolimit, which allows arbitrarily large requests that can exhaust memory. Set explicit limits:

[{max_uri_size, 8192},              %% 8 KB URI limit
 {max_header_size, 10240},          %% 10 KB (already the default)
 {max_body_size, 10_485_760},       %% 10 MB body limit
 {max_content_length, 10_485_760}]  %% 10 MB Content-Length check

max_uri_size - Maximum URI length in bytes. Default: nolimit.

max_header_size - Maximum total header size. Default: 10240 (10 KB).

max_body_size - Maximum received body size during parsing. Default: nolimit.

max_content_length - Rejects requests whose Content-Length header exceeds this value with a 413 response, before reading the body. Default: 100_000_000 (100 MB).

max_client_body_chunk - When handling large PUT or POST bodies via mod_esi, setting this option enforces chunked delivery to the ESI callback. This prevents the server from buffering the entire request body in memory, which could be exploited to cause memory exhaustion.

Note

max_body_size and max_content_length serve different purposes. max_content_length is a fast pre-check on the header value. max_body_size limits the actual bytes received. Set both for defense in depth.

Server Connection Limits

max_clients - Maximum simultaneous connections. Default: 150. Tune this to your expected load and available resources.

keep_alive - Controls whether persistent connections are used. Default: true. Disabling persistent connections (false) eliminates certain classes of connection-reuse attacks at the cost of performance.

max_keep_alive_request - Maximum requests per persistent connection. Default: infinity. Set a finite value to prevent a single connection from monopolizing server resources:

{max_keep_alive_request, 1000}

keep_alive_timeout - Seconds before closing an idle persistent connection. Default: 150.

minimum_bytes_per_second - Closes connections that transfer data below this rate. Not set by default. Enable it to mitigate slow-rate DoS attacks (for example, Slowloris):

{minimum_bytes_per_second, 100}

The following table summarizes when each limit is checked during the request lifecycle:

Stage | Event | Limit checked
1 | TCP connected | max_clients
2 | Headers received | max_uri_size, max_header_size
3 | Content-Length checked | max_content_length
4 | Body received | max_body_size
5 | Idle on keep-alive | keep_alive_timeout
6 | Slow transfer | minimum_bytes_per_second

Server Identity

The default {server_tokens, minimal} reveals the complete inets version string in the Server response header (for example, inets/9.3.1). Despite the name, minimal still includes the full version number. This helps attackers identify known vulnerabilities. Reduce information disclosure:

{server_tokens, none}   %% Omit the Server header entirely

or

{server_tokens, prod}   %% Just "inets", no version

Module Chain

The {modules, ...} option controls which httpd modules are active. In OTP 29, mod_cgi and mod_actions are deprecated and removed from the default module list. The default is:

[mod_alias, mod_auth, mod_esi,
 mod_dir, mod_get, mod_head, mod_log, mod_disk_log]

Warning

In OTP 28 and earlier, the default module list also includes mod_cgi and mod_actions, enabling CGI execution out of the box. If you are running an older release, removing these modules manually is especially important.

Review this list and remove modules you do not need:

mod_cgi and mod_actions - Enable CGI script execution. Deprecated in OTP 29 and scheduled for removal in OTP 30. If you still need CGI support, add them explicitly to your module list. CGI introduces a large attack surface (arbitrary process execution, environment variable injection).

mod_dir - Enables directory listing. Remove it to prevent information disclosure about your file structure.

mod_esi - Enables Erlang Scripting Interface. If used, restrict it with erl_script_alias to a whitelist of allowed modules.

mod_trace - Handles HTTP TRACE requests. TRACE can be exploited in cross-site tracing (XST) attacks. This module is not in the default list but should never be added in production.

A minimal module chain for a static file server:

{modules, [mod_alias, mod_get, mod_head, mod_log]}

Authentication (mod_auth)

If using mod_auth:

Avoid {auth_type, plain} in production. It stores passwords in cleartext files. Prefer dets or mnesia.

Place auth files outside document_root. The auth_user_file and auth_group_file must not be accessible via HTTP.

Set auth_access_password to a strong value. When not set or set to "NoPassword", no password is required for the authentication management API.

Use IP-based restrictions (allow_from, deny_from) as an additional layer, not as the sole access control mechanism.

Warning

The mod_auth module implements HTTP Basic Authentication, which transmits credentials in base64 encoding (effectively cleartext). Always use TLS when authentication is enabled.

Brute Force Protection (mod_security)

mod_security acts as a filter on top of mod_auth, tracking failed login attempts per user and temporarily blocking users who exceed a threshold. This mitigates credential-stuffing and brute-force password guessing attacks.

Enable mod_security to throttle authentication brute force attempts:

{security_directory, {"/protected", [
    {data_file, "/var/lib/httpd/security.dat"},
    {max_retries, 3},
    {block_time, 60},        %% Block for 60 minutes
    {fail_expire_time, 30},  %% Remember failures for 30 minutes
    {auth_timeout, 30}
]}}

data_file - Path to the persistent security data file. Store this outside document_root. Required for mod_security to persist blocked-user state across server restarts.

max_retries - Maximum failed authentication attempts before the user is blocked. Default: 3.

block_time - Minutes a blocked user remains locked out. Default: 60.

fail_expire_time - Minutes before a failed attempt is forgotten. If the user does not retry within this window, the failure counter resets. Default: 30.

auth_timeout - Seconds a successful authentication is remembered. After expiry the user must re-authenticate. Default: 30.

Warning

mod_security must appear after mod_auth in the module chain. It relies on mod_auth to perform the actual authentication; mod_security only observes the results and enforces blocking policy.

For runtime inspection and manual blocking, see mod_security (list_blocked_users/1, block_user/5, unblock_user/4).

CGI and ESI Execution

script_alias maps URL paths to CGI script directories. Ensure the mapped directory contains only intended scripts and is not writable by the web server process.

erl_script_alias controls which Erlang modules can be called via ESI. Always specify an explicit whitelist:

{erl_script_alias, {"/esi", [my_allowed_module]}}

Never use a wildcard or overly broad module list.

script_timeout and erl_script_timeout default to 15 seconds. Review whether this is appropriate for your use case.

script_nocache and erl_script_nocache - When set to true, the server adds HTTP header fields preventing proxies from caching dynamic responses. Default: false. Enable these to prevent stale or sensitive dynamic content from being served from proxy caches.

Warning

The script_alias path resolution can bypass mod_auth directory protections depending on module ordering. Ensure mod_auth appears before mod_cgi in the module chain, and test that authentication is enforced on CGI paths.

Logging

Enable logging to detect and investigate security incidents:

[{error_log, "/var/log/httpd/error.log"},
 {security_log, "/var/log/httpd/security.log"},
 {transfer_log, "/var/log/httpd/access.log"},
 {log_format, combined}]  %% Includes referer and user-agent (default: common)

For production systems, the disk_log variants (transfer_disk_log, error_disk_log, security_disk_log) are recommended as they support wrap logs with configurable size limits, preventing log files from consuming all available disk space.

For integration with the OTP logger framework, where my_httpd is the ServerID atom used in the logger domain hierarchy [otp, inets, httpd, ServerID, error]:

{logger, [{error, my_httpd}]}

Ensure log files are rotated and that log directories are not writable by the web server process.

Hardened Example

The following is a complete example combining the recommendations above for an httpd deployment serving static files with TLS:

httpd:start_service([
    {port, 8443},
    {bind_address, {127, 0, 0, 1}},
    {server_root, "/var/www"},
    {document_root, "/var/www/htdocs"},
    {server_tokens, none},
    {socket_type, {ssl, [{cert_keys, [#{certfile => "/path/to/cert.pem",
                                        keyfile => "/path/to/key.pem"}]},
                         {versions, ['tlsv1.2', 'tlsv1.3']}]}},
    {modules, [mod_alias, mod_auth, mod_security, mod_get, mod_head, mod_log]},
    {max_clients, 100},
    {max_keep_alive_request, 1000},
    {keep_alive_timeout, 60},
    {max_uri_size, 8192},
    {max_header_size, 10240},
    {max_body_size, 10_485_760},
    {max_content_length, 10_485_760},
    {minimum_bytes_per_second, 100},
    {error_log, "/var/log/httpd/error.log"},
    {transfer_log, "/var/log/httpd/access.log"},
    {log_format, combined}
]).

And a hardened httpc request:

HttpOpts = [{timeout, 30000},
            {connect_timeout, 5000},
            {autoredirect, false},
            {autoretry, 10000},
            {ssl, [{verify, verify_peer},
                   {cacerts, public_key:cacerts_get()},
                   {versions, ['tlsv1.2', 'tlsv1.3']}]}],
httpc:request(get, {"https://example.com", []}, HttpOpts, []).

General Recommendations

Defense in Depth

The inets application provides application-level security controls. For production deployments, combine these with:

Network-level controls - Firewalls, network segmentation, and rate limiting.

OS-level controls - Run the BEAM VM as an unprivileged user. Use file system permissions to protect configuration files, log files, and credential stores.

Reverse proxy - Consider placing httpd behind a dedicated reverse proxy (such as Nginx or HAProxy) that provides additional request filtering, rate limiting, and TLS termination.

Monitoring

Use the OTP logger framework to monitor for:

Repeated authentication failures (potential brute-force attacks).

Unusual request patterns (potential scanning or fuzzing).

Connection limit exhaustion (potential DoS).

Keep Up to Date

Security vulnerabilities are fixed in new releases of Erlang/OTP. Monitor the Erlang/OTP releases and apply updates promptly.

Changes from OTP 28

If you are upgrading from OTP 28 or running an older release, be aware of the following differences:

httpc

autoretry not available before OTP 28.4 - The {autoretry, timeout()} option for httpc was introduced in OTP 28.4. On older releases, the client still retries on 503 with Retry-After, but only honors values of 99 seconds or less (hardcoded). The new option allows configuring this limit or disabling retries entirely with {autoretry, 0}.

max_connections_open not available before OTP 29 - The {max_connections_open, integer()} profile option for httpc was introduced in OTP 29. On older releases, there is no global limit on the number of open handlers.

TLS verification default - httpc has verified server certificates by default since OTP 26.0. On releases before 26.0, you must pass {ssl, httpc:ssl_verify_host_options(true)} explicitly or connections will proceed without certificate verification.

httpd

mod_cgi and mod_actions in default modules - In OTP 28 and earlier, the default {modules, ...} list includes mod_cgi and mod_actions, enabling CGI execution by default. In OTP 29 these modules are deprecated and removed from the defaults. On older releases, remove them explicitly.

inets

The Inets services API.

This module provides the most basic API to the clients and servers that are part of the Inets application, such as start and stop.

Data types

Type definitions that are used more than once in this module:

service() = httpc | httpd

property() = atom()

See also

httpc, httpd

Summary

Types

inets_service()

service_info()

Functions

service_names()

Returns a list of available service names.

services()

Returns a list of currently running services.

services_info()

Returns a list of currently running services where each service is described by an [{Option, Value}] list. The information in the list is specific for each service and each service has probably its own info function that gives more details about the service. If specific service info returns {error, Reason}, Info will contain Reason term.

start()

Equivalent to start/1.

start(Type)

Starts the Inets application. Default type is temporary. See also application.

start(Service, ServiceConfig)

Equivalent to start/3.

start(Service, ServiceConfig, How)

Dynamically starts an Inets service after the Inets application has been started.

stop()

Stops the Inets application. See also application.

stop(Service, Reference)

Stops a started service of the Inets application or takes down a stand_alone-service gracefully. When option stand_alone is used in start, only the pid is a valid argument to stop.

Types

inets_service()

(not exported)

-type inets_service() :: httpd | httpc.

service_info()

(not exported)

-type service_info() ::
          {inets_service(), pid(), [{profile, atom()}] | no_such_service | service_not_available}.

Functions

service_names()

-spec service_names() -> [inets_service()].

Returns a list of available service names.

services()

-spec services() -> [{inets_service(), pid()}] | {error, inets_not_started}.

Returns a list of currently running services.

Note

Services started as stand_alone are not listed.

services_info()

-spec services_info() -> [service_info()] | {error, inets_not_started}.

Returns a list of currently running services where each service is described by an [{Option, Value}] list. The information in the list is specific for each service and each service has probably its own info function that gives more details about the service. If specific service info returns {error, Reason}, Info will contain Reason term.

start()

-spec start() -> ok | {error, Reason} when Reason :: term().

Equivalent to start/1.

start(Type)

-spec start(Type) -> ok | {error, Reason} when Type :: application:restart_type(), Reason :: term().

Starts the Inets application. Default type is temporary. See also application.

start(Service, ServiceConfig)

-spec start(Service, ServiceConfig) -> Result
               when
                   Service :: inets_service(),
                   ServiceConfig :: ConfPropList | ConfFile,
                   ConfPropList :: [{Property, Value}],
                   ConfFile :: string(),
                   Property :: term(),
                   Value :: term(),
                   Result :: {ok, pid()} | {error, term()}.

Equivalent to start/3.

start(Service, ServiceConfig, How)

-spec start(Service, ServiceConfig, How) -> Result
               when
                   Service :: inets_service(),
                   ServiceConfig :: ConfPropList | ConfFile,
                   How :: inets | stand_alone,
                   ConfPropList :: [{Property, Value}],
                   ConfFile :: string(),
                   Property :: term(),
                   Value :: term(),
                   Result :: {ok, pid()} | {error, term()}.

Dynamically starts an Inets service after the Inets application has been started.

Note

Dynamically started services are not handled by application takeover and failover behavior when Inets is run as a distributed application. Nor are they automatically restarted when the Inets application is restarted. As long as the Inets application is operational, they are supervised and can be soft code upgraded.

A service started as stand_alone, that is, the service is not started as part of the Inets application, lose all OTP application benefits, such as soft upgrade. The stand_alone-service is linked to the process that started it. Usually some supervision functionality is still in place and in some sense the calling process becomes the top supervisor.

Warning

The stand_alone option is considered deprecated.

stop()

-spec stop() -> ok.

Stops the Inets application. See also application.

stop(Service, Reference)

-spec stop(Service, Reference) -> ok | {error, Reason}
              when
                  Service :: inets_service() | stand_alone,
                  Reference :: pid() | term(),
                  Reason :: term().

Stops a started service of the Inets application or takes down a stand_alone-service gracefully. When option stand_alone is used in start, only the pid is a valid argument to stop.

httpc

An HTTP/1.1 client

This module provides the API to an HTTP/1.1 compatible client according to RFC 2616. Caching is not supported.

Note

When starting the Inets application, a manager process for the default profile is started. The functions in this API that do not explicitly use a profile accesses the default profile. A profile keeps track of proxy options, cookies, and other options that can be applied to more than one request.

If the scheme https is used, the SSL application must be started. When https links need to go through a proxy, the CONNECT method extension to HTTP-1.1 is used to establish a tunnel and then the connection is upgraded to TLS. However, "TLS upgrade" according to RFC 2817 is not supported.

Pipelining is only used if the pipeline time-out is set, otherwise persistent connections without pipelining are used. That is, the client always waits for the previous response before sending the next request.

Some examples are provided in the Inets User's Guide.

HTTP client service start & stop

An HTTP client can be configured to start when starting the Inets application or started dynamically in runtime by calling the Inets application API inets:start(httpc, ServiceConfig) or inets:start(httpc, ServiceConfig, How), see inets. The configuration options are as follows:

{profile, Profile :: atom() | pid()} - Name of the profile. This option is mandatory.

{data_dir, Path :: string()} - Directory where the profile can save persistent data. If omitted, all cookies are treated as session cookies. Path represents a file path or directory path.

The client can be stopped using inets:stop(httpc, Pid) or inets:stop(httpc, Profile).

Warning

Please note that httpc normalizes input URIs before internal processing and special care shall be taken when the URI has percent ("%") characters. A percent serves as the indicator for percent-encoded octets and it must be percent-encoded as "%25" for that octet to be used as data within the URI.

For example, in order to send an HTTP GET request with the URI http://localhost/foo%25bar, the percent character must be percent-encoded when creating the request: httpc:request("http://localhost/foo%2525bar").

See also

RFC 2616, inets, gen_tcp, ssl

Summary

Functions

cancel_request(RequestId)

Equivalent to cancel_request/2.

cancel_request(RequestId, Profile)

Cancels an asynchronous HTTP request. Notice that this does not guarantee that the request response is not delivered. Because it is asynchronous, the request can already have been completed when the cancellation arrives.

cookie_header(Url)

Equivalent to cookie_header/2.

cookie_header(Url, ProfileOrOpts)

Returns the cookie header that would have been sent when making a request to Url using profile Profile. If no profile is specified, the default profile is used.

cookie_header(Url, Opts, Profile)

Returns the cookie header that would have been sent when making a request to Url using profile Profile. If no profile is specified, the default profile is used.

get_options(OptionItems)

Equivalent to get_options/2.

get_options(OptionItems, Profile)

Retrieves the options currently used by the client.

info()

Equivalent to info/1.

info(Profile)

Produces a list of miscellaneous information. Intended for debugging. If no profile is specified, the default profile is used.

request(Url)

Equivalent to request/2.

request(Url, Profile)

Equivalent to httpc:request(get, {Url, []}, [], []).

request(Method, Request, HttpOptions, Options)

Equivalent to request/5.

request(Method, Request, HttpOptions, Options, Profile)

Sends an HTTP request. The function can be both synchronous and asynchronous. In the latter case, the function returns {ok, RequestId} and then the information is delivered to the receiver depending on that value.

reset_cookies()

Equivalent to reset_cookies/1.

reset_cookies(Profile)

Resets (clears) the cookie database for the specified Profile. If no profile is specified the default profile is used.

set_options(Options)

Equivalent to set_options/2.

set_options(Options, Profile)

Sets options to be used for subsequent requests.

ssl_verify_host_options(WildcardHostName)

Returns ssl options which can be used to verify the host, uses public_key:cacerts_get() to read CA certicates and if WildcardHostName is true adds the hostname check from public_key:public_key:pkix_verify_hostname_match_fun(https) to the options.

store_cookies(SetCookieHeaders, Url)

Equivalent to store_cookies/3.

store_cookies(SetCookieHeaders, Url, Profile)

Saves the cookies defined in SetCookieHeaders in the client profile cookie database. Call this function if option cookies is set to verify. If no profile is specified, the default profile is used.

stream_next(Pid)

Triggers the next message to be streamed, that is, the same behavior as active ones for sockets.

which_cookies()

Equivalent to which_cookies/1.

which_cookies(Profile)

Produces a list of the entire cookie database. Intended for debugging/testing purposes. If no profile is specified, the default profile is used.

which_sessions()

Equivalent to which_sessions/1.

which_sessions(Profile)

This function is intended for debugging only. It produces a slightly processed dump of the session database. The first list of the session information tuple will contain session information on an internal format. The last two lists of the session information tuple should always be empty if the code is working as intended. If no profile is specified, the default profile is used.

Functions

cancel_request(RequestId)

(since OTP R13B04)

-spec cancel_request(RequestId) -> ok when RequestId :: any().

Equivalent to cancel_request/2.

cancel_request(RequestId, Profile)

(since OTP R13B04)

-spec cancel_request(RequestId, Profile) -> ok when RequestId :: any(), Profile :: atom() | pid().

Cancels an asynchronous HTTP request. Notice that this does not guarantee that the request response is not delivered. Because it is asynchronous, the request can already have been completed when the cancellation arrives.

cookie_header(Url)

(since OTP R13B04)

-spec cookie_header(Url) -> HttpHeader | {error, Reason}
                       when
                           Url :: uri_string:uri_string(),
                           HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                           Reason :: term().

Equivalent to cookie_header/2.

cookie_header(Url, ProfileOrOpts)

(since OTP R13B04)

-spec cookie_header(Url, ProfileOrOpts) -> HttpHeader | {error, Reason}
                       when
                           Url :: uri_string:uri_string(),
                           HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                           ProfileOrOpts :: Profile | Opts,
                           Profile :: atom() | pid(),
                           Opts :: [CookieHeaderOpt],
                           CookieHeaderOpt :: {ipv6_host_with_brackets, boolean()},
                           Reason :: term().

Returns the cookie header that would have been sent when making a request to Url using profile Profile. If no profile is specified, the default profile is used.

Option ipv6_host_with_bracket deals with how to parse IPv6 addresses. For details, see argument Options of request/4,5.

cookie_header(Url, Opts, Profile)

(since OTP R15B)

-spec cookie_header(Url, Opts, Profile) -> HttpHeader | {error, Reason}
                       when
                           Url :: uri_string:uri_string(),
                           HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                           Profile :: atom() | pid(),
                           Opts :: [CookieHeaderOpt],
                           CookieHeaderOpt :: {ipv6_host_with_brackets, boolean()},
                           Reason :: term().

Returns the cookie header that would have been sent when making a request to Url using profile Profile. If no profile is specified, the default profile is used.

Option ipv6_host_with_bracket deals with how to parse IPv6 addresses. For details, see argument Options of request/4,5.

get_options(OptionItems)

(since OTP R15B01)

-spec get_options(OptionItems) -> {ok, Values} | {error, Reason}
                     when
                         OptionItems :: all | [OptionItem],
                         OptionItem ::
                             proxy | https_proxy | max_sessions | max_connections_open |
                             keep_alive_timeout | max_keep_alive_length | pipeline_timeout |
                             max_pipeline_length | cookies | ipfamily | ip | port | socket_opts |
                             verbose | unix_socket,
                         Values :: [{OptionItem, term()}],
                         Reason :: term().

Equivalent to get_options/2.

get_options(OptionItems, Profile)

(since OTP R15B01)

-spec get_options(OptionItems, Profile) -> {ok, Values} | {error, Reason}
                     when
                         OptionItems :: all | [OptionItem],
                         OptionItem ::
                             proxy | https_proxy | max_sessions | max_connections_open |
                             keep_alive_timeout | max_keep_alive_length | pipeline_timeout |
                             max_pipeline_length | cookies | ipfamily | ip | port | socket_opts |
                             verbose | unix_socket,
                         Values :: [{OptionItem, term()}],
                         Profile :: atom() | pid(),
                         Reason :: term().

Retrieves the options currently used by the client.

info()

(since OTP R15B02)

-spec info() -> list() | {error, Reason} when Reason :: term().

Equivalent to info/1.

info(Profile)

(since OTP R15B02)

-spec info(Profile) -> list() | {error, Reason} when Reason :: term(), Profile :: atom() | pid().

Produces a list of miscellaneous information. Intended for debugging. If no profile is specified, the default profile is used.

request(Url)

(since OTP R13B04)

-spec request(uri_string:uri_string()) -> {ok, Result} | {error, term()}
                 when
                     Result ::
                         {StatusLine :: {HttpVersion, StatusCode, string()},
                          [HttpHeader],
                          HttpBodyResult} |
                         {StatusCode, HttpBodyResult} |
                         RequestId | saved_to_file,
                     HttpBodyResult :: string() | binary(),
                     HttpVersion :: string(),
                     StatusCode :: non_neg_integer(),
                     HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                     RequestId :: any().

Equivalent to request/2.

request(Url, Profile)

(since OTP R13B04)

-spec request(Url, Profile) -> {ok, Result} | {error, term()}
                 when
                     Url :: uri_string:uri_string(),
                     Profile :: atom() | pid(),
                     Result ::
                         {StatusLine, [HttpHeader], HttpBodyResult} |
                         {StatusCode, HttpBodyResult} |
                         RequestId | saved_to_file,
                     HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                     HttpBodyResult :: string() | binary(),
                     StatusLine :: {HttpVersion, StatusCode, string()},
                     HttpVersion :: string(),
                     StatusCode :: non_neg_integer(),
                     RequestId :: any().

Equivalent to httpc:request(get, {Url, []}, [], []).

request(Method, Request, HttpOptions, Options)

(since OTP R13B04)

-spec request(Method, Request, HttpOptions, Options) -> {ok, Result} | {error, term()}
                 when
                     Method :: head | get | put | patch | post | trace | options | delete,
                     Request ::
                         {uri_string:uri_string(), [HttpHeader]} |
                         {uri_string:uri_string(), [HttpHeader], ContentType :: string(), HttpBody},
                     HttpBody ::
                         iolist() |
                         binary() |
                         {fun((Accumulator :: term()) -> eof | {ok, iolist(), Accumulator :: term()}),
                          Accumulator :: term()} |
                         {chunkify,
                          fun((Accumulator :: term()) -> eof | {ok, iolist(), Accumulator :: term()}),
                          Accumulator :: term()},
                     HttpOptions :: [HttpOption],
                     HttpOption ::
                         {timeout, timeout()} |
                         {connect_timeout, timeout()} |
                         {ssl, [ssl:tls_option()]} |
                         {autoredirect, boolean()} |
                         {autoretry, timeout()} |
                         {proxy_auth, {string(), string()}} |
                         {version, HttpVersion} |
                         {relaxed, boolean()},
                     Options :: [OptionRequest],
                     OptionRequest ::
                         {sync, boolean()} |
                         {stream, StreamTo} |
                         {body_format, BodyFormat} |
                         {full_result, boolean()} |
                         {headers_as_is, boolean()} |
                         {socket_opts, [SocketOpt]} |
                         {receiver, Receiver} |
                         {ipv6_host_with_brackets, boolean()},
                     StreamTo :: none | self | {self, once} | file:name_all(),
                     SocketOpt :: term(),
                     BodyFormat :: string | binary,
                     Receiver ::
                         pid() |
                         fun((term()) -> term()) |
                         {ReceiverModule :: atom(), ReceiverFunction :: atom(), ReceiverArgs :: list()},
                     Result ::
                         {StatusLine, [HttpHeader], HttpBodyResult} |
                         {StatusCode, HttpBodyResult} |
                         RequestId | saved_to_file,
                     StatusCode :: non_neg_integer(),
                     StatusLine :: {HttpVersion, StatusCode, string()},
                     HttpVersion :: string(),
                     HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                     HttpBodyResult :: string() | binary(),
                     RequestId :: any().

Equivalent to request/5.

request(Method, Request, HttpOptions, Options, Profile)

(since OTP R13B04)

-spec request(Method, Request, HttpOptions, Options, Profile) -> {ok, Result} | {error, term()}
                 when
                     Method :: head | get | put | patch | post | trace | options | delete,
                     Request ::
                         {uri_string:uri_string(), [HttpHeader]} |
                         {uri_string:uri_string(), [HttpHeader], ContentType :: string(), HttpBody},
                     HttpBody ::
                         iolist() |
                         binary() |
                         {fun((Accumulator :: term()) -> eof | {ok, iolist(), Accumulator :: term()}),
                          Accumulator :: term()} |
                         {chunkify,
                          fun((Accumulator :: term()) -> eof | {ok, iolist(), Accumulator :: term()}),
                          Accumulator :: term()},
                     HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                     HttpOptions :: [HttpOption],
                     HttpOption ::
                         {timeout, timeout()} |
                         {connect_timeout, timeout()} |
                         {ssl, [ssl:tls_option()]} |
                         {autoredirect, boolean()} |
                         {autoretry, timeout()} |
                         {proxy_auth, {string(), string()}} |
                         {version, HttpVersion} |
                         {relaxed, boolean()},
                     Options :: [OptionRequest],
                     OptionRequest ::
                         {sync, boolean()} |
                         {stream, StreamTo} |
                         {body_format, BodyFormat} |
                         {full_result, boolean()} |
                         {headers_as_is, boolean()} |
                         {socket_opts, [SocketOpt]} |
                         {receiver, Receiver} |
                         {ipv6_host_with_brackets, boolean()},
                     StreamTo :: none | self | {self, once} | file:name_all(),
                     BodyFormat :: string | binary,
                     SocketOpt :: term(),
                     Receiver ::
                         pid() |
                         fun((term()) -> term()) |
                         {ReceiverModule :: atom(), ReceiverFunction :: atom(), ReceiverArgs :: list()},
                     Profile :: atom() | pid(),
                     HttpVersion :: string(),
                     Result ::
                         {StatusLine, [HttpHeader], HttpBodyResult} |
                         {StatusCode, HttpBodyResult} |
                         RequestId | saved_to_file,
                     StatusLine :: {HttpVersion, StatusCode, string()},
                     StatusCode :: non_neg_integer(),
                     HttpBodyResult :: string() | binary(),
                     RequestId :: any().

Sends an HTTP request. The function can be both synchronous and asynchronous. In the latter case, the function returns {ok, RequestId} and then the information is delivered to the receiver depending on that value.

When Profile is stand_alone only the pid can be used.

HTTP options:

timeout - Time-out time for the request.

The clock starts ticking when the request is sent.

Time is in milliseconds.

Default is infinity.

connect_timeout - Connection time-out time, used during the initial request, when the client is connecting to the server.

Time is in milliseconds.

Default is the value of option timeout.

ssl - This is the SSL/TLS connecting configuration option.

Default value is obtained by calling httpc:ssl_verify_host_options(true). . See ssl:connect/2,3,4 for available options.

autoredirect - The client automatically retrieves the information from the new URI and returns that as the result, instead of a 30X-result code.

For some 30X-result codes, automatic redirect is not allowed. In these cases the 30X-result is always returned.

Default is true.

autoretry - The client automatically retries the request once after receiving a Retry-After header from the server.

Sometimes servers can suggest a value that is not suitable for application, so this option allows limiting the wait time (in miliseconds) inbetween requests, or disabling the retry with a value of 0. If a value of Retry-After header exceeds the set value, no retry will be done.

Default is atom infinity.

Since OTP 28.4

proxy_auth - A proxy-authorization header using a tuple where the first element is the username and the second element of the tuple is the password added to the request.

version - Can be used to make the client act as an HTTP/1.0 client. By default this is an HTTP/1.1 client. When using HTTP/1.0 persistent connections are not used.

Default is the string "HTTP/1.1".

relaxed - If set to true, workarounds for known server deviations from the HTTP-standard are enabled.

Default is false.

Options details:

sync - Option for the request to be synchronous or asynchronous.

Default is true.

stream - Streams the body of a 200 or 206 response to the calling process or to a file. When streaming to the calling process using option self, the following stream messages are sent to that process: {http, {RequestId, stream_start, Headers}}, {http, {RequestId, stream, BinBodyPart}}, and {http, {RequestId, stream_end, Headers}}.

When streaming to the calling processes using option {self, once}, the first message has an extra element, that is, {http, {RequestId, stream_start, Headers, Pid}}. This is the process id to be used as an argument to httpc:stream_next/1 to trigger the next message to be sent to the calling process.

Notice that chunked encoding can add headers so that there are more headers in the stream_end message than in stream_start. When streaming to a file and the request is asynchronous, the message {http, {RequestId, saved_to_file}} is sent.

Default is none.

body_format - Defines if the body is to be delivered as a string or binary. This option is only valid for the synchronous request.

Default is string. Asynchronous requests always use binary.

full_result - Defines if a "full result" is to be returned to the caller (that is, the body, the headers, and the entire status line) or not (the body and the status code).

Default is true.

headers_as_is - Defines if the headers provided by the user are to be made lower case or to be regarded as case sensitive.

The HTTP standard requires them to be case insensitive. Use this feature only if there is no other way to communicate with the server or for testing purpose. When this option is used, no headers are automatically added. All necessary headers must be provided by the user.

Default is false.

socket_opts - Socket options to be used for this request.

See the options used by gen_tcp and ssl

Overrides any value set by function set_options.

The validity of the options is not checked by the HTTP client they are assumed to be correct and passed on to ssl application and inet driver, which may reject them if they are not correct.

Note

Persistent connections are not supported when setting the socket_opts option. When socket_opts is not set the current implementation assumes the requests to the same host, port combination will use the same socket options.

By default the socket options set by function set_options/1,2 are used when establishing a connection.

receiver - Defines how the client delivers the result of an asynchronous request (sync has the value false).

pid/0 - Messages are sent to this process in the format {http, ReplyInfo}.

alias/0 - Messages are sent to this special reference in the format {http, ReplyInfo}.

function/1 - Information is delivered to the receiver through calls to the provided fun Receiver(ReplyInfo).

{Module, Function, Args} - Information is delivered to the receiver through calls to the callback function apply(Module, Function, [ReplyInfo | Args]).

In all of these cases, ReplyInfo has the following structure:

 {RequestId, saved_to_file}
 {RequestId, {error, Reason}}
 {RequestId, Result}
 {RequestId, stream_start, Headers}
 {RequestId, stream_start, Headers, HandlerPid}
 {RequestId, stream, BinBodyPart}
 {RequestId, stream_end, Headers}

Default is the pid of the process calling the request function (self/0).

ipv6_host_with_brackets - Defines when parsing the Host-Port part of an URI with an IPv6 address with brackets, if those brackets are to be retained (true) or stripped (false).

Default is false.

reset_cookies()

(since OTP R13B04)

-spec reset_cookies() -> Void when Void :: term().

Equivalent to reset_cookies/1.

reset_cookies(Profile)

(since OTP R13B04)

-spec reset_cookies(Profile) -> Void when Profile :: atom() | pid(), Void :: term().

Resets (clears) the cookie database for the specified Profile. If no profile is specified the default profile is used.

set_options(Options)

(since OTP R13B04)

-spec set_options(Options) -> ok | {error, Reason}
                     when
                         Options :: [Option],
                         Option ::
                             {proxy, {Proxy, NoProxy}} |
                             {https_proxy, {Proxy, NoProxy}} |
                             {max_connections_open, MaxConnectionsOpen} |
                             {max_sessions, MaxSessions} |
                             {max_keep_alive_length, MaxKeepAlive} |
                             {keep_alive_timeout, KeepAliveTimeout} |
                             {max_pipeline_length, MaxPipeline} |
                             {pipeline_timeout, PipelineTimeout} |
                             {cookies, CookieMode} |
                             {ipfamily, IpFamily} |
                             {ip, IpAddress} |
                             {port, Port} |
                             {socket_opts, SocketOpts} |
                             {verbose, VerboseMode} |
                             {unix_socket, UnixSocket},
                         Proxy :: {HostName, Port},
                         Port :: non_neg_integer(),
                         NoProxy :: [DomainDesc | HostName | IpAddressDesc],
                         MaxSessions :: integer(),
                         MaxConnectionsOpen :: integer(),
                         MaxKeepAlive :: integer(),
                         KeepAliveTimeout :: integer(),
                         MaxPipeline :: integer(),
                         PipelineTimeout :: integer(),
                         CookieMode :: enabled | disabled | verify,
                         IpFamily :: inet | inet6 | local | inet6fb4,
                         IpAddressDesc :: string(),
                         IpAddress :: inet:ip_address(),
                         VerboseMode :: false | verbose | debug | trace,
                         SocketOpts :: [SocketOpt],
                         SocketOpt :: term(),
                         UnixSocket :: file:name_all(),
                         Reason :: term(),
                         DomainDesc :: string(),
                         HostName :: string().

Equivalent to set_options/2.

set_options(Options, Profile)

(since OTP R13B04)

-spec set_options(Options, Profile) -> ok | {error, Reason}
                     when
                         Options :: [Option],
                         Option ::
                             {proxy, {Proxy, NoProxy}} |
                             {https_proxy, {Proxy, NoProxy}} |
                             {max_connections_open, MaxConnectionsOpen} |
                             {max_sessions, MaxSessions} |
                             {max_keep_alive_length, MaxKeepAlive} |
                             {keep_alive_timeout, KeepAliveTimeout} |
                             {max_pipeline_length, MaxPipeline} |
                             {pipeline_timeout, PipelineTimeout} |
                             {cookies, CookieMode} |
                             {ipfamily, IpFamily} |
                             {ip, IpAddress} |
                             {port, Port} |
                             {socket_opts, [SocketOpt]} |
                             {verbose, VerboseMode} |
                             {unix_socket, UnixSocket},
                         Profile :: atom() | pid(),
                         SocketOpt :: term(),
                         Proxy :: {HostName, Port},
                         Port :: non_neg_integer(),
                         NoProxy :: [DomainDesc | HostName | IpAddressDesc],
                         MaxConnectionsOpen :: integer() | infinity,
                         MaxSessions :: integer(),
                         MaxKeepAlive :: integer(),
                         KeepAliveTimeout :: integer(),
                         MaxPipeline :: integer(),
                         PipelineTimeout :: integer(),
                         CookieMode :: enabled | disabled | verify,
                         IpFamily :: inet | inet6 | local | inet6fb4,
                         IpAddressDesc :: string(),
                         IpAddress :: inet:ip_address(),
                         VerboseMode :: false | verbose | debug | trace,
                         UnixSocket :: string(),
                         Reason :: term(),
                         DomainDesc :: string(),
                         HostName :: string().

Sets options to be used for subsequent requests.

HostName - Example: "localhost" or "foo.bar.se"

DomainDesc - Example "*.Domain" or "*.ericsson.se"

IpAddressDesc - Example: "134.138" or "[FEDC:BA98" (all IP addresses starting with 134.138 or FEDC:BA98), "66.35.250.150" or "[2010:836B:4179::836B:4179]" (a complete IP address). proxy defaults to {undefined, []}, that is, no proxy is configured and https_proxy defaults to the value of proxy.

MaxConnectionsOpen - MaxConnectionsOpen Maximum number of handlers that can be opened at the same time. Default is infinity which means that it's not limited.

MaxSessions - MaxSessions Maximum number of persistent connections to a host. Default is 2.

MaxKeepAlive - MaxKeepAlive Maximum number of outstanding requests on the same connection to a host. Default is 5.

KeepAliveTimeout - KeepAliveTimeout If a persistent connection is idle longer than the keep_alive_timeout in milliseconds, the client closes the connection. The server can also have such a time-out but do not take that for granted. Default is 120000 (= 2 min).

MaxPipeline - MaxPipeline Maximum number of outstanding requests on a pipelined connection to a host. Default is 2.

PipelineTimeout - PipelineTimeout If a persistent connection is idle longer than the pipeline_timeout in milliseconds, the client closes the connection. Default is 0, which results in pipelining not being used.

CookieMode - If cookies are enabled, all valid cookies are automatically saved in the cookie database of the client manager. If option verify is used, function store_cookies/2 has to be called for the cookies to be saved. Default is disabled.

IpFamily - Default is inet. With inet6fb4 option, IPv6 will be preferred but if connection fails, an IPv4 fallback connection attempt will be made.

IpAddress - If the host has several network interfaces, this option specifies which one to use. See gen_tcp:connect/3,4 for details.

Port - Example: 8080. Local port number to use. See gen_tcp:connect/3,4 for details.

SocketOpts - The options are appended to the socket options used by the client. These are the default values when a new request handler is started (for the initial connect). They are passed directly to the underlying transport (gen_tcp or SSL) without verification.

See the options used by gen_tcp and ssl

VerboseMode - Default is false. This option is used to switch on (or off) different levels of Erlang trace on the client. It is a debug feature.

Profile - When started stand_alone only the pid can be used.

UnixSocket - Experimental option for sending HTTP requests over a unix domain socket. The value of unix_socket shall be the full path to a unix domain socket file with read/write permissions for the erlang process. Default is undefined.

Note

If possible, the client keeps its connections alive and uses persistent connections with or without pipeline depending on configuration and current circumstances. The HTTP/1.1 specification does not provide a guideline for how many requests that are ideal to be sent on a persistent connection. This depends much on the application.

A long queue of requests can cause a user-perceived delay, as earlier requests can take a long time to complete. The HTTP/1.1 specification suggests a limit of two persistent connections per server, which is the default value of option max_sessions.

The current implementation assumes the requests to the same host, port combination will use the same socket options.

ssl_verify_host_options(WildcardHostName)

(since OTP 25.1)

-spec ssl_verify_host_options(WildcardHostName) -> list() when WildcardHostName :: boolean().

Returns ssl options which can be used to verify the host, uses public_key:cacerts_get() to read CA certicates and if WildcardHostName is true adds the hostname check from public_key:public_key:pkix_verify_hostname_match_fun(https) to the options.

store_cookies(SetCookieHeaders, Url)

(since OTP R14B02)

-spec store_cookies(SetCookieHeaders, Url) -> ok | {error, Reason}
                       when
                           SetCookieHeaders :: [HttpHeader],
                           HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                           Url :: term(),
                           Reason :: term().

Equivalent to store_cookies/3.

store_cookies(SetCookieHeaders, Url, Profile)

(since OTP R14B02)

-spec store_cookies(SetCookieHeaders, Url, Profile) -> ok | {error, Reason}
                       when
                           SetCookieHeaders :: [HttpHeader],
                           HttpHeader :: {Field :: [byte()], Value :: binary() | iolist()},
                           Url :: term(),
                           Profile :: atom() | pid(),
                           Reason :: term().

Saves the cookies defined in SetCookieHeaders in the client profile cookie database. Call this function if option cookies is set to verify. If no profile is specified, the default profile is used.

stream_next(Pid)

(since OTP R13B04)

-spec stream_next(Pid) -> ok when Pid :: pid().

Triggers the next message to be streamed, that is, the same behavior as active ones for sockets.

which_cookies()

(since OTP R13B04)

-spec which_cookies() -> [CookieStores]
                       when
                           CookieStores :: {cookies, Cookies} | {session_cookies, Cookies},
                           Cookies :: [term()].

Equivalent to which_cookies/1.

which_cookies(Profile)

(since OTP R13B04)

-spec which_cookies(Profile) -> [CookieStores]
                       when
                           Profile :: atom() | pid(),
                           CookieStores :: {cookies, Cookies} | {session_cookies, Cookies},
                           Cookies :: [term()].

Produces a list of the entire cookie database. Intended for debugging/testing purposes. If no profile is specified, the default profile is used.

which_sessions()

(since OTP R15B02)

-spec which_sessions() -> SessionInfo
                        when
                            SessionInfo :: {GoodSession, BadSessions, NonSessions},
                            GoodSession :: [Session],
                            BadSessions :: [term()],
                            NonSessions :: [term()],
                            Session :: term().

Equivalent to which_sessions/1.

which_sessions(Profile)

(since OTP R15B02)

-spec which_sessions(Profile) -> SessionInfo
                        when
                            Profile :: atom() | pid(),
                            SessionInfo :: {GoodSession, BadSessions, NonSessions},
                            GoodSession :: [Session],
                            BadSessions :: [term()],
                            NonSessions :: [term()],
                            Session :: term().

This function is intended for debugging only. It produces a slightly processed dump of the session database. The first list of the session information tuple will contain session information on an internal format. The last two lists of the session information tuple should always be empty if the code is working as intended. If no profile is specified, the default profile is used.

httpd behaviour

HTTP server API

An implementation of an HTTP 1.1 compliant web server, as defined in RFC 2616. Provides web server start options, administrative functions, and an Erlang callback API.

Data types

Type definitions that are used more than once in this module:

boolean() = true | false

string/0 = list of ASCII characters

path() = string() representing a file or a directory path

ip_address() = {N1,N2,N3,N4} % IPv4 | {K1,K2,K3,K4,K5,K6,K7,K8} % IPv6

hostname() = string() representing a host, for example, "foo.bar.com"

property() = atom()

HTTP server service start & stop

A web server can be configured to start when starting the Inets application, or dynamically in runtime by calling the Inets application API inets:start(httpd, ServiceConfig) or inets:start(httpd, ServiceConfig, How), see inets. The configuration options, also called properties, are as follows:

File Properties

When the web server is started at application start time, the properties are to be fetched from a configuration file that can consist of a regular Erlang property list, that is, [{Option, Value}], where Option = property()and Value = term(), followed by a full stop. If the web server is started dynamically at runtime, a file can still be specified but also the complete property list.

{proplist_file, path()}
If this property is defined, Inets expects to find all other properties defined in this file. The file must include all properties listed under mandatory properties.

Note

Note support for legacy configuration file with Apache syntax is dropped in OTP-23.

Mandatory Properties

{port, integer()}
The port that the HTTP server listen to. If zero is specified as port, an arbitrary available port is picked and function httpd:info/2 can be used to determine which port was picked.

{server_root, path()}
Defines the home directory of the server, where log files, and so on, can be stored. Relative paths specified in other properties refer to this directory.

{document_root, path()}
Defines the top directory for the documents that are available on the HTTP server.

Communication Properties

{bind_address, ip_address() | hostname() | any}
Default is any

{server_name, string()}
The name of your server, normally a fully qualified domain name.

If not given, this defaults to net_adm:localhost().

{profile, atom()}
Used together with bind_address and port to uniquely identify a HTTP server. This can be useful in a virtualized environment, where there can be more that one server that has the same bind_address and port. If this property is not explicitly set, it is assumed that the bind_address and port uniquely identifies the HTTP server.

{socket_type, ip_comm | {ip_comm, Config::proplist()} | {ssl, Config::proplist()}}
For ip_comm configuration options, see gen_tcp:listen/2, some options that are used internally by httpd cannot be set.

For SSL configuration options, see ssl:listen/2.

Default is ip_comm.

Note

OTP-25 deprecates the communication properties {socket_type, ip_comm | {ip_comm, Config::proplist()} | {essl, Config::proplist()}} replacing it by {socket_type, ip_comm | {ip_comm, Config::proplist()} | {ssl, Config::proplist()}}.

{ipfamily, inet | inet6}
Default is inet, legacy option inet6fb4 no longer makes sense and will be translated to inet.

{minimum_bytes_per_second, integer()}
If given, sets a minimum of bytes per second value for connections.

If the value is unreached, the socket closes for that connection.

The option is good for reducing the risk of "slow DoS" attacks.

Erlang Web Server API Modules

{modules, [atom()]}
Defines which modules the HTTP server uses when handling requests. Default is [mod_alias, mod_auth, mod_esi, mod_dir, mod_get, mod_head, mod_log, mod_disk_log]. Notice that some mod-modules are dependent on others, so the order cannot be entirely arbitrary. See the Inets Web Server Modules in the User's Guide for details.

Limit properties

{customize, atom()}
A callback module to customize the inets HTTP servers behaviour see httpd_custom_api

{disable_chunked_transfer_encoding_send, boolean()}
Allows you to disable chunked transfer-encoding when sending a response to an HTTP/1.1 client. Default is false.

{keep_alive, boolean()}
Instructs the server whether to use persistent connections when the client claims to be HTTP/1.1 compliant. Default is true.

{keep_alive_timeout, integer()}
The number of seconds the server waits for a subsequent request from the client before closing the connection. Default is 150.

{max_body_size, integer()}
Limits the size of the message body of an HTTP request. Default is no limit.

{max_clients, integer()}
Limits the number of simultaneous requests that can be supported. Default is 150.

{max_header_size, integer()}
Limits the size of the message header of an HTTP request. Default is 10240.

{max_content_length, integer()}
Maximum content-length in an incoming request, in bytes. Requests with content larger than this are answered with status 413. Default is 100000000 (100 MB).

{max_uri_size, integer()}
Limits the size of the HTTP request URI. Default is no limit.

{max_keep_alive_request, integer()}
The number of requests that a client can do on one connection. When the server has responded to the number of requests defined by max_keep_alive_requests, the server closes the connection. The server closes it even if there are queued request. Default is no limit.

{max_client_body_chunk, integer()}
Enforces chunking of a HTTP PUT or POST body data to be delivered to the mod_esi callback. Note this is not supported for mod_cgi. Default is no limit e.i the whole body is delivered as one entity, which could be very memory consuming. mod_esi.

Administrative Properties

{mime_types, [{MimeType, Extension}] | path()}
MimeType = string() and Extension = string(). Files delivered to the client are MIME typed according to RFC 1590. File suffixes are mapped to MIME types before file delivery. The mapping between file suffixes and MIME types can be specified in the property list.

Mime types can also be read from a file. The file should contain lines in the form MediaType [Extensions...], such as text/html html htm. To configure this, specify the path to it, such as {mime_types, "/etc/mime.types"}.

If unset, conf/mime.types under server_root will be used if it exists, otherwise, the default is [{"html","text/html"},{"htm","text/html"}].

{mime_type, string()}
When the server is asked to provide a document type that cannot be determined by the MIME Type Settings, the server uses this default type.

{server_admin, string()}
Defines the email-address of the server administrator to be included in any error messages returned by the server.

{server_tokens, none|prod|major|minor|minimal|os|full|{private, string()}}
Defines the look of the value of the server header.

Example: Assuming the version of Inets is 5.8.1, the server header string can look as follows for the different values of server-tokens:

none - "" % A Server: header will not be generated

prod - "inets"

major - "inets/5"

minor - "inets/5.8"

minimal - "inets/5.8.1"

os - "inets/5.8.1 (unix)"

full - "inets/5.8.1 (unix/linux) OTP/R15B"

{private, "foo/bar"} - "foo/bar"

By default, the value is as before, that is, minimal.

{logger, Options::list()}
Currently only one option is supported:

{error, ServerID::atom()} - Produces logger events on logger level error under the hierarchical logger domain: [otp, inets, httpd, ServerID, error] The built in logger formatting function produces log entries from the error reports:

#{server_name => string()
  protocol => internal | 'TCP' | 'TLS' | 'HTTP',
  transport => "TCP" | "TLS", %% Present when protocol = 'HTTP'
  uri => string(), %% Present when protocol = 'HTTP' and URI is valid
  peer => inet:peername(),
  host => inet:hostname(),
  reason => term()
}

An example of a log entry with only default settings of logger

=ERROR REPORT==== 9-Oct-2019::09:33:27.350235 ===
   Server: My Server
 Protocol: HTTP
Transport: TLS
      URI: /not_there
     Host: 127.0.1.1:80
     Peer: 127.0.0.1:45253
   Reason: [{statuscode,404},{description,"Object Not Found"}]

Using this option makes mod_log and mod_disk_log error logs redundant.

Add the filter

{fun logger_filters:domain/2,
    {log,equal,[otp,inets, httpd, ServerID, error]}

to appropriate logger handler to handle the events. For example to write the error log from an httpd server with a ServerID of my_server to a file you can use the following sys.config:

[{kernel,
 [{logger,
  [{handler, http_error_test, logger_std_h,
    #{config => #{ file => "log/http_error.log" },
      filters => [{inets_httpd, {fun logger_filters:domain/2,
                                 {log, equal,
                                  [otp, inets, httpd, my_server, error]
                                 }}}],
      filter_default => stop }}]}]}].

or if you want to add it to the default logger via an API:

logger:add_handler_filter(default,
                          inets_httpd,
                          {fun logger_filters:domain/2,
                           {log, equal,
                            [otp, inets, httpd, my_server, error]}}).

{log_format, common | combined}
Defines if access logs are to be written according to the common log format or the extended common log format. The common format is one line looking like this: remotehost rfc931 authuser [date] "request" status bytes.

Here:

remotehost - Remote.

rfc931 - The remote username of the client (RFC 931).

authuser - The username used for authentication.

[date] - Date and time of the request (RFC 1123).

"request" - The request line as it came from the client (RFC 1945).

status - The HTTP status code returned to the client (RFC 1945).

bytes - The content-length of the document transferred.

The combined format is one line looking like this: remotehost rfc931 authuser [date] "request" status bytes "referer" "user_agent"

In addition to the earlier:

"referer" - The URL the client was on before requesting the URL (if it could not be determined, a minus sign is placed in this field).

"user_agent" - The software the client claims to be using (if it could not be determined, a minus sign is placed in this field).

This affects the access logs written by mod_log and mod_disk_log.

{error_log_format, pretty | compact}
Default is pretty. If the error log is meant to be read directly by a human, pretty is the best option.

pretty has a format corresponding to:

io:format("[~s] ~s, reason: ~n ~p ~n~n", [Date, Msg, Reason]).

compact has a format corresponding to:

io:format("[~s] ~s, reason: ~w ~n", [Date, Msg, Reason]).

This affects the error logs written by mod_log and mod_disk_log.

URL Aliasing Properties - Requires mod_alias

{alias, {Alias, RealName}}
Alias = string() and RealName = string(). alias allows documents to be stored in the local file system instead of the document_root location. URLs with a path beginning with url-path is mapped to local files beginning with directory-filename, for example:

{alias, {"/image", "/ftp/pub/image"}}

Access to http://your.server.org/image/foo.gif would refer to the file /ftp/pub/image/foo.gif.

{re_write, {Re, Replacement}}
Re = string() and Replacement = string(). re_write allows documents to be stored in the local file system instead of the document_root location. URLs are rewritten by re:replace/3 to produce a path in the local file-system, for example:

{re_write, {"^/[~]([^/]+)(.*)$", "/home/\\1/public\\2"}}

Access to http://your.server.org/~bob/foo.gif would refer to the file /home/bob/public/foo.gif.

{directory_index, [string()]}
directory_index specifies a list of resources to look for if a client requests a directory using a / at the end of the directory name. file depicts the name of a file in the directory. Several files can be given, in which case the server returns the first it finds, for example:

{directory_index, ["index.html", "welcome.html"]}

Access to http://your.server.org/docs/ would return http://your.server.org/docs/index.html or http://your.server.org/docs/welcome.html if index.html does not exist.

CGI Properties - Requires mod_cgi

Note

mod_cgi and mod_actions are deprecated since OTP 29 and will be removed in OTP 30. Use mod_esi instead for dynamic page generation.

{script_alias, {Alias, RealName}}
Alias = string() and RealName = string(). Have the same behavior as property alias, except that they also mark the target directory as containing CGI scripts. URLs with a path beginning with url-path are mapped to scripts beginning with directory-filename, for example:

{script_alias, {"/cgi-bin/", "/web/cgi-bin/"}}

Access to http://your.server.org/cgi-bin/foo would cause the server to run the script /web/cgi-bin/foo.

Note

When using script_alias with directory-based authentication (see directory), ensure that authentication rules reference the actual filesystem path (RealName), not the URL path (Alias). The server correctly resolves script_alias paths for authentication checks.

{script_re_write, {Re, Replacement}}
Re = string() and Replacement = string(). Have the same behavior as property re_write, except that they also mark the target directory as containing CGI scripts. URLs with a path beginning with url-path are mapped to scripts beginning with directory-filename, for example:

{script_re_write, {"^/cgi-bin/(\\d+)/", "/web/\\1/cgi-bin/"}}

Access to http://your.server.org/cgi-bin/17/foo would cause the server to run the script /web/17/cgi-bin/foo.

{script_nocache, boolean()}
If script_nocache is set to true, the HTTP server by default adds the header fields necessary to prevent proxies from caching the page. Generally this is preferred. Default to false.

{script_timeout, integer()}
The time in seconds the web server waits between each chunk of data from the script. If the CGI script does not deliver any data before the timeout, the connection to the client is closed. Default is 15.

{action, {MimeType, CgiScript}} - requires mod_actions
MimeType = string() and CgiScript = string(). action adds an action activating a CGI script whenever a file of a certain MIME type is requested. It propagates the URL and file path of the requested document using the standard CGI PATH_INFO and PATH_TRANSLATED environment variables.

Example:

{action, {"text/plain", "/cgi-bin/log_and_deliver_text"}}

Note

mod_cgi and mod_actions are deprecated since OTP 29 and will be removed in OTP 30. Use mod_esi instead for dynamic page generation.

{script, {Method, CgiScript}} - requires mod_actions
Method = string() and CgiScript = string(). script adds an action activating a CGI script whenever a file is requested using a certain HTTP method. The method is either GET or POST, as defined in RFC 1945. It propagates the URL and file path of the requested document using the standard CGI PATH_INFO and PATH_TRANSLATED environment variables.

Example:

{script, {"PUT", "/cgi-bin/put"}}

Note

mod_cgi and mod_actions are deprecated since OTP 29 and will be removed in OTP 30. Use mod_esi instead for dynamic page generation.

ESI Properties - Requires mod_esi

{erl_script_alias, {URLPath, [AllowedModule]}}
URLPath = string() and AllowedModule = atom(). erl_script_alias marks all URLs matching url-path as erl scheme scripts. A matching URL is mapped into a specific module and function, for example:

{erl_script_alias, {"/cgi-bin/example", [httpd_example]}}

A request to http://your.server.org/cgi-bin/example/httpd_example:yahoo would refer to httpd_example:yahoo/3 or, if that does not exist, httpd_example:yahoo/2 and http://your.server.org/cgi-bin/example/other:yahoo would not be allowed to execute.

{erl_script_nocache, boolean()}
If erl_script_nocache is set to true, the server adds HTTP header fields preventing proxies from caching the page. This is generally a good idea for dynamic content, as the content often varies between each request. Default is false.

{erl_script_timeout, integer()}
If erl_script_timeout sets the time in seconds the server waits between each chunk of data to be delivered through mod_esi:deliver/2. Default is 15. This is only relevant for scripts that use the erl scheme.

Log Properties - Requires mod_log

{error_log, path()}
Defines the filename of the error log file to be used to log server errors. If the filename does not begin with a slash (/), it is assumed to be relative to the server_root.

{security_log, path()}
Defines the filename of the access log file to be used to log security events. If the filename does not begin with a slash (/), it is assumed to be relative to the server_root.

{transfer_log, path()}
Defines the filename of the access log file to be used to log incoming requests. If the filename does not begin with a slash (/), it is assumed to be relative to the server_root.

Disk Log Properties - Requires mod_disk_log

{disk_log_format, internal | external}
Defines the file format of the log files. See disk_log for details. If the internal file format is used, the log file is repaired after a crash. When a log file is repaired, data can disappear. When the external file format is used, httpd does not start if the log file is broken. Default is external.

{error_disk_log, path()}
Defines the filename of the (disk_log) error log file to be used to log server errors. If the filename does not begin with a slash (/), it is assumed to be relative to the server_root.

{error_disk_log_size, {MaxBytes, MaxFiles}}
MaxBytes = integer() and MaxFiles = integer(). Defines the properties of the (disk_log) error log file. This file is of type wrap log and max bytes is written to each file and max files is used before the first file is truncated and reused.

{security_disk_log, path()}
Defines the filename of the (disk_log) access log file logging incoming security events, that is, authenticated requests. If the filename does not begin with a slash (/), it is assumed to be relative to the server_root.

{security_disk_log_size, {MaxBytes, MaxFiles}}
MaxBytes = integer() and MaxFiles = integer(). Defines the properties of the disk_log access log file. This file is of type wrap log and max bytes is written to each file and max files is used before the first file is truncated and reused.

{transfer_disk_log, path()}
Defines the filename of the (disk_log) access log file logging incoming requests. If the filename does not begin with a slash (/), it is assumed to be relative to the server_root.

{transfer_disk_log_size, {MaxBytes, MaxFiles}}
MaxBytes = integer() and MaxFiles = integer(). Defines the properties of the disk_log access log file. This file is of type wrap log and max bytes is written to each file and max files is used before the first file is truncated and reused.

Authentication Properties - Requires mod_auth

{directory, {path(), [{property(), term()}]}}

The properties for directories are as follows:

{allow_from, all | [RegxpHostString]}
Defines a set of hosts to be granted access to a given directory, for example:

{allow_from, ["123.34.56.11", "150.100.23"]}

The host 123.34.56.11 and all machines on the 150.100.23 subnet are allowed access.

{deny_from, all | [RegxpHostString]}
Defines a set of hosts to be denied access to a given directory, for example:

{deny_from, ["123.34.56.11", "150.100.23"]}

The host 123.34.56.11 and all machines on the 150.100.23 subnet are not allowed access.

{auth_type, plain | dets | mnesia}
Sets the type of authentication database that is used for the directory. The key difference between the different methods is that dynamic data can be saved when Mnesia and Dets are used.

{auth_user_file, path()}
Sets the name of a file containing the list of users and passwords for user authentication. The filename can be either absolute or relative to the server_root. If using the plain storage method, this file is a plain text file where each line contains a username followed by a colon, followed by the non-encrypted password. If usernames are duplicated, the behavior is undefined.

Example:

ragnar:s7Xxv7
edward:wwjau8

If the Dets storage method is used, the user database is maintained by Dets and must not be edited by hand. Use the API functions in module mod_auth to create/edit the user database. This directive is ignored if the Mnesia storage method is used. For security reasons, ensure that auth_user_file is stored outside the document tree of the web server. If it is placed in the directory that it protects, clients can download it.

{auth_group_file, path()}
Sets the name of a file containing the list of user groups for user authentication. The filename can be either absolute or relative to the server_root. If the plain storage method is used, the group file is a plain text file, where each line contains a group name followed by a colon, followed by the members usernames separated by spaces.

Example:

group1: bob joe ante

If the Dets storage method is used, the group database is maintained by Dets and must not be edited by hand. Use the API for module mod_auth to create/edit the group database. This directive is ignored if the Mnesia storage method is used. For security reasons, ensure that the auth_group_file is stored outside the document tree of the web server. If it is placed in the directory that it protects, clients can download it.

{auth_name, string()}
Sets the name of the authorization realm (auth-domain) for a directory. This string informs the client about which username and password to use.

{auth_access_password, string()}
If set to other than "NoPassword", the password is required for all API calls. If the password is set to "DummyPassword", the password must be changed before any other API calls. To secure the authenticating data, the password must be changed after the web server is started. Otherwise it is written in clear text in the configuration file.

{require_user, [string()]}
Defines users to grant access to a given directory using a secret password.

{require_group, [string()]}
Defines users to grant access to a given directory using a secret password.

Security Properties - Requires mod_security

{security_directory, {path(), [{property(), term()}]}}

The properties for the security directories are as follows:

{data_file, path()}
Name of the security data file. The filename can either be absolute or relative to the server_root. This file is used to store persistent data for module mod_security.

{max_retries, integer()}
Specifies the maximum number of attempts to authenticate a user before the user is blocked out. If a user successfully authenticates while blocked, the user receives a 403 (Forbidden) response from the server. If the user makes a failed attempt while blocked, the server returns 401 (Unauthorized), for security reasons. Default is 3. Can be set to infinity.

{block_time, integer()}
Specifies the number of minutes a user is blocked. After this time has passed, the user automatically regains access. Default is 60.

{fail_expire_time, integer()}
Specifies the number of minutes a failed user authentication is remembered. If a user authenticates after this time has passed, the previous failed authentications are forgotten. Default is 30.

{auth_timeout, integer()}
Specifies the number of seconds a successful user authentication is remembered. After this time has passed, the authentication is no longer reported. Default is 30.

Web server API data types

The Erlang web server API data types are as follows:

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
}).

To access the record in your callback-module use:

-include_lib("inets/include/httpd.hrl").

The fields of record mod have 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 an IP socket or an ssl socket.

socket - The socket, in format ip_comm or ssl, depending on 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 method.

absolute_uri - If the request is an HTTP/1.1 request, the URI can be in the absolute URI format. In that case, httpd saves the absolute URI in this field. An Example of an absolute URI is "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/1.0", or "HTTP/1.1".

request_line - The Request-Line as defined inRFC 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 is 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 can be in lower case or upper case. httpd ensures that all header field names are in lower 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 connection and is not closed when the request is served.

See also

RFC 2616, inets, ssl

Summary

Types

property()

socket_type()

Callbacks: ERLANG WEB SERVER API CALLBACK FUNCTIONS

do(ModData)

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

remove(ConfigDB)

When httpd is shut down, it tries to execute remove/1 in each Erlang web server callback module. The programmer can use this function to clean up resources created in the store function.

store/2

Checks the validity of the configuration options before saving them in the internal database. This function can also have a side effect, that is, setup of necessary extra resources implied by the configuration option. It can also resolve possible dependencies among configuration options by changing the value of the option. This function only needs clauses for the options implemented by this particular callback module.

Web server API help functions

parse_query(QueryString) deprecated

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

Functions

info(Pid)

Equivalent to info/2.

info/2

Fetches information about the HTTP server. When called with only the pid, all properties are fetched. When called with a list of specific properties, they are fetched. The available properties are the same as the start options of the server.

info/3

Equivalent to info/4.

info(Address, Port, Profile, Properties)

Fetches information about the HTTP server. When called with only Address and Port, all properties are fetched. When called with a list of specific properties, they are fetched. The available properties are the same as the start options of the server.

reload_config(Config, Mode)

Reloads the HTTP server configuration without restarting the server. Incoming requests are answered with a temporary down message during the reload time.

Types

property()

(not exported)

-type property() :: atom().

socket_type()

-type socket_type() :: ip_comm | ssl.

Callbacks: ERLANG WEB SERVER API CALLBACK FUNCTIONS

do(ModData)

-callback do(ModData) -> {proceed, OldData} | {proceed, NewData} | {break, NewData} | done
                when
                    ModData :: [{data, NewData} | {'Body', Body} | {'Head', Head}],
                    OldData :: list(),
                    NewData :: [{response, NewDataCompatFormat}] | [{response, NewDataFormat}],
                    NewDataCompatFormat :: {StatusCode, Body},
                    NewDataFormat :: {response, Head, Body} | {already_sent, StatusCode, Size},
                    StatusCode :: integer(),
                    Size :: non_neg_integer(),
                    Body :: iolist() | nobody | {Fun, FunArg},
                    Head :: [HeaderOption] | {Key, Value},
                    HeaderOption :: {Option, Value} | {code, StatusCode},
                    Option :: accept_ranges | allow,
                    Key :: atom() | string(),
                    Value :: string(),
                    FunArg :: [term()],
                    Fun :: fun((FunArg) -> sent | close | Body).

When a valid request reaches httpd, it calls do/1 in each module, defined by the configuration option of Module. The function can 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 is the list returned from the last call to do/1.

Body is the body of the HTTP response that is sent back to the client. An appropriate header is appended to the message. StatusCode is the status code of the response, see RFC 2616 for the appropriate values.

Head is a key value list of HTTP header fields. The server constructs an HTTP header from this data. See RFC 2616 for the appropriate value for each header field. If the client is an HTTP/1.0 client, the server filters the list so that only HTTP/1.0 header fields are sent back to the client.

If Body is returned and equal to {Fun,Arg}, the web server tries apply/2 on Fun with Arg as argument. The web server expects that the fun either returns a list (Body) that is an HTTP response, 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 signals this to the client by closing the connection.

Note

It is strongly advised to use NewDataFormat in the return value of do/1 as it relies on a newer mechanism for parsing and sending headers, provides more accurate status codes, and supports a wider range of Body formats.

remove(ConfigDB)

(optional)

-callback remove(ConfigDB) -> ok | {error, Reason} when ConfigDB :: ets:tid(), Reason :: term().

When httpd is shut down, it tries to execute remove/1 in each Erlang web server callback module. The programmer can use this function to clean up resources created in the store function.

store/2

(optional)

-callback store({Option, Value}, Config) -> {ok, {Option, NewValue}} | {error, Reason}
                   when
                       Option :: property(),
                       Config :: [{Option, Value}],
                       Value :: term(),
                       NewValue :: term(),
                       Reason :: term().

Checks the validity of the configuration options before saving them in the internal database. This function can also have a side effect, that is, setup of necessary extra resources implied by the configuration option. It can also resolve possible dependencies among configuration options by changing the value of the option. This function only needs clauses for the options implemented by this particular callback module.

Web server API help functions

parse_query(QueryString)

This function is deprecated. httpd:parse_query/1 is deprecated; use uri_string:dissect_query/1 instead.

-spec parse_query(QueryString) -> QueryList | uri_string:error()
                     when
                         QueryString :: string(),
                         QueryList :: [{unicode:chardata(), unicode:chardata() | true}].

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

Functions

info(Pid)

-spec info(Pid) -> HttpInformation
              when
                  Pid :: pid(),
                  Path :: file:name_all(),
                  HttpInformation ::
                      [CommonOption] |
                      [CommunicationOption] |
                      [ModOption] |
                      [LimitOption] |
                      [AdminOption],
                  CommonOption ::
                      {port, non_neg_integer()} |
                      {server_name, string()} |
                      {server_root, Path} |
                      {document_root, Path},
                  CommunicationOption ::
                      {bind_address, inet:ip_address() | inet:hostname() | any} |
                      {profile, atom()} |
                      {socket_type,
                       ip_comm |
                       {ip_comm, ssl:tls_option() | gen_tcp:option()} |
                       {ssl, ssl:tls_option() | gen_tcp:option()}} |
                      {ipfamily, inet | inet6} |
                      {minimum_bytes_per_second, integer()},
                  ModOption :: {modules, atom()},
                  LimitOption ::
                      {customize, atom()} |
                      {disable_chunked_transfer_encoding_send, boolean()} |
                      {keep_alive, boolean()} |
                      {keep_alive_timeout, integer()} |
                      {max_body_size, integer()} |
                      {max_clients, integer()} |
                      {max_header_size, integer()} |
                      {max_content_length, integer()} |
                      {max_uri_size, integer()} |
                      {max_keep_alive_request, integer()} |
                      {max_client_body_chunk, integer()},
                  AdminOption ::
                      {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} |
                      {mime_type, string()} |
                      {server_admin, string()} |
                      {server_tokens,
                       none | prod | major | minor | minimal | os | full | {private, string()}} |
                      {logger, Options :: list()} |
                      {log_format, common | combined} |
                      {error_log_format, pretty | compact}.

Equivalent to info/2.

info/2

-spec info(Pid, Properties) -> HttpInformation
              when
                  Pid :: pid(),
                  Properties :: [atom()],
                  HttpInformation ::
                      [CommonOption] |
                      [CommunicationOption] |
                      [ModOption] |
                      [LimitOption] |
                      [AdminOption],
                  CommonOption ::
                      {port, non_neg_integer()} |
                      {server_name, string()} |
                      {server_root, Path} |
                      {document_root, Path},
                  CommunicationOption ::
                      {bind_address, inet:ip_address() | inet:hostname() | any} |
                      {profile, atom()} |
                      {socket_type,
                       ip_comm |
                       {ip_comm, ssl:tls_option() | gen_tcp:option()} |
                       {ssl, ssl:tls_option() | gen_tcp:option()}} |
                      {ipfamily, inet | inet6} |
                      {minimum_bytes_per_second, integer()},
                  ModOption :: {modules, atom()},
                  LimitOption ::
                      {customize, atom()} |
                      {disable_chunked_transfer_encoding_send, boolean()} |
                      {keep_alive, boolean()} |
                      {keep_alive_timeout, integer()} |
                      {max_body_size, integer()} |
                      {max_clients, integer()} |
                      {max_header_size, integer()} |
                      {max_content_length, integer()} |
                      {max_uri_size, integer()} |
                      {max_keep_alive_request, integer()} |
                      {max_client_body_chunk, integer()},
                  AdminOption ::
                      {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} |
                      {mime_type, string()} |
                      {server_admin, string()} |
                      {server_tokens,
                       none | prod | major | minor | minimal | os | full | {private, string()}} |
                      {logger, Options :: list()} |
                      {log_format, common | combined} |
                      {error_log_format, pretty | compact};
          (Address, Port) -> HttpInformation
              when
                  Address :: inet:ip_address(),
                  Port :: integer(),
                  Path :: file:name_all(),
                  HttpInformation ::
                      [CommonOption] |
                      [CommunicationOption] |
                      [ModOption] |
                      [LimitOption] |
                      [AdminOption],
                  CommonOption ::
                      {port, non_neg_integer()} |
                      {server_name, string()} |
                      {server_root, Path} |
                      {document_root, Path},
                  CommunicationOption ::
                      {bind_address, inet:ip_address() | inet:hostname() | any} |
                      {profile, atom()} |
                      {socket_type,
                       ip_comm |
                       {ip_comm, ssl:tls_option() | gen_tcp:option()} |
                       {ssl, ssl:tls_option() | gen_tcp:option()}} |
                      {ipfamily, inet | inet6} |
                      {minimum_bytes_per_second, integer()},
                  ModOption :: {modules, atom()},
                  LimitOption ::
                      {customize, atom()} |
                      {disable_chunked_transfer_encoding_send, boolean()} |
                      {keep_alive, boolean()} |
                      {keep_alive_timeout, integer()} |
                      {max_body_size, integer()} |
                      {max_clients, integer()} |
                      {max_header_size, integer()} |
                      {max_content_length, integer()} |
                      {max_uri_size, integer()} |
                      {max_keep_alive_request, integer()} |
                      {max_client_body_chunk, integer()},
                  AdminOption ::
                      {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} |
                      {mime_type, string()} |
                      {server_admin, string()} |
                      {server_tokens,
                       none | prod | major | minor | minimal | os | full | {private, string()}} |
                      {logger, Options :: list()} |
                      {log_format, common | combined} |
                      {error_log_format, pretty | compact}.

Fetches information about the HTTP server. When called with only the pid, all properties are fetched. When called with a list of specific properties, they are fetched. The available properties are the same as the start options of the server.

Note

Pid is the pid returned from inets:start/[2,3]. Can also be retrieved form inets:services/0 and inets:services_info/0, see inets.

info/3

-spec info(Address, Port, Profile) -> HttpInformation
              when
                  Address :: inet:ip_address() | any,
                  Port :: integer(),
                  Profile :: atom(),
                  Path :: file:name_all(),
                  HttpInformation ::
                      [CommonOption] |
                      [CommunicationOption] |
                      [ModOption] |
                      [LimitOption] |
                      [AdminOption],
                  CommonOption ::
                      {port, non_neg_integer()} |
                      {server_name, string()} |
                      {server_root, Path} |
                      {document_root, Path},
                  CommunicationOption ::
                      {bind_address, inet:ip_address() | inet:hostname() | any} |
                      {profile, atom()} |
                      {socket_type,
                       ip_comm |
                       {ip_comm, ssl:tls_option() | gen_tcp:option()} |
                       {ssl, ssl:tls_option() | gen_tcp:option()}} |
                      {ipfamily, inet | inet6} |
                      {minimum_bytes_per_second, integer()},
                  ModOption :: {modules, atom()},
                  LimitOption ::
                      {customize, atom()} |
                      {disable_chunked_transfer_encoding_send, boolean()} |
                      {keep_alive, boolean()} |
                      {keep_alive_timeout, integer()} |
                      {max_body_size, integer()} |
                      {max_clients, integer()} |
                      {max_header_size, integer()} |
                      {max_content_length, integer()} |
                      {max_uri_size, integer()} |
                      {max_keep_alive_request, integer()} |
                      {max_client_body_chunk, integer()},
                  AdminOption ::
                      {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} |
                      {mime_type, string()} |
                      {server_admin, string()} |
                      {server_tokens,
                       none | prod | major | minor | minimal | os | full | {private, string()}} |
                      {logger, Options :: list()} |
                      {log_format, common | combined} |
                      {error_log_format, pretty | compact};
          (Address, Port, Properties) -> HttpInformation
              when
                  Address :: inet:ip_address() | any,
                  Port :: integer(),
                  Properties :: [atom()],
                  Path :: file:name_all(),
                  HttpInformation ::
                      [CommonOption] |
                      [CommunicationOption] |
                      [ModOption] |
                      [LimitOption] |
                      [AdminOption],
                  CommonOption ::
                      {port, non_neg_integer()} |
                      {server_name, string()} |
                      {server_root, Path} |
                      {document_root, Path},
                  CommunicationOption ::
                      {bind_address, inet:ip_address() | inet:hostname() | any} |
                      {profile, atom()} |
                      {socket_type,
                       ip_comm |
                       {ip_comm, ssl:tls_option() | gen_tcp:option()} |
                       {ssl, ssl:tls_option() | gen_tcp:option()}} |
                      {ipfamily, inet | inet6} |
                      {minimum_bytes_per_second, integer()},
                  ModOption :: {modules, atom()},
                  LimitOption ::
                      {customize, atom()} |
                      {disable_chunked_transfer_encoding_send, boolean()} |
                      {keep_alive, boolean()} |
                      {keep_alive_timeout, integer()} |
                      {max_body_size, integer()} |
                      {max_clients, integer()} |
                      {max_header_size, integer()} |
                      {max_content_length, integer()} |
                      {max_uri_size, integer()} |
                      {max_keep_alive_request, integer()} |
                      {max_client_body_chunk, integer()},
                  AdminOption ::
                      {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} |
                      {mime_type, string()} |
                      {server_admin, string()} |
                      {server_tokens,
                       none | prod | major | minor | minimal | os | full | {private, string()}} |
                      {logger, Options :: list()} |
                      {log_format, common | combined} |
                      {error_log_format, pretty | compact}.

Equivalent to info/4.

info(Address, Port, Profile, Properties)

(since OTP 18.0)

-spec info(Address, Port, Profile, Properties) -> HttpInformation
              when
                  Address :: inet:ip_address() | any,
                  Port :: integer(),
                  Profile :: atom(),
                  Properties :: [atom()],
                  Path :: file:name_all(),
                  HttpInformation ::
                      [CommonOption] |
                      [CommunicationOption] |
                      [ModOption] |
                      [LimitOption] |
                      [AdminOption],
                  CommonOption ::
                      {port, non_neg_integer()} |
                      {server_name, string()} |
                      {server_root, Path} |
                      {document_root, Path},
                  CommunicationOption ::
                      {bind_address, inet:ip_address() | inet:hostname() | any} |
                      {profile, atom()} |
                      {socket_type,
                       ip_comm |
                       {ip_comm, ssl:tls_option() | gen_tcp:option()} |
                       {ssl, ssl:tls_option() | gen_tcp:option()}} |
                      {ipfamily, inet | inet6} |
                      {minimum_bytes_per_second, integer()},
                  ModOption :: {modules, atom()},
                  LimitOption ::
                      {customize, atom()} |
                      {disable_chunked_transfer_encoding_send, boolean()} |
                      {keep_alive, boolean()} |
                      {keep_alive_timeout, integer()} |
                      {max_body_size, integer()} |
                      {max_clients, integer()} |
                      {max_header_size, integer()} |
                      {max_content_length, integer()} |
                      {max_uri_size, integer()} |
                      {max_keep_alive_request, integer()} |
                      {max_client_body_chunk, integer()},
                  AdminOption ::
                      {mime_types, [{MimeType :: string(), Extension :: string()}] | Path} |
                      {mime_type, string()} |
                      {server_admin, string()} |
                      {server_tokens,
                       none | prod | major | minor | minimal | os | full | {private, string()}} |
                      {logger, Options :: list()} |
                      {log_format, common | combined} |
                      {error_log_format, pretty | compact}.

Fetches information about the HTTP server. When called with only Address and Port, all properties are fetched. When called with a list of specific properties, they are fetched. The available properties are the same as the start options of the server.

Note

The Address must be the IP address and cannot be the hostname.

reload_config(Config, Mode)

-spec reload_config(Config, Mode) -> ok | {error, Reason} | no_return()
                       when
                           Config :: file:name_all() | [{Option, Value}],
                           Mode :: non_disturbing | disturbing | blocked,
                           Option :: atom(),
                           Value :: term(),
                           Reason :: term().

Reloads the HTTP server configuration without restarting the server. Incoming requests are answered with a temporary down message during the reload time.

Note

Available properties are the same as the start options of the server, but the properties bind_address and port cannot be changed.

If mode is disturbing, the server is blocked forcefully, all ongoing requests terminates, and the reload starts immediately. If mode is non-disturbing, no new connections are accepted, but ongoing requests are allowed to complete before the reload is done.

httpd_custom_api behaviour

Behaviour with optional callbacks to customize the inets HTTP server.

The module implementing this behaviour shall be supplied to to the servers configuration with the option customize

Summary

Callbacks

request_header/1

Filter and possible alter HTTP request headers before they are processed by the server.

response_default_headers()

Provide default headers for the HTTP servers responses. Note that this option may override built-in defaults.

response_header/1

Filter and possible alter HTTP response headers before they are sent to the client.

Callbacks

request_header/1

(since OTP 17.5.6) (optional)

-callback request_header({Key :: string(), Value :: string()}) ->
                            {true, {Key :: string(), Value :: string()}} | false.

Filter and possible alter HTTP request headers before they are processed by the server.

response_default_headers()

(since OTP 18.1.1) (optional)

-callback response_default_headers() -> [{Key :: string(), Value :: string()}].

Provide default headers for the HTTP servers responses. Note that this option may override built-in defaults.

response_header/1

(since OTP 17.5.6) (optional)

-callback response_header({Key :: string(), Value :: string()}) ->
                             {true, {Key :: string(), Value :: string()}} | false | {true, string()}.

Filter and possible alter HTTP response headers before they are sent to the client.

httpd_socket

Communication utility functions to be used by the Erlang web server API programmer.

This module provides the Erlang web server API module programmer with utility functions for generic sockets communication. The appropriate communication mechanism is transparently used, that is, ip_comm or ssl.

See also

httpd

Summary

Functions

deliver(SocketType, Socket, Data)

deliver/3 sends Data over Socket using the specified SocketType. Socket and SocketType is to be the socket and the socket_type form the mod record as defined in httpd.hrl

peername(SocketType, Socket)

peername/2 returns the Port and IPAddress of the remote Socket.

resolve()

resolve/0 returns the official HostName of the current host.

Functions

deliver(SocketType, Socket, Data)

-spec deliver(SocketType, Socket, Data) -> Result
                 when
                     SocketType :: httpd:socket_type(),
                     Socket :: inet:socket(),
                     Data :: iolist() | binary(),
                     Result :: ok | socket_closed.

deliver/3 sends Data over Socket using the specified SocketType. Socket and SocketType is to be the socket and the socket_type form the mod record as defined in httpd.hrl

peername(SocketType, Socket)

-spec peername(SocketType, Socket) -> {Port, IpAdress}
                  when
                      SocketType :: httpd:socket_type(),
                      Socket :: inet:socket() | ssl:sslsocket(),
                      Port :: inet:port_number(),
                      IpAdress :: inet:ip4_address() | inet:ip6_address() | string().

peername/2 returns the Port and IPAddress of the remote Socket.

resolve()

-spec resolve() -> HostName when HostName :: inet:hostname().

resolve/0 returns the official HostName of the current host.

httpd_util

Miscellaneous utility functions to be used when implementing Erlang web server API modules.

This module provides the Erlang web server API module programmer with miscellaneous utility functions.

Note

Note the module is only recommended for using with httpd - for other cases it should be considered as deprecated.

See also

httpd

Summary

Functions

convert_request_date(DateString)

convert_request_date/1 converts DateString to the Erlang date format. DateString must be in one of the three date formats defined in RFC 2616.

create_etag(FileInfo)

create_etag/1 calculates the Etag for a file from its size and time for last modification. FileInfo is a record defined in kernel/include/file.hrl.

day(NthDayOfWeek)

day/1 converts the day of the week (NthDayOfWeek) from an integer (1-7) to an abbreviated string, that is

lookup(EtsTable, Key)

Equivalent to lookup/3.

lookup(EtsTable, Key, Undefined)

lookup extracts {Key, Value} tuples from ETSTable and returns the Value associated with Key. If ETSTable is of type bag, only the first Value associated with Key is returned. lookup/2 returns undefined and lookup/3 returns Undefined if no Value is found.

lookup_mime(ConfigDB, Suffix)

Equivalent to lookup_mime/3.

lookup_mime(ConfigDB, Suffix, Undefined)

lookup_mime returns the MIME type associated with a specific file suffix as specified in the file mime.types (located in the config directory).

lookup_mime_default(ConfigDB, Suffix)

Equivalent to lookup_mime_default/3.

lookup_mime_default(ConfigDB, Suffix, Undefined)

lookup_mime_default returns the MIME type associated with a specific file suffix as specified in the mime.types file (located in the config directory). If no appropriate association is found, the value of DefaultType is returned.

message(StatusCode, PhraseArgs, ConfigDB)

message/3 returns an informative HTTP 1.1 status string in HTML. Each StatusCode requires a specific PhraseArgs

month(NthMonth)

month/1 converts the month NthMonth as an integer (1-12) to an abbreviated string, that is

multi_lookup(EtsTable, Key)

multi_lookup extracts all {Key, Value} tuples from an ETSTable and returns all Values associated with Key in a list.

reason_phrase(StatusCode)

reason_phrase returns Description of an HTTP 1.1 StatusCode, for example, 200 is "OK" and 201 is "Created". For more information, see RFC 2616.

rfc1123_date()

Equivalent to rfc1123_date/1.

rfc1123_date(LocalTime)

rfc1123_date/0 returns the current date in RFC 1123 format. rfc_date/1 converts the date in the Erlang format to the RFC 1123 date format.

split(String, RegExp, N)

split/3 splits String in N chunks using RegExp. split/3 is equivalent to re:split/3 with the exception that N defines the maximum number of fields in FieldList.

split_path(URIString)

split_path/1 splits RequestLine in a file reference (Path), and a QueryString or a PathInfo string as specified in RFC 2616. A QueryString is isolated from Path with a question mark (?) and PathInfo with a slash (/). In the case of a QueryString, everything before ? is a Path and everything after ? is a QueryString. In the case of a PathInfo, RequestLine is scanned from left-to-right on the hunt for longest possible Path being a file or a directory. Everything after the longest possible Path, isolated with a /, is regarded as PathInfo

split_script_path(URIString)

split_script_path/1 is equivalent to split_path/1 with one exception. If the longest possible path is not a regular, accessible, and executable file, then not_a_script is returned.

Functions

convert_request_date(DateString)

-spec convert_request_date(DateString) -> ErlDate | bad_date
                              when DateString :: string(), ErlDate :: calendar:datetime().

convert_request_date/1 converts DateString to the Erlang date format. DateString must be in one of the three date formats defined in RFC 2616.

create_etag(FileInfo)

-spec create_etag(FileInfo) -> Etag when FileInfo :: file:file_info(), Etag :: string().

create_etag/1 calculates the Etag for a file from its size and time for last modification. FileInfo is a record defined in kernel/include/file.hrl.

day(NthDayOfWeek)

-spec day(NthDayOfWeek) -> DayOfWeek when NthDayOfWeek :: 1..7, DayOfWeek :: string().

day/1 converts the day of the week (NthDayOfWeek) from an integer (1-7) to an abbreviated string, that is:

1 = "Mon", 2 = "Tue", ..., 7 = "Sat".

lookup(EtsTable, Key)

-spec lookup(EtsTable, Key) -> Result
                when EtsTable :: ets:table(), Key :: term(), Result :: term() | undefined.

Equivalent to lookup/3.

lookup(EtsTable, Key, Undefined)

-spec lookup(EtsTable, Key, Undefined) -> Result
                when
                    EtsTable :: ets:table(),
                    Key :: term(),
                    Undefined :: term(),
                    Result :: term() | Undefined.

lookup extracts {Key, Value} tuples from ETSTable and returns the Value associated with Key. If ETSTable is of type bag, only the first Value associated with Key is returned. lookup/2 returns undefined and lookup/3 returns Undefined if no Value is found.

lookup_mime(ConfigDB, Suffix)

-spec lookup_mime(ConfigDB, Suffix) -> MimeType
                     when ConfigDB :: ets:tid(), Suffix :: string(), MimeType :: string() | undefined.

Equivalent to lookup_mime/3.

lookup_mime(ConfigDB, Suffix, Undefined)

-spec lookup_mime(ConfigDB, Suffix, Undefined) -> MimeType
                     when
                         ConfigDB :: ets:tid(),
                         Suffix :: string(),
                         Undefined :: term(),
                         MimeType :: string() | Undefined.

lookup_mime returns the MIME type associated with a specific file suffix as specified in the file mime.types (located in the config directory).

lookup_mime_default(ConfigDB, Suffix)

-spec lookup_mime_default(ConfigDB, Suffix) -> MimeType
                             when
                                 ConfigDB :: ets:tid(),
                                 Suffix :: string(),
                                 MimeType :: string() | undefined.

Equivalent to lookup_mime_default/3.

lookup_mime_default(ConfigDB, Suffix, Undefined)

-spec lookup_mime_default(ConfigDB, Suffix, Undefined) -> MimeType
                             when
                                 ConfigDB :: ets:tid(),
                                 Suffix :: string(),
                                 Undefined :: term(),
                                 MimeType :: string() | Undefined.

lookup_mime_default returns the MIME type associated with a specific file suffix as specified in the mime.types file (located in the config directory). If no appropriate association is found, the value of DefaultType is returned.

message(StatusCode, PhraseArgs, ConfigDB)

-spec message(StatusCode, PhraseArgs, ConfigDB) -> Message
                 when
                     StatusCode ::
                         301 | 304 | 400 | 401 | 403 | 404 | 408 | 412 | 413 | 414 | 500 | 501 | 503 |
                         504,
                     PhraseArgs :: term(),
                     ConfigDB :: ets:tid(),
                     Message :: string().

message/3 returns an informative HTTP 1.1 status string in HTML. Each StatusCode requires a specific PhraseArgs:

301 - string/0: A URL pointing at the new document position.

400 | 401 | 500 - none (no PhraseArgs).

403 | 404 - string/0: A Request-URI as described in RFC 2616.

501 - {Method, RequestURI, HTTPVersion}: The HTTP Method, Request-URI, and HTTP-Version as defined in RFC 2616.

504 - string/0: A string describing why the service was unavailable.

month(NthMonth)

-spec month(NthMonth) -> Month when NthMonth :: 1..12, Month :: string().

month/1 converts the month NthMonth as an integer (1-12) to an abbreviated string, that is:

1 = "Jan", 2 = "Feb", ..., 12 = "Dec".

multi_lookup(EtsTable, Key)

-spec multi_lookup(EtsTable, Key) -> Result
                      when EtsTable :: ets:tid(), Key :: term(), Result :: list() | [term()].

multi_lookup extracts all {Key, Value} tuples from an ETSTable and returns all Values associated with Key in a list.

reason_phrase(StatusCode)

-spec reason_phrase(StatusCode) -> Description
                       when
                           StatusCode ::
                               100 | 101 | 102 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 226 |
                               300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 400 | 401 | 402 |
                               403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 |
                               415 | 416 | 417 | 422 | 423 | 424 | 425 | 426 | 500 | 501 | 502 | 503 |
                               504 | 505 | 507,
                           Description :: string().

reason_phrase returns Description of an HTTP 1.1 StatusCode, for example, 200 is "OK" and 201 is "Created". For more information, see RFC 2616.

rfc1123_date()

-spec rfc1123_date() -> RFC1123Date when RFC1123Date :: string().

Equivalent to rfc1123_date/1.

rfc1123_date(LocalTime)

-spec rfc1123_date(LocalTime) -> RFC1123Date
                      when
                          LocalTime :: calendar:datetime() | undefined,
                          RFC1123Date :: string() | undefined.

rfc1123_date/0 returns the current date in RFC 1123 format. rfc_date/1 converts the date in the Erlang format to the RFC 1123 date format.

split(String, RegExp, N)

-spec split(String, RegExp, N) -> SplitRes
               when
                   String :: string(),
                   RegExp :: string(),
                   N :: non_neg_integer(),
                   SplitRes :: {ok, FieldList} | {error, term()},
                   FieldList :: [string()].

split/3 splits String in N chunks using RegExp. split/3 is equivalent to re:split/3 with the exception that N defines the maximum number of fields in FieldList.

split_path(URIString)

-spec split_path(URIString) -> {Path, QueryStringOrPathInfo}
                    when URIString :: string(), Path :: string(), QueryStringOrPathInfo :: string().

split_path/1 splits RequestLine in a file reference (Path), and a QueryString or a PathInfo string as specified in RFC 2616. A QueryString is isolated from Path with a question mark (?) and PathInfo with a slash (/). In the case of a QueryString, everything before ? is a Path and everything after ? is a QueryString. In the case of a PathInfo, RequestLine is scanned from left-to-right on the hunt for longest possible Path being a file or a directory. Everything after the longest possible Path, isolated with a /, is regarded as PathInfo

split_script_path(URIString)

-spec split_script_path(URIString) -> Split
                           when
                               URIString :: string(),
                               Split :: not_a_script | {Path, {PathInfo, QueryString}} | {Path, []},
                               Path :: string(),
                               QueryString :: string(),
                               PathInfo :: string().

split_script_path/1 is equivalent to split_path/1 with one exception. If the longest possible path is not a regular, accessible, and executable file, then not_a_script is returned.

mod_alias

URL aliasing.

Erlang web server internal API for handling of, for example, interaction data exported by module mod_alias.

Summary

Functions

default_index(ConfigDB, Path)

If Path is a directory, default_index/2, it starts searching for resources or files that are specified in the config directive DirectoryIndex. If an appropriate resource or file is found, it is appended to the end of Path and then returned. Path is returned unaltered if no appropriate file is found or if Path is not a directory. config_db() is the server config file in ETS table format as described in Inets User's Guide.

path(Data, ConfigDB, RequestURI)

path/3 returns the file Path in the RequestURI (see RFC 1945). If the interaction data {real_name, {Path, AfterPath}} has been exported by mod_alias, Path is returned. If no interaction data has been exported, ServerRoot is used to generate a file Path. config_db() and interaction_data() are as defined in Inets User's Guide.

real_name(ConfigDB, RequestURI, Aliases)

real_name/3 traverses Aliases, typically extracted from ConfigDB, and matches each FakeName with RequestURI. If a match is found, FakeName is replaced with RealName in the match. The resulting path is split into two parts, ShortPath and AfterPath, as defined in httpd_util:split_path/1. Path is generated from ShortPath, that is, the result from default_index/2 with ShortPath as an argument. config_db() is the server config file in ETS table format as described in Inets User's Guide.

real_script_name(ConfigDB, RequestURI, ScriptAliases)

real_script_name/3 traverses ScriptAliases, typically extracted from ConfigDB, and matches each FakeName with RequestURI. If a match is found, FakeName is replaced with RealName in the match. If the resulting match is not an executable script, not_a_script is returned. If it is a script, the resulting script path is in two parts, ShortPath and AfterPath, as defined in httpd_util:split_script_path/1. config_db() is the server config file in ETS table format as described in Inets User's Guide.

Functions

default_index(ConfigDB, Path)

-spec default_index(ConfigDB, Path) -> NewPath
                       when ConfigDB :: ets:tid(), Path :: string(), NewPath :: string().

If Path is a directory, default_index/2, it starts searching for resources or files that are specified in the config directive DirectoryIndex. If an appropriate resource or file is found, it is appended to the end of Path and then returned. Path is returned unaltered if no appropriate file is found or if Path is not a directory. config_db() is the server config file in ETS table format as described in Inets User's Guide.

path(Data, ConfigDB, RequestURI)

-spec path(Data, ConfigDB, RequestURI) -> Path
              when
                  Data :: [{real_name, {Path, AfterPath}}],
                  ConfigDB :: ets:tid(),
                  RequestURI :: string(),
                  AfterPath :: string(),
                  Path :: string().

path/3 returns the file Path in the RequestURI (see RFC 1945). If the interaction data {real_name, {Path, AfterPath}} has been exported by mod_alias, Path is returned. If no interaction data has been exported, ServerRoot is used to generate a file Path. config_db() and interaction_data() are as defined in Inets User's Guide.

real_name(ConfigDB, RequestURI, Aliases)

-spec real_name(ConfigDB, RequestURI, Aliases) -> ReturnPath
                   when
                       ConfigDB :: ets:tid(),
                       RequestURI :: string(),
                       Aliases :: [{FakeName, RealName}],
                       ReturnPath :: {ShortPath, Path, AfterPath},
                       FakeName :: re:mp() | iodata() | unicode:charlist() | string(),
                       RealName :: string(),
                       ShortPath :: string(),
                       Path :: string(),
                       AfterPath :: string().

real_name/3 traverses Aliases, typically extracted from ConfigDB, and matches each FakeName with RequestURI. If a match is found, FakeName is replaced with RealName in the match. The resulting path is split into two parts, ShortPath and AfterPath, as defined in httpd_util:split_path/1. Path is generated from ShortPath, that is, the result from default_index/2 with ShortPath as an argument. config_db() is the server config file in ETS table format as described in Inets User's Guide.

real_script_name(ConfigDB, RequestURI, ScriptAliases)

-spec real_script_name(ConfigDB, RequestURI, ScriptAliases) -> ReturnPath | not_a_script
                          when
                              ConfigDB :: ets:tid(),
                              RequestURI :: string(),
                              ScriptAliases :: list() | [{FakeName, RealName}],
                              ReturnPath :: {ShortPath, AfterPath},
                              FakeName :: re:mp() | iodata() | unicode:charlist() | string(),
                              RealName :: string(),
                              ShortPath :: string(),
                              AfterPath :: term().

real_script_name/3 traverses ScriptAliases, typically extracted from ConfigDB, and matches each FakeName with RequestURI. If a match is found, FakeName is replaced with RealName in the match. If the resulting match is not an executable script, not_a_script is returned. If it is a script, the resulting script path is in two parts, ShortPath and AfterPath, as defined in httpd_util:split_script_path/1. config_db() is the server config file in ETS table format as described in Inets User's Guide.

mod_auth

User authentication using text files, Dets, or Mnesia database.

This module provides for basic user authentication using textual files, Dets databases, or Mnesia databases.

See also

httpd, mod_alias

Summary

Types

httpd_group()

httpd_user()

Functions

add_group_member(GroupName, UserName, Options)

Equivalent to add_group_member/5.

add_group_member(GroupName, UserName, Port, Directory)

Equivalent to add_group_member/5.

add_group_member(GroupName, UserName, Address, Port, Directory)

add_group_member/3, add_group_member/4, and add_group_member/5 each adds a user to a group. If the group does not exist, it is created and the user is added to the group. Upon successful operation, this function returns true. When add_group_members/3 is called, options Port and Dir are mandatory.

add_user(UserName, Options)

Equivalent to add_user/6.

add_user(UserName, Password, UserData, Port, Directory)

Equivalent to add_user/6.

add_user(UserName, Password, UserData, Address, Port, Directory)

add_user(UserName, Password, UserData, Address, Port, Dir) -> true | {error, Reason}

delete_group(GroupName, Options)

Equivalent to delete_group/4.

delete_group(GroupName, Port, Directory)

Equivalent to delete_group(GroupName, undefined, Port, Dir).

delete_group(GroupName, Address, Port, Directory)

delete_group/2, delete_group/3, and delete_group/4 each deletes the group specified and returns true. If there is an error, {error, Reason} is returned. When delete_group/2 is called, option Port and Dir are mandatory.

delete_group_member(GroupName, UserName, Options)

Equivalent to delete_group_member/5.

delete_group_member(GroupName, UserName, Port, Directory)

Equivalent to delete_group_member/5.

delete_group_member(GroupName, UserName, Address, Port, Directory)

delete_group_member/3, delete_group_member/4, and delete_group_member/5 each deletes a user from a group. If the group or the user does not exist, this function returns an error, otherwise true. When delete_group_member/3 is called, the options Port and Dir are mandatory.

delete_user(UserName, Options)

Equivalent to delete_user/4.

delete_user(UserName, Port, Directory)

Equivalent to delete_user/4.

delete_user(UserName, Address, Port, Directory)

delete_user/2, delete_user/3, and delete_user/4 each deletes a user from the user database. If the operation is successful, this function returns true. If an error occurs, {error, Reason} is returned. When delete_user/2 is called, options Port and Dir are mandatory.

get_user(UserName, Options)

Equivalent to get_user/4.

get_user(UserName, Port, Directory)

Equivalent to get_user/4.

get_user(UserName, Address, Port, Directory)

get_user/2, get_user/3, and get_user/4 each returns an httpd_user/0 record containing the userdata for a specific user. If the user cannot be found, {error, Reason} is returned. When get_user/2 is called, options Port and Dir are mandatory.

list_group_members(GroupName, Options)

Equivalent to list_group_members/4.

list_group_members(GroupName, Port, Directory)

Equivalent to list_group_members/4.

list_group_members(GroupName, Address, Port, Directory)

list_group_members/2, list_group_members/3, and list_group_members/4 each lists the members of a specified group. If the group does not exist or there is an error, {error, Reason} is returned. When list_group_members/2 is called, options Port and Dir are mandatory.

list_groups(Options)

Equivalent to list_groups/3.

list_groups(Port, Directory)

Equivalent to list_groups/3.

list_groups(Address, Port, Directory)

list_groups/1, list_groups/2, and list_groups/3 each lists all the groups available. If there is an error, {error, Reason} is returned. When list_groups/1 is called, options Port and Dir are mandatory.

list_users(Options)

Equivalent to list_users/3.

list_users(Port, Directory)

Equivalent to list_users/3.

list_users(Address, Port, Directory)

list_users/1, list_users/2, and list_users/3 each returns a list of users in the user database for a specific Port/Dir. When list_users/1 is called, options Port and Dir are mandatory.

update_password(Port, Dir, OldPassword, NewPassword, NewPassword)

Equivalent to update_password/6.

update_password(Address, Port, Dir, OldPassword, NewPassword, NewPassword)

update_password/5 and update_password/6 each updates AuthAccessPassword for the specified directory. If NewPassword is equal to "NoPassword", no password is required to change authorisation data. If NewPassword is equal to "DummyPassword", no changes can be done without changing the password first.

Types

httpd_group()

(not exported)

-type httpd_group() :: #httpd_group{name :: term(), userlist :: term()}.

httpd_user()

(not exported)

-type httpd_user() :: #httpd_user{username :: term(), password :: term(), user_data :: term()}.

Functions

add_group_member(GroupName, UserName, Options)

-spec add_group_member(GroupName, UserName, Options) -> true | {error, Reason}
                          when
                              GroupName :: string(),
                              UserName :: string(),
                              Options ::
                                  [{port, Port} |
                                   {addr, Address} |
                                   {dir, Directory} |
                                   {authPassword, AuthPassword}],
                              Port :: inet:port_number(),
                              Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                              Directory :: string(),
                              AuthPassword :: string(),
                              Reason :: term().

Equivalent to add_group_member/5.

add_group_member(GroupName, UserName, Port, Directory)

-spec add_group_member(GroupName, UserName, Port, Directory) -> true | {error, Reason}
                          when
                              GroupName :: string(),
                              UserName :: string(),
                              Port :: inet:port_number(),
                              Directory :: string(),
                              Reason :: term().

Equivalent to add_group_member/5.

add_group_member(GroupName, UserName, Address, Port, Directory)

-spec add_group_member(GroupName, UserName, Address, Port, Directory) -> true | {error, Reason}
                          when
                              GroupName :: string(),
                              UserName :: string(),
                              Port :: inet:port_number(),
                              Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                              Directory :: string(),
                              Reason :: term().

add_group_member/3, add_group_member/4, and add_group_member/5 each adds a user to a group. If the group does not exist, it is created and the user is added to the group. Upon successful operation, this function returns true. When add_group_members/3 is called, options Port and Dir are mandatory.

add_user(UserName, Options)

-spec add_user(UserName, Options) -> true | {error, Reason}
                  when
                      UserName :: string(),
                      Options ::
                          [{password, Password} |
                           {userData, UserData} |
                           {port, Port} |
                           {addr, Address} |
                           {dir, Directory} |
                           {authPassword, AuthPassword}],
                      Password :: string(),
                      UserData :: term(),
                      Port :: inet:port_number(),
                      Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                      Directory :: string(),
                      AuthPassword :: string(),
                      Reason :: term().

Equivalent to add_user/6.

add_user(UserName, Password, UserData, Port, Directory)

-spec add_user(UserName, Password, UserData, Port, Directory) -> true | {error, Reason}
                  when
                      UserName :: string(),
                      Password :: string(),
                      UserData :: term(),
                      Port :: inet:port_number(),
                      Directory :: string(),
                      Reason :: term().

Equivalent to add_user/6.

add_user(UserName, Password, UserData, Address, Port, Directory)

-spec add_user(UserName, Password, UserData, Address, Port, Directory) -> true | {error, Reason}
                  when
                      UserName :: string(),
                      Password :: string(),
                      UserData :: term(),
                      Port :: inet:port_number(),
                      Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                      Directory :: string(),
                      Reason :: term().

add_user(UserName, Password, UserData, Address, Port, Dir) -> true | {error, Reason}

add_user/2, add_user/5, and add_user/6 each adds a user to the user database. If the operation is successful, this function returns true. If an error occurs, {error, Reason} is returned. When add_user/2 is called, options Password, UserData, Port, and Dir are mandatory.

delete_group(GroupName, Options)

-spec delete_group(GroupName, Options) -> true | {error, Reason}
                      when
                          GroupName :: string(),
                          Options ::
                              [{port, Port} |
                               {addr, Address} |
                               {dir, Directory} |
                               {authPassword, AuthPassword}],
                          Port :: inet:port_number(),
                          Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                          Directory :: string(),
                          AuthPassword :: string(),
                          Reason :: term().

Equivalent to delete_group/4.

delete_group(GroupName, Port, Directory)

-spec delete_group(GroupName, Port, Directory) -> true | {error, Reason}
                      when
                          GroupName :: string(),
                          Port :: inet:port_number(),
                          Directory :: string(),
                          Reason :: term().

Equivalent to delete_group(GroupName, undefined, Port, Dir).

delete_group(GroupName, Address, Port, Directory)

-spec delete_group(GroupName, Address, Port, Directory) -> true | {error, Reason}
                      when
                          GroupName :: string(),
                          Port :: inet:port_number(),
                          Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                          Directory :: string(),
                          Reason :: term().

delete_group/2, delete_group/3, and delete_group/4 each deletes the group specified and returns true. If there is an error, {error, Reason} is returned. When delete_group/2 is called, option Port and Dir are mandatory.

delete_group_member(GroupName, UserName, Options)

-spec delete_group_member(GroupName, UserName, Options) -> true | {error, Reason}
                             when
                                 GroupName :: string(),
                                 UserName :: string(),
                                 Options ::
                                     [{port, Port} |
                                      {addr, Address} |
                                      {dir, Directory} |
                                      {authPassword, AuthPassword}],
                                 Port :: inet:port_number(),
                                 Address ::
                                     inet:ip4_address() | inet:ip6_address() | string() | undefined,
                                 Directory :: string(),
                                 AuthPassword :: string(),
                                 Reason :: term().

Equivalent to delete_group_member/5.

delete_group_member(GroupName, UserName, Port, Directory)

-spec delete_group_member(GroupName, UserName, Port, Directory) -> true | {error, Reason}
                             when
                                 GroupName :: string(),
                                 UserName :: string(),
                                 Port :: inet:port_number(),
                                 Directory :: string(),
                                 Reason :: term().

Equivalent to delete_group_member/5.

delete_group_member(GroupName, UserName, Address, Port, Directory)

-spec delete_group_member(GroupName, UserName, Address, Port, Directory) -> true | {error, Reason}
                             when
                                 GroupName :: string(),
                                 UserName :: string(),
                                 Port :: inet:port_number(),
                                 Address ::
                                     inet:ip4_address() | inet:ip6_address() | string() | undefined,
                                 Directory :: string(),
                                 Reason :: term().

delete_group_member/3, delete_group_member/4, and delete_group_member/5 each deletes a user from a group. If the group or the user does not exist, this function returns an error, otherwise true. When delete_group_member/3 is called, the options Port and Dir are mandatory.

delete_user(UserName, Options)

-spec delete_user(UserName, Options) -> true | {error, Reason}
                     when
                         UserName :: string(),
                         Options ::
                             [{port, Port} |
                              {addr, Address} |
                              {dir, Directory} |
                              {authPassword, AuthPassword}],
                         Port :: inet:port_number(),
                         Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                         Directory :: string(),
                         AuthPassword :: string(),
                         Reason :: term().

Equivalent to delete_user/4.

delete_user(UserName, Port, Directory)

-spec delete_user(UserName, Port, Directory) -> true | {error, Reason}
                     when
                         UserName :: string(),
                         Port :: inet:port_number(),
                         Directory :: string(),
                         Reason :: term().

Equivalent to delete_user/4.

delete_user(UserName, Address, Port, Directory)

-spec delete_user(UserName, Address, Port, Directory) -> true | {error, Reason}
                     when
                         UserName :: string(),
                         Port :: inet:port_number(),
                         Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                         Directory :: string(),
                         Reason :: term().

delete_user/2, delete_user/3, and delete_user/4 each deletes a user from the user database. If the operation is successful, this function returns true. If an error occurs, {error, Reason} is returned. When delete_user/2 is called, options Port and Dir are mandatory.

get_user(UserName, Options)

-spec get_user(UserName, Options) -> {ok, User} | {error, Reason}
                  when
                      UserName :: string(),
                      Options ::
                          [{port, Port} |
                           {addr, Address} |
                           {dir, Directory} |
                           {authPassword, AuthPassword}],
                      User :: httpd_user(),
                      Port :: inet:port_number(),
                      Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                      Directory :: string(),
                      AuthPassword :: string(),
                      Reason :: term().

Equivalent to get_user/4.

get_user(UserName, Port, Directory)

-spec get_user(UserName, Port, Directory) -> {ok, User} | {error, Reason}
                  when
                      UserName :: string(),
                      User :: httpd_user(),
                      Port :: inet:port_number(),
                      Directory :: string(),
                      Reason :: term().

Equivalent to get_user/4.

get_user(UserName, Address, Port, Directory)

-spec get_user(UserName, Address, Port, Directory) -> {ok, User} | {error, Reason}
                  when
                      UserName :: string(),
                      User :: httpd_user(),
                      Port :: inet:port_number(),
                      Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                      Directory :: string(),
                      Reason :: term().

get_user/2, get_user/3, and get_user/4 each returns an httpd_user/0 record containing the userdata for a specific user. If the user cannot be found, {error, Reason} is returned. When get_user/2 is called, options Port and Dir are mandatory.

list_group_members(GroupName, Options)

-spec list_group_members(GroupName, Options) -> {ok, Users} | {error, Reason}
                            when
                                GroupName :: string(),
                                Options ::
                                    [{port, Port} |
                                     {addr, Address} |
                                     {dir, Directory} |
                                     {authPassword, AuthPassword}],
                                Port :: inet:port_number(),
                                Address ::
                                    inet:ip4_address() | inet:ip6_address() | string() | undefined,
                                Directory :: string(),
                                Users :: [httpd_user()],
                                AuthPassword :: string(),
                                Reason :: term().

Equivalent to list_group_members/4.

list_group_members(GroupName, Port, Directory)

-spec list_group_members(GroupName, Port, Directory) -> {ok, Users} | {error, Reason}
                            when
                                GroupName :: string(),
                                Port :: inet:port_number(),
                                Directory :: string(),
                                Users :: [httpd_user()],
                                Reason :: term().

Equivalent to list_group_members/4.

list_group_members(GroupName, Address, Port, Directory)

-spec list_group_members(GroupName, Address, Port, Directory) -> {ok, Users} | {error, Reason}
                            when
                                GroupName :: string(),
                                Port :: inet:port_number(),
                                Address ::
                                    inet:ip4_address() | inet:ip6_address() | string() | undefined,
                                Directory :: string(),
                                Users :: [httpd_user()],
                                Reason :: term().

list_group_members/2, list_group_members/3, and list_group_members/4 each lists the members of a specified group. If the group does not exist or there is an error, {error, Reason} is returned. When list_group_members/2 is called, options Port and Dir are mandatory.

list_groups(Options)

-spec list_groups(Options) -> {ok, Groups} | {error, Reason}
                     when
                         Options ::
                             [{port, Port} |
                              {addr, Address} |
                              {dir, Directory} |
                              {authPassword, AuthPassword}],
                         Port :: inet:port_number(),
                         Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                         Directory :: string(),
                         Groups :: [httpd_group()],
                         AuthPassword :: string(),
                         Reason :: term().

Equivalent to list_groups/3.

list_groups(Port, Directory)

-spec list_groups(Port, Directory) -> {ok, Groups} | {error, Reason}
                     when
                         Port :: inet:port_number(),
                         Directory :: string(),
                         Groups :: [httpd_group()],
                         Reason :: term().

Equivalent to list_groups/3.

list_groups(Address, Port, Directory)

-spec list_groups(Address, Port, Directory) -> {ok, Groups} | {error, Reason}
                     when
                         Port :: inet:port_number(),
                         Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                         Directory :: string(),
                         Groups :: [httpd_group()],
                         Reason :: term().

list_groups/1, list_groups/2, and list_groups/3 each lists all the groups available. If there is an error, {error, Reason} is returned. When list_groups/1 is called, options Port and Dir are mandatory.

list_users(Options)

-spec list_users(Options) -> {ok, Users} | {error, Reason}
                    when
                        Options ::
                            [{port, Port} |
                             {addr, Address} |
                             {dir, Directory} |
                             {authPassword, AuthPassword}],
                        Port :: inet:port_number(),
                        Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                        Directory :: string(),
                        Users :: [httpd_user()],
                        AuthPassword :: string(),
                        Reason :: atom().

Equivalent to list_users/3.

list_users(Port, Directory)

(since OTP R14B01)

-spec list_users(Port, Directory) -> {ok, Users} | {error, Reason}
                    when
                        Port :: inet:port_number(),
                        Directory :: string(),
                        Users :: [httpd_user()],
                        Reason :: atom().

Equivalent to list_users/3.

list_users(Address, Port, Directory)

-spec list_users(Address, Port, Directory) -> {ok, Users} | {error, Reason}
                    when
                        Port :: inet:port_number(),
                        Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                        Directory :: string(),
                        Users :: [httpd_user()],
                        Reason :: atom().

list_users/1, list_users/2, and list_users/3 each returns a list of users in the user database for a specific Port/Dir. When list_users/1 is called, options Port and Dir are mandatory.

update_password(Port, Dir, OldPassword, NewPassword, NewPassword)

-spec update_password(Port, Dir, OldPassword, NewPassword, NewPassword) -> ok | {error, Reason}
                         when
                             Port :: inet:port_number(),
                             Dir :: string(),
                             OldPassword :: string(),
                             NewPassword :: string(),
                             Reason :: term().

Equivalent to update_password/6.

update_password(Address, Port, Dir, OldPassword, NewPassword, NewPassword)

-spec update_password(Address, Port, Dir, OldPassword, NewPassword, NewPassword) -> ok | {error, Reason}
                         when
                             Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                             Port :: inet:port_number(),
                             Dir :: string(),
                             OldPassword :: string(),
                             NewPassword :: string(),
                             Reason :: term().

update_password/5 and update_password/6 each updates AuthAccessPassword for the specified directory. If NewPassword is equal to "NoPassword", no password is required to change authorisation data. If NewPassword is equal to "DummyPassword", no changes can be done without changing the password first.

mod_esi behaviour

Erlang Server Interface

This module defines the Erlang Server Interface (ESI) API. It is a more efficient way of writing Erlang scripts for your Inets web server than writing them as common CGI scripts.

Summary

Types

env()

Environment data associated with a request.

session_id()

Identifies the requesting client.

Callbacks: ESI Callback Functions

'Function'(SessionID, Env, Input)

Called by mod_esi in response to requests.

Functions

deliver(SessionID, Data)

Sends data from an ESI script back to the client.

Types

env()

(not exported)

-type env() ::
          {server_software, string()} |
          {server_name, string()} |
          {gateway_interface, string()} |
          {server_protocol, string()} |
          {server_port, integer()} |
          {request_method, string()} |
          {remote_adress, inet:ip_address()} |
          {peer_cert, undefined | no_peercert | public_key:der_encoded()} |
          {script_name, string()} |
          {http_LowerCaseHTTPHeaderName, string()}.

Environment data associated with a request.

Possible values

{server_software, string()} - Indicates the inets version.

{server_name, string()} - The local hostname.

{gateway_interface, string()} - Legacy string used in CGI, just ignore.

{server_protocol, string()} - HTTP version, currently "HTTP/1.1"

{server_port, integer()} - Servers port number.

{request_method, "GET" | "PUT" | "DELETE" | "POST" | "PATCH"} - HTTP request method.

{remote_adress, inet:ip_address()} - The clients ip address.

{peer_cert, undefined | no_peercert | DER:binary()} - For TLS connections where client certificates are used this will be an ASN.1 DER-encoded X509-certificate as an Erlang binary. If client certificates are not used the value will be no_peercert, and if TLS is not used (HTTP or connection is lost due to network failure) the value will be undefined.

{script_name, string()} - Request URI

{http_LowerCaseHTTPHeaderName, string()} - example: {http_content_type, "text/html"}

session_id()

(since OTP 28.0)

-opaque session_id()

Identifies the requesting client.

Callbacks: ESI Callback Functions

'Function'(SessionID, Env, Input)

(optional)

-callback 'Function'(SessionID, Env, Input) -> {continue, State} | _
                        when
                            SessionID :: session_id(),
                            Env :: [env()],
                            Input :: string() | ChunkedData,
                            ChunkedData ::
                                {first, Data :: binary()} |
                                {continue, Data :: binary(), State :: term()} |
                                {last, Data :: binary(), State :: term()},
                            State :: term().

Called by mod_esi in response to requests.

Module must be found in the code path and export Function with an arity of three. An erl_script_alias must also be set up in the configuration file for the web server, see the ESI properties documentation.

The Module and Function that are called depend on the URL. See the ESI introductory documentation for more details.

mod_esi:deliver/2 shall be used to generate the response to the client, and SessionID shall be passed as the first argument.

Chunking

This function may be called several times to chunk the response data. Notice that the first chunk of data sent to the client must at least contain all HTTP header fields that the response will generate. If the first chunk does not contain the end of HTTP header, that is, "\r\n\r\n", the server assumes that no HTTP header fields will be generated. This behaviour depends on the httpd configuration, see below.

Parameters

SessionID: request identifier.

Pass this to mod_esi:deliver/2 when generating a response.

Env: environment data of the request, see env/0.

Input: query data of a GET request or the body of a PUT or POST request.

The default behavior (legacy reasons) for delivering the body, is that the whole body is gathered and converted to a string. But if the httpd config parameter max_client_body_chunk is set, the body will be delivered as binary chunks instead. The maximum size of the chunks is either max_client_body_chunk or decided by the client if it uses HTTP chunked encoding to send the body.

When using the chunking mechanism, this callback must return {continue, State::term()} for all calls where Input is {first, Data::binary()} or {continue, Data::binary(), State::term()}. When Input is {last, Data::binary(), State::term()} the return value will be ignored.

The input State is the last returned State, in it the callback can include any data that it needs to keep track of when handling the chunks.

Note

Note that if the body is small all data may be delivered in only one chunk and then the callback will be called with {last, Data::binary(), undefined} without getting called with {first, Data::binary()}.

Setting a response status

To set the response status code, the special status response header can be sent. For instance, to acknowledge creation of a resource and send an empty JSON response body, one could pass the following:

"status: 201 Created\r\ncontent-type: application/json\r\n\r\n{}"

Functions

deliver(SessionID, Data)

-spec deliver(SessionID, Data) -> ok | {error, Reason}
                 when SessionID :: session_id(), Data :: iolist(), Reason :: bad_sessionID.

Sends data from an ESI script back to the client.

This function is only intended to be used from functions called by the ESI interface to deliver parts of the content to the user.

Note

If any HTTP header fields are added by the script, they must be in the first call to deliver/2, and the data in the call must be a string. Calls after the headers are complete can contain binary data to reduce copying overhead. Do not assume anything about the data type of SessionID. SessionID must be the value given as input to the ESI callback function that you implemented.

mod_security behaviour

Security Audit and Trailing Functionality

Summary

Callbacks

event(What, Port, Dir, Data)

event(What, Address, Port, Dir, Data)

event/4 or event/5 is called whenever an event occurs in the mod_security Erlang web server API module. (event/4 is called if Address is undefined, otherwise event/5. Argument What specifies the type of event that has occurred and is one of the following reasons

Functions

block_user(User, Port, Dir, Seconds)

Equivalent to block_user/5.

block_user(User, Address, Port, Dir, Seconds)

block_user/4 and block_user/5 each blocks the user User from directory Dir for a specified amount of time.

list_auth_users(Port)

Equivalent to list_auth_users/3.

list_auth_users/2

Equivalent to list_auth_users/3.

list_auth_users(Address, Port, Dir)

list_auth_users/1, list_auth_users/2, and list_auth_users/3 each returns a list of users that are currently authenticated. Authentications are stored for SecurityAuthTimeout seconds, and then discarded.

list_blocked_users(Port)

Equivalent to list_blocked_users/3.

list_blocked_users/2

Equivalent to list_blocked_users/3.

list_blocked_users(Address, Port, Dir)

list_blocked_users/1, list_blocked_users/2, and list_blocked_users/3 each returns a list of users that are currently blocked from access.

unblock_user(User, Port)

Equivalent to unblock_user/4.

unblock_user/3

Equivalent to unblock_user/4.

unblock_user(User, Address, Port, Dir)

unblock_user/2, unblock_user/3, and unblock_user/4 each removes the user User from the list of blocked users for Port (and Dir).

Callbacks

event(What, Port, Dir, Data)

(since OTP 18.1)

-callback event(What, Port, Dir, Data) -> term()
                   when
                       What :: auth_fail | user_block | user_unblock,
                       Port :: integer(),
                       Dir :: string(),
                       Data :: [Info],
                       Info :: {Name :: term(), Value :: term()}.

event(What, Address, Port, Dir, Data)

(since OTP 18.1)

-callback event(What, Address, Port, Dir, Data) -> term()
                   when
                       What :: auth_fail | user_block | user_unblock,
                       Port :: integer(),
                       Address :: inet:ip4_address() | inet:ip6_address() | string(),
                       Dir :: string(),
                       Data :: [Info],
                       Info :: {Name :: term(), Value :: term()}.

event/4 or event/5 is called whenever an event occurs in the mod_security Erlang web server API module. (event/4 is called if Address is undefined, otherwise event/5. Argument What specifies the type of event that has occurred and is one of the following reasons:

auth_fail - A failed user authentication.

user_block - A user is being blocked from access.

user_unblock - A user is being removed from the block list.

Note

The event user_unblock is not triggered when a user is removed from the block list explicitly using the unblock_user function.

Functions

block_user(User, Port, Dir, Seconds)

-spec block_user(User, Port, Dir, Seconds) -> true | {error, Reason}
                    when
                        User :: string(),
                        Port :: inet:port_number(),
                        Dir :: string(),
                        Seconds :: non_neg_integer() | infinity,
                        Reason :: no_such_directory.

Equivalent to block_user/5.

block_user(User, Address, Port, Dir, Seconds)

-spec block_user(User, Address, Port, Dir, Seconds) -> true | {error, Reason}
                    when
                        User :: string(),
                        Port :: inet:port_number(),
                        Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                        Dir :: string(),
                        Seconds :: non_neg_integer() | infinity,
                        Reason :: no_such_directory.

block_user/4 and block_user/5 each blocks the user User from directory Dir for a specified amount of time.

list_auth_users(Port)

-spec list_auth_users(Port) -> Users | [] when Port :: inet:port_number(), Users :: [string()].

Equivalent to list_auth_users/3.

list_auth_users/2

-spec list_auth_users(Port, Directory) -> Users | []
                         when Port :: inet:port_number(), Directory :: string(), Users :: [string()];
                     (Address, Port) -> Users | []
                         when
                             Port :: inet:port_number(),
                             Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                             Users :: [string()].

Equivalent to list_auth_users/3.

list_auth_users(Address, Port, Dir)

-spec list_auth_users(Address, Port, Dir) -> Users | []
                         when
                             Port :: inet:port_number(),
                             Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                             Dir :: string(),
                             Users :: [string()].

list_auth_users/1, list_auth_users/2, and list_auth_users/3 each returns a list of users that are currently authenticated. Authentications are stored for SecurityAuthTimeout seconds, and then discarded.

list_blocked_users(Port)

-spec list_blocked_users(Port) -> Users | []
                            when
                                Port :: integer(),
                                Users :: [{blocked_user, term(), term(), term(), term()}].

Equivalent to list_blocked_users/3.

list_blocked_users/2

-spec list_blocked_users(Port, Directory) -> Users | []
                            when
                                Port :: integer(),
                                Directory :: string(),
                                Users :: [{blocked_user, term(), term(), term(), term()}];
                        (Address, Port) -> Users | []
                            when
                                Port :: integer(),
                                Address ::
                                    inet:ip4_address() | inet:ip6_address() | string() | undefined,
                                Users :: [{blocked_user, term(), term(), term(), term()}].

Equivalent to list_blocked_users/3.

list_blocked_users(Address, Port, Dir)

-spec list_blocked_users(Address, Port, Dir) -> Users | []
                            when
                                Port :: integer(),
                                Address ::
                                    inet:ip4_address() | inet:ip6_address() | string() | undefined,
                                Dir :: string(),
                                Users :: [{blocked_user, term(), term(), term(), term()}].

list_blocked_users/1, list_blocked_users/2, and list_blocked_users/3 each returns a list of users that are currently blocked from access.

unblock_user(User, Port)

-spec unblock_user(User, Port) -> true | {error, Reason}
                      when User :: string(), Port :: integer(), Reason :: term().

Equivalent to unblock_user/4.

unblock_user/3

-spec unblock_user(User, Port, Directory) -> true | {error, Reason}
                      when User :: string(), Port :: integer(), Directory :: string(), Reason :: term();
                  (User, Address, Port) -> true | {error, Reason}
                      when
                          User :: string(),
                          Port :: integer(),
                          Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                          Reason :: term().

Equivalent to unblock_user/4.

unblock_user(User, Address, Port, Dir)

-spec unblock_user(User, Address, Port, Dir) -> true | {error, Reason}
                      when
                          User :: string(),
                          Port :: integer(),
                          Address :: inet:ip4_address() | inet:ip6_address() | string() | undefined,
                          Dir :: string(),
                          Reason :: term().

unblock_user/2, unblock_user/3, and unblock_user/4 each removes the user User from the list of blocked users for Port (and Dir).

http_uri

Old URI utility module, use uri_string instead

This module is deprecated since OTP 23. Use the module uri_string to properly handle URIs, this is the recommended module since OTP 21.

Data types

Type definitions that are related to URI:

uri_part() = [byte()] | binary() - Syntax according to the URI definition in RFC 3986, for example, "http://www.erlang.org/"

For more information about URI, see RFC 3986.

Summary

Functions

decode(QuotedData) deprecated

Decodes a possibly percent encoded URI part

encode(Data) deprecated

Performs percent encoding.

Functions

decode(QuotedData)

(since OTP R15B01)

This function is deprecated. http_uri:decode/1 is deprecated; use uri_string:unquote function instead.

-spec decode(QuotedData) -> Data when QuotedData :: unicode:chardata(), Data :: unicode:chardata().

Decodes a possibly percent encoded URI part

Warning

Use uri_string:unquote/1 instead

encode(Data)

(since OTP R15B01)

This function is deprecated. http_uri:encode/1 is deprecated; use uri_string:quote function instead.

-spec encode(Data) -> QuotedData when Data :: unicode:chardata(), QuotedData :: unicode:chardata().

Performs percent encoding.

Warning

Use uri_string:quote/1 instead