http_server
The http_server library provides the user-facing facade for starting
and stopping HTTP and HTTPS servers. It selects a default transport from
the scheme/1 option while still allowing explicit transport
selection when an application needs lower-level control.
By default, scheme(http) uses http_socket_transport and
scheme(https) uses http_process_transport (selecting a TLS
listener). Incompatible scheme, transport, and listener transport
combinations are rejected with a consistency_error/3 exception.
API documentation
Open the ../../apis/library_index.html#http_server link in a web browser.
Loading
To load all entities in this library, load the loader.lgt file:
| ?- logtalk_load(http_server(loader)).
Testing
To test this library predicates, load the tester.lgt file:
| ?- logtalk_load(http_server(tester)).
Bounded serving
To serve a given number of connections, use the serve/4 predicate.
For example:
| ?- http_server::serve(8080, my_handler, 10, [scheme(http)]).
To inspect or reuse a listener, open it explicitly and close it after serving:
| ?- http_server::open('127.0.0.1', Port, Server, []),
http_server::serve(Server, my_handler, 1, ClientInfos),
http_server::close(Server).
Open-ended serving
To serve any number of connections until shutdown, use the
serve_until_shutdown/5 predicate. For example:
| ?- http_server::serve_until_shutdown('127.0.0.1', 8080, my_handler, control, []).
...
| ?- http_server::request_shutdown(control).
...
When the Prolog backend supports threads, you can also use the
start/4-5 and stop/1 predicates. For example:
| ?- http_server::start(8080, my_handler, Server, []),
http_server::stop(Server).
HTTPS
For HTTPS, the server must have TLS credentials. The facade selects
http_process_transport and a TLS listener when scheme(https) is
used, but the transport still needs either explicit certificate and key
files or a request to create temporary credentials.
Use tls_certificate_file/1 and tls_key_file/1 for real
deployments:
| ?- http_server::serve(
'127.0.0.1', 8443, my_handler, 10, _ClientInfos,
[
scheme(https),
tls_certificate_file('/path/to/cert.pem'),
tls_key_file('/path/to/key.pem')
]
).
Use temporary_tls_credentials/1 for local examples and tests. Its
argument is a file name prefix used for temporary certificate and key
files. The temporary files are created by the process transport and
removed when the listener is closed:
| ?- http_server::serve(
'127.0.0.1', 8443, my_handler, 10, _ClientInfos,
[scheme(https), temporary_tls_credentials('logtalk_http_server_')]
).
If scheme(https) is used without either
temporary_tls_credentials/1 or both tls_certificate_file/1 and
tls_key_file/1, the process transport rejects the listener options.
Handling server requests
The handler argument in the examples above, my_handler, is the
object that implements http_handler_protocol and receives each
accepted HTTP request, building the corresponding HTTP response.
For ordinary HTTP requests, the handler is expected to provide a
handle/2 predicate compatible with the http_server_core
request/response pipeline. For example, a minimal handler can
pattern-match the request and return a plain text response:
:- object(my_handler,
implements(http_handler_protocol)).
:- uses(http_core, [
response/6
]).
handle(Request, Response) :-
Request = request(_Method, _Target, Version, _Headers, _Body, _Properties),
response(
Version, status(200, 'OK'), [],
content('text/plain', text('Hello!')), [], Response
).
:- end_object.
When a server accepts a connection, the selected transport reads the
request, calls my_handler::handle(Request, Response), writes the
response back to the client, and then follows the selected serving
policy. Parametric objects can be used when the handler needs
configuration, e.g. static_site_handler(Root).
Options
The predicates that open or start a listener accept the following facade options:
scheme(Scheme)controls the URL scheme served by the listener. Valid values:httporhttps. Default:http.transport(Transport)selects the transport object. Valid values:defaultor an object implementinghttp_transport_protocol. Default:default, which resolves tohttp_socket_transportforscheme(http)and tohttp_process_transportforscheme(https).listener_options(Options)passes additional listener options directly to the selected transport. Default:[].serve_options(Options)passes additional serving options directly to the selected transport. Default:[].control(Control)names the shutdown control used bystart/4-5and open-ended serving. Valid values: any non-variable term, ordefaultto create a fresh internal control term. Default:default.
For convenience, selected listener and serving options can also be
written directly in the facade option list instead of wrapping them in
listener_options/1 or serve_options/1:
Listener options:
backlog/1,type/1,listener_transport/1,listener_helper_executable/1,temporary_tls_credentials/1,tls_certificate_file/1, andtls_key_file/1.Serving options:
workers/1andshutdown/1.
The direct listener options accepted by the facade have the following
values: backlog/1 takes a positive integer, type/1 takes
binary or text, listener_transport/1 takes tcp or
tls, listener_helper_executable/1 takes ncat or socat,
and the TLS credential options take file names or a temporary file name
prefix as atoms.
The direct serving options accepted by the facade are
workers(serial), workers(per_connection),
workers(pool(Size)), workers(pool(Size, rolling)),
shutdown(keep_open), and shutdown(close).
These direct options are pass-through options. They are checked by the
facade for basic shape, but the selected transport still decides whether
a particular option is supported and what its transport-specific default
is. For example, listener_transport(tls),
listener_helper_executable/1, and the TLS credential options are
options for the process transport. With scheme(https), the facade
adds listener_transport(tls) automatically unless another listener
transport is explicitly specified.
When the process transport is selected, these listener defaults apply:
backlog(5), type(binary), listener_transport(tcp), and
listener_helper_executable(ncat). The facade changes the effective
listener transport to tls for scheme(https). The TLS credential
options have no default usable certificate:
temporary_tls_credentials/1 must be requested explicitly, or both
tls_certificate_file/1 and tls_key_file/1 must be provided when
opening a TLS listener.
Common serving defaults are inherited from the transports:
workers(serial) and shutdown(keep_open). The convenience
predicates that open and close a listener around a bounded request loop
add shutdown(close) while serving.