mirror of
https://github.com/c-cube/nanoev.git
synced 2025-12-06 11:15:48 -05:00
134 lines
40 KiB
HTML
134 lines
40 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Tiny_httpd (tiny_httpd.Tiny_httpd)</title><meta charset="utf-8"/><link rel="stylesheet" href="../../_odoc-theme/odoc.css"/><meta name="generator" content="odoc 3.0.0"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> – <a href="../../index.html">Index</a> » <a href="../index.html">tiny_httpd</a> » Tiny_httpd</nav><header class="odoc-preamble"><h1>Module <code><span>Tiny_httpd</span></code></h1><p>Tiny Http Server</p><p>This library implements a very simple, basic HTTP/1.1 server using blocking IOs and threads. Basic routing based is provided for convenience, so that several handlers can be registered.</p><p>It is possible to use a thread pool, see <a href="#val-create"><code>create</code></a>'s argument <code>new_thread</code>.</p><p>The <code>echo</code> example (see <code>src/examples/echo.ml</code>) demonstrates some of the features by declaring a few endpoints, including one for uploading files:</p><pre class="language-ocaml"><code>module S = Tiny_httpd
|
||
|
||
let () =
|
||
let server = S.create () in
|
||
|
||
(* say hello *)
|
||
S.add_route_handler ~meth:`GET server
|
||
S.Route.(exact "hello" @/ string @/ return)
|
||
(fun name _req -> S.Response.make_string (Ok ("hello " ^name ^"!\n")));
|
||
|
||
(* echo request *)
|
||
S.add_route_handler server
|
||
S.Route.(exact "echo" @/ return)
|
||
(fun req -> S.Response.make_string
|
||
(Ok (Format.asprintf "echo:@ %a@." S.Request.pp req)));
|
||
|
||
(* file upload *)
|
||
S.add_route_handler ~meth:`PUT server
|
||
S.Route.(exact "upload" @/ string_urlencoded @/ return)
|
||
(fun path req ->
|
||
try
|
||
let oc = open_out @@ "/tmp/" ^ path in
|
||
output_string oc req.S.Request.body;
|
||
flush oc;
|
||
S.Response.make_string (Ok "uploaded file")
|
||
with e ->
|
||
S.Response.fail ~code:500 "couldn't upload file: %s"
|
||
(Printexc.to_string e)
|
||
);
|
||
|
||
(* run the server *)
|
||
Printf.printf "listening on http://%s:%d\n%!" (S.addr server) (S.port server);
|
||
match S.run server with
|
||
| Ok () -> ()
|
||
| Error e -> raise e</code></pre><p>It is then possible to query it using curl:</p><pre class="language-ocaml"><code>$ dune exec src/examples/echo.exe &
|
||
listening on http://127.0.0.1:8080
|
||
|
||
# the path "hello/name" greets you.
|
||
$ curl -X GET http://localhost:8080/hello/quadrarotaphile
|
||
hello quadrarotaphile!
|
||
|
||
# the path "echo" just prints the request.
|
||
$ curl -X GET http://localhost:8080/echo --data "howdy y'all"
|
||
echo:
|
||
{meth=GET;
|
||
headers=Host: localhost:8080
|
||
User-Agent: curl/7.66.0
|
||
Accept: */*
|
||
Content-Length: 10
|
||
Content-Type: application/x-www-form-urlencoded;
|
||
path="/echo"; body="howdy y'all"}
|
||
|
||
</code></pre></header><div class="odoc-tocs"><nav class="odoc-toc odoc-local-toc"><ul><li><a href="#tiny-buffer-implementation">Tiny buffer implementation</a></li><li><a href="#io-abstraction">IO Abstraction</a></li><li><a href="#logging">Logging</a></li><li><a href="#utils">Utils</a></li><li><a href="#resource-pool">Resource pool</a></li><li><a href="#static-directory-serving">Static directory serving</a></li><li><a href="#html-combinators">HTML combinators</a></li><li><a href="#main-server-types">Main server types</a><ul><li><a href="#middlewares">Middlewares</a></li><li><a href="#main-server-type">Main Server type</a></li><li><a href="#request-handlers">Request handlers</a></li><li><a href="#server-sent-events">Server-sent events</a></li><li><a href="#upgrade-handlers">Upgrade handlers</a></li><li><a href="#run-the-server">Run the server</a></li></ul></li></ul></nav></div><div class="odoc-content"><h3 id="tiny-buffer-implementation"><a href="#tiny-buffer-implementation" class="anchor"></a>Tiny buffer implementation</h3><p>These buffers are used to avoid allocating too many byte arrays when processing streams and parsing requests.</p><div class="odoc-spec"><div class="spec module anchored" id="module-Buf"><a href="#module-Buf" class="anchor"></a><code><span><span class="keyword">module</span> Buf</span><span> = <a href="../Tiny_httpd_core/Buf/index.html">Tiny_httpd_core.Buf</a></span></code></div></div><h3 id="io-abstraction"><a href="#io-abstraction" class="anchor"></a>IO Abstraction</h3><div class="odoc-spec"><div class="spec module anchored" id="module-IO"><a href="#module-IO" class="anchor"></a><code><span><span class="keyword">module</span> IO</span><span> = <a href="../Tiny_httpd_core/IO/index.html">Tiny_httpd_core.IO</a></span></code></div></div><h3 id="logging"><a href="#logging" class="anchor"></a>Logging</h3><div class="odoc-spec"><div class="spec module anchored" id="module-Log"><a href="#module-Log" class="anchor"></a><code><span><span class="keyword">module</span> Log</span><span> = <a href="../Tiny_httpd_core/Log/index.html">Tiny_httpd_core.Log</a></span></code></div></div><h3 id="utils"><a href="#utils" class="anchor"></a>Utils</h3><div class="odoc-spec"><div class="spec module anchored" id="module-Util"><a href="#module-Util" class="anchor"></a><code><span><span class="keyword">module</span> Util</span><span> = <a href="../Tiny_httpd_core/Util/index.html">Tiny_httpd_core.Util</a></span></code></div></div><h3 id="resource-pool"><a href="#resource-pool" class="anchor"></a>Resource pool</h3><div class="odoc-spec"><div class="spec module anchored" id="module-Pool"><a href="#module-Pool" class="anchor"></a><code><span><span class="keyword">module</span> Pool</span><span> = <a href="../Tiny_httpd_core/Pool/index.html">Tiny_httpd_core.Pool</a></span></code></div></div><h3 id="static-directory-serving"><a href="#static-directory-serving" class="anchor"></a>Static directory serving</h3><div class="odoc-spec"><div class="spec module anchored" id="module-Dir"><a href="#module-Dir" class="anchor"></a><code><span><span class="keyword">module</span> Dir</span><span> = <a href="../Tiny_httpd_unix/Dir/index.html">Tiny_httpd_unix.Dir</a></span></code></div></div><div class="odoc-spec"><div class="spec module-type anchored" id="module-type-VFS"><a href="#module-type-VFS" class="anchor"></a><code><span><span class="keyword">module</span> <span class="keyword">type</span> VFS</span><span> = <a href="../Tiny_httpd_unix/Dir/module-type-VFS/index.html">Tiny_httpd_unix.Dir.VFS</a></span></code></div></div><h3 id="html-combinators"><a href="#html-combinators" class="anchor"></a>HTML combinators</h3><div class="odoc-spec"><div class="spec module anchored" id="module-Html"><a href="#module-Html" class="anchor"></a><code><span><span class="keyword">module</span> Html</span><span> = <a href="../Tiny_httpd_html/index.html">Tiny_httpd_html</a></span></code></div><div class="spec-doc"><p>Alias to <a href="../Tiny_httpd_html/index.html"><code>Tiny_httpd_html</code></a></p></div></div><h3 id="main-server-types"><a href="#main-server-types" class="anchor"></a>Main server types</h3><div class="odoc-spec"><div class="spec module anchored" id="module-Request"><a href="#module-Request" class="anchor"></a><code><span><span class="keyword">module</span> Request</span><span> = <a href="../Tiny_httpd_core/Request/index.html">Tiny_httpd_core.Request</a></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Response"><a href="#module-Response" class="anchor"></a><code><span><span class="keyword">module</span> Response</span><span> = <a href="../Tiny_httpd_core/Response/index.html">Tiny_httpd_core.Response</a></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Response_code"><a href="#module-Response_code" class="anchor"></a><code><span><span class="keyword">module</span> Response_code</span><span> = <a href="../Tiny_httpd_core/Response_code/index.html">Tiny_httpd_core.Response_code</a></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Route"><a href="#module-Route" class="anchor"></a><code><span><span class="keyword">module</span> Route</span><span> = <a href="../Tiny_httpd_core/Route/index.html">Tiny_httpd_core.Route</a></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Headers"><a href="#module-Headers" class="anchor"></a><code><span><span class="keyword">module</span> Headers</span><span> = <a href="../Tiny_httpd_core/Headers/index.html">Tiny_httpd_core.Headers</a></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Meth"><a href="#module-Meth" class="anchor"></a><code><span><span class="keyword">module</span> Meth</span><span> = <a href="../Tiny_httpd_core/Meth/index.html">Tiny_httpd_core.Meth</a></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Server"><a href="#module-Server" class="anchor"></a><code><span><span class="keyword">module</span> Server</span><span> = <a href="../Tiny_httpd_core/Server/index.html">Tiny_httpd_core.Server</a></span></code></div></div><div class="odoc-spec"><div class="spec exception anchored" id="exception-Bad_req"><a href="#exception-Bad_req" class="anchor"></a><code><span><span class="keyword">exception</span> </span><span><span class="exception">Bad_req</span> <span class="keyword">of</span> int * string</span></code></div><div class="spec-doc"><p>Exception raised to exit request handlers with a code+error message</p></div></div><h5 id="middlewares"><a href="#middlewares" class="anchor"></a>Middlewares</h5><p>A middleware can be inserted in a handler to modify or observe its behavior.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.11</li></ul><div class="odoc-spec"><div class="spec module anchored" id="module-Middleware"><a href="#module-Middleware" class="anchor"></a><code><span><span class="keyword">module</span> Middleware</span><span> = <a href="../Tiny_httpd_core/Server/Middleware/index.html">Server.Middleware</a></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Head_middleware"><a href="#module-Head_middleware" class="anchor"></a><code><span><span class="keyword">module</span> Head_middleware</span><span> = <a href="../Tiny_httpd_core/Server/Head_middleware/index.html">Server.Head_middleware</a></span></code></div><div class="spec-doc"><p>A middleware that only considers the request's head+headers.</p></div></div><h5 id="main-server-type"><a href="#main-server-type" class="anchor"></a>Main Server type</h5><div class="odoc-spec"><div class="spec type anchored" id="type-t"><a href="#type-t" class="anchor"></a><code><span><span class="keyword">type</span> t</span><span> = <a href="../Tiny_httpd_core/Server/index.html#type-t">Tiny_httpd_core.Server.t</a></span></code></div><div class="spec-doc"><p>A HTTP server. See <a href="#val-create"><code>create</code></a> for more details.</p></div></div><div class="odoc-spec"><div class="spec module-type anchored" id="module-type-IO_BACKEND"><a href="#module-type-IO_BACKEND" class="anchor"></a><code><span><span class="keyword">module</span> <span class="keyword">type</span> IO_BACKEND</span><span> = <a href="../Tiny_httpd_core/Server/module-type-IO_BACKEND/index.html">Server.IO_BACKEND</a></span></code></div><div class="spec-doc"><p>A backend that provides IO operations, network operations, etc.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-create_from"><a href="#val-create_from" class="anchor"></a><code><span><span class="keyword">val</span> create_from :
|
||
<span><span class="optlabel">?enable_logging</span>:bool <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?buf_size</span>:int <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?head_middlewares</span>:<span><a href="../Tiny_httpd_core/Server/Head_middleware/index.html#type-t">Head_middleware.t</a> list</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?middlewares</span>:<span><span>(<span>[ `Encoding <span><span>| `Stage</span> of int</span> ]</span> * <a href="../Tiny_httpd_core/Server/Middleware/index.html#type-t">Middleware.t</a>)</span> list</span> <span class="arrow">-></span></span>
|
||
<span><span class="label">backend</span>:<span>(<span class="keyword">module</span> <a href="module-type-IO_BACKEND/index.html">IO_BACKEND</a>)</span> <span class="arrow">-></span></span>
|
||
<span>unit <span class="arrow">-></span></span>
|
||
<a href="#type-t">t</a></span></code></div><div class="spec-doc"><p>Create a new webserver using provided backend.</p><p>The server will not do anything until <a href="#val-run"><code>run</code></a> is called on it. Before starting the server, one can use <code>add_path_handler</code> and <a href="#val-set_top_handler"><code>set_top_handler</code></a> to specify how to handle incoming requests.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">buf_size</span> <p>size for buffers (since 0.11)</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">head_middlewares</span> <p>see <a href="#val-add_head_middleware"><code>add_head_middleware</code></a> for details (since 0.18)</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">middlewares</span> <p>see <a href="#val-add_middleware"><code>add_middleware</code></a> for more details.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">enable_logging</span> <p>if true and <code>Logs</code> is installed, emit logs via Logs (since 0.18). Default <code>true</code>.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-addr"><a href="#val-addr" class="anchor"></a><code><span><span class="keyword">val</span> addr : <span><a href="#type-t">t</a> <span class="arrow">-></span></span> string</span></code></div><div class="spec-doc"><p>Address on which the server listens.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-is_ipv6"><a href="#val-is_ipv6" class="anchor"></a><code><span><span class="keyword">val</span> is_ipv6 : <span><a href="#type-t">t</a> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p><code>is_ipv6 server</code> returns <code>true</code> iff the address of the server is an IPv6 address.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.3</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-port"><a href="#val-port" class="anchor"></a><code><span><span class="keyword">val</span> port : <span><a href="#type-t">t</a> <span class="arrow">-></span></span> int</span></code></div><div class="spec-doc"><p>Port on which the server listens. Note that this might be different than the port initially given if the port was <code>0</code> (meaning that the OS picks a port for us).</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-active_connections"><a href="#val-active_connections" class="anchor"></a><code><span><span class="keyword">val</span> active_connections : <span><a href="#type-t">t</a> <span class="arrow">-></span></span> int</span></code></div><div class="spec-doc"><p>Number of currently active connections.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_decode_request_cb"><a href="#val-add_decode_request_cb" class="anchor"></a><code><span><span class="keyword">val</span> add_decode_request_cb :
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><span>(<span><span>unit <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span>(<span>unit <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span>
|
||
* <span>(<span><a href="../Tiny_httpd_core/IO/Input/class-type-t/index.html">Tiny_httpd_core.IO.Input.t</a> <span class="arrow">-></span></span>
|
||
<a href="../Tiny_httpd_core/IO/Input/class-type-t/index.html">Tiny_httpd_core.IO.Input.t</a>)</span>)</span>
|
||
option</span>)</span> <span class="arrow">-></span></span>
|
||
unit</span></code></div><div class="spec-doc"><p>Add a callback for every request. The callback can provide a stream transformer and a new request (with modified headers, typically). A possible use is to handle decompression by looking for a <code>Transfer-Encoding</code> header and returning a stream transformer that decompresses on the fly.</p><ul class="at-tags"><li class="deprecated"><span class="at-tag">deprecated</span> <p>use <a href="#val-add_middleware"><code>add_middleware</code></a> instead</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_encode_response_cb"><a href="#val-add_encode_response_cb" class="anchor"></a><code><span><span class="keyword">val</span> add_encode_response_cb :
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><span>(<span><span>unit <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<span><a href="../Tiny_httpd_core/Response/index.html#type-t">Tiny_httpd_core.Response.t</a> <span class="arrow">-></span></span>
|
||
<span><a href="../Tiny_httpd_core/Response/index.html#type-t">Tiny_httpd_core.Response.t</a> option</span>)</span> <span class="arrow">-></span></span>
|
||
unit</span></code></div><div class="spec-doc"><p>Add a callback for every request/response pair. Similarly to <a href="#val-add_encode_response_cb"><code>add_encode_response_cb</code></a> the callback can return a new response, for example to compress it. The callback is given the query with only its headers, as well as the current response.</p><ul class="at-tags"><li class="deprecated"><span class="at-tag">deprecated</span> <p>use <a href="#val-add_middleware"><code>add_middleware</code></a> instead</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_middleware"><a href="#val-add_middleware" class="anchor"></a><code><span><span class="keyword">val</span> add_middleware :
|
||
<span><span class="label">stage</span>:<span>[ `Encoding <span><span>| `Stage</span> of int</span> ]</span> <span class="arrow">-></span></span>
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><a href="../Tiny_httpd_core/Server/Middleware/index.html#type-t">Middleware.t</a> <span class="arrow">-></span></span>
|
||
unit</span></code></div><div class="spec-doc"><p>Add a middleware to every request/response pair.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">stage</span> <p>specify when middleware applies. Encoding comes first (outermost layer), then stages in increasing order.</p></li></ul><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <code>Invalid_argument</code> <p>if stage is <code>`Stage n</code> where <code>n < 1</code></p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.11</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_head_middleware"><a href="#val-add_head_middleware" class="anchor"></a><code><span><span class="keyword">val</span> add_head_middleware : <span><a href="#type-t">t</a> <span class="arrow">-></span></span> <span><a href="../Tiny_httpd_core/Server/Head_middleware/index.html#type-t">Head_middleware.t</a> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p>Add a request-header only <a href="../Tiny_httpd_core/Server/Head_middleware/index.html#type-t"><code>Head_middleware.t</code></a>. This is called on requests, to modify them, and returns a new request immediately.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.18</li></ul></div></div><h5 id="request-handlers"><a href="#request-handlers" class="anchor"></a>Request handlers</h5><div class="odoc-spec"><div class="spec value anchored" id="val-set_top_handler"><a href="#val-set_top_handler" class="anchor"></a><code><span><span class="keyword">val</span> set_top_handler :
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><span>(<span><span><a href="../Tiny_httpd_core/IO/Input/class-type-t/index.html">Tiny_httpd_core.IO.Input.t</a> <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<a href="../Tiny_httpd_core/Response/index.html#type-t">Tiny_httpd_core.Response.t</a>)</span> <span class="arrow">-></span></span>
|
||
unit</span></code></div><div class="spec-doc"><p>Setup a handler called by default.</p><p>This handler is called with any request not accepted by any handler installed via <code>add_path_handler</code>. If no top handler is installed, unhandled paths will return a <code>404</code> not found</p><p>This used to take a <code>string Request.t</code> but it now takes a <code>byte_stream Request.t</code> since 0.14 . Use <a href="../Tiny_httpd_core/Request/index.html#val-read_body_full"><code>Request.read_body_full</code></a> to read the body into a string if needed.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_route_handler"><a href="#val-add_route_handler" class="anchor"></a><code><span><span class="keyword">val</span> add_route_handler :
|
||
<span><span class="optlabel">?accept</span>:
|
||
<span>(<span><span>unit <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span>(unit, <a href="../Tiny_httpd_core/Response_code/index.html#type-t">Tiny_httpd_core.Response_code.t</a> * string)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span>)</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?middlewares</span>:<span><a href="../Tiny_httpd_core/Server/Middleware/index.html#type-t">Middleware.t</a> list</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?meth</span>:<a href="../Tiny_httpd_core/Meth/index.html#type-t">Tiny_httpd_core.Meth.t</a> <span class="arrow">-></span></span>
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><span><span>(<span class="type-var">'a</span>, <span><span>string <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span> <a href="../Tiny_httpd_core/Response/index.html#type-t">Tiny_httpd_core.Response.t</a>)</span>
|
||
<a href="../Tiny_httpd_core/Route/index.html#type-t">Tiny_httpd_core.Route.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span class="type-var">'a</span> <span class="arrow">-></span></span>
|
||
unit</span></code></div><div class="spec-doc"><p><code>add_route_handler server Route.(exact "path" @/ string @/ int @/ return) f</code> calls <code>f "foo" 42 request</code> when a <code>request</code> with path "path/foo/42/" is received.</p><p>Note that the handlers are called in the reverse order of their addition, so the last registered handler can override previously registered ones.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">meth</span> <p>if provided, only accept requests with the given method. Typically one could react to <code>`GET</code> or <code>`PUT</code>.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">accept</span> <p>should return <code>Ok()</code> if the given request (before its body is read) should be accepted, <code>Error (code,message)</code> if it's to be rejected (e.g. because its content is too big, or for some permission error). See the <code>http_of_dir</code> program for an example of how to use <code>accept</code> to filter uploads that are too large before the upload even starts. The default always returns <code>Ok()</code>, i.e. it accepts all requests.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_route_handler_stream"><a href="#val-add_route_handler_stream" class="anchor"></a><code><span><span class="keyword">val</span> add_route_handler_stream :
|
||
<span><span class="optlabel">?accept</span>:
|
||
<span>(<span><span>unit <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span>(unit, <a href="../Tiny_httpd_core/Response_code/index.html#type-t">Tiny_httpd_core.Response_code.t</a> * string)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span>)</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?middlewares</span>:<span><a href="../Tiny_httpd_core/Server/Middleware/index.html#type-t">Middleware.t</a> list</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?meth</span>:<a href="../Tiny_httpd_core/Meth/index.html#type-t">Tiny_httpd_core.Meth.t</a> <span class="arrow">-></span></span>
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><span><span>(<span class="type-var">'a</span>,
|
||
<span><span><a href="../Tiny_httpd_core/IO/Input/class-type-t/index.html">Tiny_httpd_core.IO.Input.t</a> <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<a href="../Tiny_httpd_core/Response/index.html#type-t">Tiny_httpd_core.Response.t</a>)</span>
|
||
<a href="../Tiny_httpd_core/Route/index.html#type-t">Tiny_httpd_core.Route.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span class="type-var">'a</span> <span class="arrow">-></span></span>
|
||
unit</span></code></div><div class="spec-doc"><p>Similar to <a href="#val-add_route_handler"><code>add_route_handler</code></a>, but where the body of the request is a stream of bytes that has not been read yet. This is useful when one wants to stream the body directly into a parser, json decoder (such as <code>Jsonm</code>) or into a file.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.6</li></ul></div></div><h5 id="server-sent-events"><a href="#server-sent-events" class="anchor"></a>Server-sent events</h5><p><b>EXPERIMENTAL</b>: this API is not stable yet.</p><div class="odoc-spec"><div class="spec module-type anchored" id="module-type-SERVER_SENT_GENERATOR"><a href="#module-type-SERVER_SENT_GENERATOR" class="anchor"></a><code><span><span class="keyword">module</span> <span class="keyword">type</span> SERVER_SENT_GENERATOR</span><span> = <a href="../Tiny_httpd_core/Server/module-type-SERVER_SENT_GENERATOR/index.html">Server.SERVER_SENT_GENERATOR</a></span></code></div><div class="spec-doc"><p>A server-side function to generate of Server-sent events.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-server_sent_generator"><a href="#type-server_sent_generator" class="anchor"></a><code><span><span class="keyword">type</span> server_sent_generator</span><span> = <span>(<span class="keyword">module</span> <a href="module-type-SERVER_SENT_GENERATOR/index.html">SERVER_SENT_GENERATOR</a>)</span></span></code></div><div class="spec-doc"><p>Server-sent event generator. This generates events that are forwarded to the client (e.g. the browser).</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.9</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_route_server_sent_handler"><a href="#val-add_route_server_sent_handler" class="anchor"></a><code><span><span class="keyword">val</span> add_route_server_sent_handler :
|
||
<span><span class="optlabel">?accept</span>:
|
||
<span>(<span><span>unit <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span>(unit, <a href="../Tiny_httpd_core/Response_code/index.html#type-t">Tiny_httpd_core.Response_code.t</a> * string)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span>)</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?middlewares</span>:<span><a href="../Tiny_httpd_core/Server/Head_middleware/index.html#type-t">Head_middleware.t</a> list</span> <span class="arrow">-></span></span>
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><span><span>(<span class="type-var">'a</span>, <span><span>string <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span> <span><a href="#type-server_sent_generator">server_sent_generator</a> <span class="arrow">-></span></span> unit)</span>
|
||
<a href="../Tiny_httpd_core/Route/index.html#type-t">Tiny_httpd_core.Route.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span class="type-var">'a</span> <span class="arrow">-></span></span>
|
||
unit</span></code></div><div class="spec-doc"><p>Add a handler on an endpoint, that serves server-sent events.</p><p>The callback is given a generator that can be used to send events as it pleases. The connection is always closed by the client, and the accepted method is always <code>GET</code>. This will set the header "content-type" to "text/event-stream" automatically and reply with a 200 immediately. See <a href="#type-server_sent_generator"><code>server_sent_generator</code></a> for more details.</p><p>This handler stays on the original thread (it is synchronous).</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.9</li></ul></div></div><h5 id="upgrade-handlers"><a href="#upgrade-handlers" class="anchor"></a>Upgrade handlers</h5><p>These handlers upgrade the connection to another protocol.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.17</li></ul><div class="odoc-spec"><div class="spec module-type anchored" id="module-type-UPGRADE_HANDLER"><a href="#module-type-UPGRADE_HANDLER" class="anchor"></a><code><span><span class="keyword">module</span> <span class="keyword">type</span> UPGRADE_HANDLER</span><span> = <a href="../Tiny_httpd_core/Server/module-type-UPGRADE_HANDLER/index.html">Server.UPGRADE_HANDLER</a></span></code></div><div class="spec-doc"><p>Handler that upgrades to another protocol.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-upgrade_handler"><a href="#type-upgrade_handler" class="anchor"></a><code><span><span class="keyword">type</span> upgrade_handler</span><span> = <span>(<span class="keyword">module</span> <a href="module-type-UPGRADE_HANDLER/index.html">UPGRADE_HANDLER</a>)</span></span></code></div><div class="spec-doc"><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.17</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-add_upgrade_handler"><a href="#val-add_upgrade_handler" class="anchor"></a><code><span><span class="keyword">val</span> add_upgrade_handler :
|
||
<span><span class="optlabel">?accept</span>:
|
||
<span>(<span><span>unit <a href="../Tiny_httpd_core/Request/index.html#type-t">Tiny_httpd_core.Request.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span>(unit, <a href="../Tiny_httpd_core/Response_code/index.html#type-t">Tiny_httpd_core.Response_code.t</a> * string)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span>)</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?middlewares</span>:<span><a href="../Tiny_httpd_core/Server/Head_middleware/index.html#type-t">Head_middleware.t</a> list</span> <span class="arrow">-></span></span>
|
||
<span><a href="#type-t">t</a> <span class="arrow">-></span></span>
|
||
<span><span><span>(<span class="type-var">'a</span>, <a href="#type-upgrade_handler">upgrade_handler</a>)</span> <a href="../Tiny_httpd_core/Route/index.html#type-t">Tiny_httpd_core.Route.t</a></span> <span class="arrow">-></span></span>
|
||
<span><span class="type-var">'a</span> <span class="arrow">-></span></span>
|
||
unit</span></code></div></div><h5 id="run-the-server"><a href="#run-the-server" class="anchor"></a>Run the server</h5><div class="odoc-spec"><div class="spec value anchored" id="val-running"><a href="#val-running" class="anchor"></a><code><span><span class="keyword">val</span> running : <span><a href="#type-t">t</a> <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>Is the server running?</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-stop"><a href="#val-stop" class="anchor"></a><code><span><span class="keyword">val</span> stop : <span><a href="#type-t">t</a> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p>Ask the server to stop. This might not have an immediate effect as <a href="#val-run"><code>run</code></a> might currently be waiting on IO.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-run"><a href="#val-run" class="anchor"></a><code><span><span class="keyword">val</span> run : <span><span class="optlabel">?after_init</span>:<span>(<span>unit <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><a href="#type-t">t</a> <span class="arrow">-></span></span> <span><span>(unit, exn)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p>Run the main loop of the server, listening on a socket described at the server's creation time, using <code>new_thread</code> to start a thread for each new client.</p><p>This returns <code>Ok ()</code> if the server exits gracefully, or <code>Error e</code> if it exits with an error.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">after_init</span> <p>is called after the server starts listening. since 0.13 .</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-run_exn"><a href="#val-run_exn" class="anchor"></a><code><span><span class="keyword">val</span> run_exn : <span><span class="optlabel">?after_init</span>:<span>(<span>unit <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> <span><a href="#type-t">t</a> <span class="arrow">-></span></span> unit</span></code></div><div class="spec-doc"><p><code>run_exn s</code> is like <code>run s</code> but re-raises an exception if the server exits with an error.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.14</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-create"><a href="#val-create" class="anchor"></a><code><span><span class="keyword">val</span> create :
|
||
<span><span class="optlabel">?enable_logging</span>:bool <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?masksigpipe</span>:bool <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?max_connections</span>:int <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?timeout</span>:float <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?buf_size</span>:int <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?get_time_s</span>:<span>(<span>unit <span class="arrow">-></span></span> float)</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?new_thread</span>:<span>(<span><span>(<span>unit <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span> unit)</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?addr</span>:string <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?port</span>:int <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?sock</span>:<a href="../../ocaml/Unix/index.html#type-file_descr">Unix.file_descr</a> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?head_middlewares</span>:<span><a href="../Tiny_httpd_core/Server/Head_middleware/index.html#type-t">Head_middleware.t</a> list</span> <span class="arrow">-></span></span>
|
||
<span><span class="optlabel">?middlewares</span>:<span><span>(<span>[ `Encoding <span><span>| `Stage</span> of int</span> ]</span> * <a href="../Tiny_httpd_core/Server/Middleware/index.html#type-t">Middleware.t</a>)</span> list</span> <span class="arrow">-></span></span>
|
||
<span>unit <span class="arrow">-></span></span>
|
||
<a href="#type-t">t</a></span></code></div><div class="spec-doc"><p>Create a new webserver using UNIX abstractions.</p><p>The server will not do anything until <a href="#val-run"><code>run</code></a> is called on it. Before starting the server, one can use <code>add_path_handler</code> and <a href="#val-set_top_handler"><code>set_top_handler</code></a> to specify how to handle incoming requests.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">masksigpipe</span> <p>if true, block the signal <code>Sys.sigpipe</code> which otherwise tends to kill client threads when they try to write on broken sockets. Default: <code>true</code> except when on Windows, which defaults to <code>false</code>.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">buf_size</span> <p>size for buffers (since 0.11)</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">new_thread</span> <p>a function used to spawn a new thread to handle a new client connection. By default it is <a href="../../ocaml/Thread/index.html#val-create"><code>Thread.create</code></a> but one could use a thread pool instead. See for example <a href="https://github.com/c-cube/tiny-httpd-moonpool-bench/blob/0dcbbffb4fe34ea4ad79d46343ad0cebb69ca69f/examples/t1.ml#L31">this use of moonpool</a>.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">middlewares</span> <p>see <a href="#val-add_middleware"><code>add_middleware</code></a> for more details.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">max_connections</span> <p>maximum number of simultaneous connections.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">timeout</span> <p>connection is closed if the socket does not do read or write for the amount of second. Default: 0.0 which means no timeout. timeout is not recommended when using proxy.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">addr</span> <p>address (IPv4 or IPv6) to listen on. Default <code>"127.0.0.1"</code>.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">port</span> <p>to listen on. Default <code>8080</code>.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">sock</span> <p>an existing socket given to the server to listen on, e.g. by systemd on Linux (or launchd on macOS). If passed in, this socket will be used instead of the <code>addr</code> and <code>port</code>. If not passed in, those will be used. This parameter exists since 0.10.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">enable_logging</span> <p>if true and <code>Logs</code> is installed, log requests. Default true. This parameter exists since 0.18. Does not affect debug-level logs.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">get_time_s</span> <p>obtain the current timestamp in seconds. This parameter exists since 0.11.</p></li></ul></div></div></div></body></html>
|