From 92351cce9193b365eb2bb9710dbcd50d1a297c77 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 18 Nov 2019 22:03:18 -0600 Subject: [PATCH] update docs --- 0.1/tiny_httpd/Tiny_httpd/Buf_/index.html | 2 ++ 0.1/tiny_httpd/Tiny_httpd/Headers/index.html | 2 +- 0.1/tiny_httpd/Tiny_httpd/Meth/index.html | 2 +- 0.1/tiny_httpd/Tiny_httpd/Request/index.html | 2 +- 0.1/tiny_httpd/Tiny_httpd/Response/index.html | 2 +- 0.1/tiny_httpd/Tiny_httpd/Response_code/index.html | 2 +- 0.1/tiny_httpd/Tiny_httpd/Stream_/index.html | 2 ++ 0.1/tiny_httpd/Tiny_httpd/index.html | 2 +- 8 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 0.1/tiny_httpd/Tiny_httpd/Buf_/index.html create mode 100644 0.1/tiny_httpd/Tiny_httpd/Stream_/index.html diff --git a/0.1/tiny_httpd/Tiny_httpd/Buf_/index.html b/0.1/tiny_httpd/Tiny_httpd/Buf_/index.html new file mode 100644 index 00000000..ebecdf1a --- /dev/null +++ b/0.1/tiny_httpd/Tiny_httpd/Buf_/index.html @@ -0,0 +1,2 @@ + +Buf_ (tiny_httpd.Tiny_httpd.Buf_)

Module Tiny_httpd.Buf_

Tiny buffer implementation

These buffers are used to avoid allocating too many byte arrays when processing streams and parsing requests.

type t
val size : t -> int
val clear : t -> unit
val create : ?⁠size:int -> unit -> t
val contents : t -> string
\ No newline at end of file diff --git a/0.1/tiny_httpd/Tiny_httpd/Headers/index.html b/0.1/tiny_httpd/Tiny_httpd/Headers/index.html index 181803c5..bb3e44eb 100644 --- a/0.1/tiny_httpd/Tiny_httpd/Headers/index.html +++ b/0.1/tiny_httpd/Tiny_httpd/Headers/index.html @@ -1,2 +1,2 @@ -Headers (tiny_httpd.Tiny_httpd.Headers)

Module Tiny_httpd.Headers

type t = (string * string) list
val get : string -> t -> string option
val set : string -> string -> t -> t
val contains : string -> t -> bool
val pp : Format.formatter -> t -> unit
\ No newline at end of file +Headers (tiny_httpd.Tiny_httpd.Headers)

Module Tiny_httpd.Headers

type t = (string * string) list

The header files of a request or response.

Neither the key nor the value can contain '\r' or '\n'. See https://tools.ietf.org/html/rfc7230#section-3.2

val get : ?⁠f:(string -> string) -> string -> t -> string option

get k headers looks for the header field with key k.

parameter f

if provided, will transform the value before it is returned.

val set : string -> string -> t -> t

set k v headers sets the key k to value v. It erases any previous entry for k

val remove : string -> t -> t

Remove the key from the headers, if present.

val contains : string -> t -> bool

Is there a header with the given key?

val pp : Format.formatter -> t -> unit

Pretty print the headers.

\ No newline at end of file diff --git a/0.1/tiny_httpd/Tiny_httpd/Meth/index.html b/0.1/tiny_httpd/Tiny_httpd/Meth/index.html index fb422a01..4a4b71ac 100644 --- a/0.1/tiny_httpd/Tiny_httpd/Meth/index.html +++ b/0.1/tiny_httpd/Tiny_httpd/Meth/index.html @@ -1,2 +1,2 @@ -Meth (tiny_httpd.Tiny_httpd.Meth)

Module Tiny_httpd.Meth

type t = [
| `GET
| `PUT
| `POST
| `HEAD
| `DELETE
]
val pp : Format.formatter -> t -> unit
val to_string : t -> string
\ No newline at end of file +Meth (tiny_httpd.Tiny_httpd.Meth)

Module Tiny_httpd.Meth

type t = [
| `GET
| `PUT
| `POST
| `HEAD
| `DELETE
]

A HTTP method. For now we only handle a subset of these.

See https://tools.ietf.org/html/rfc7231#section-4

val pp : Format.formatter -> t -> unit
val to_string : t -> string
\ No newline at end of file diff --git a/0.1/tiny_httpd/Tiny_httpd/Request/index.html b/0.1/tiny_httpd/Tiny_httpd/Request/index.html index 307dcb70..83a3b41a 100644 --- a/0.1/tiny_httpd/Tiny_httpd/Request/index.html +++ b/0.1/tiny_httpd/Tiny_httpd/Request/index.html @@ -1,2 +1,2 @@ -Request (tiny_httpd.Tiny_httpd.Request)

Module Tiny_httpd.Request

type 'body t = {
meth : Meth.t;
headers : Headers.t;
path : string;
body : 'body;
}
val pp : Format.formatter -> string t -> unit
val headers : _ t -> Headers.t
val get_header : _ t -> string -> string option
val get_header_int : _ t -> string -> int option
val meth : _ t -> Meth.t
val path : _ t -> string
val body : 'b t -> 'b
\ No newline at end of file +Request (tiny_httpd.Tiny_httpd.Request)

Module Tiny_httpd.Request

HTTP request

A request sent by a client.

type 'body t = {
meth : Meth.t;
headers : Headers.t;
path : string;
body : 'body;
}

A request with method, path, headers, and a body.

The body is polymorphic because the request goes through several transformations. First it has no body, as only the request and headers are read; then it has a stream body; then the body might be entirely read as a string via read_body_full.

val pp : Format.formatter -> string t -> unit

Pretty print the request and its body

val pp_ : Format.formatter -> _ t -> unit

Pretty print the request without its body

val headers : _ t -> Headers.t
val get_header : ?⁠f:(string -> string) -> _ t -> string -> string option
val get_header_int : _ t -> string -> int option
val set_header : 'a t -> string -> string -> 'a t
val meth : _ t -> Meth.t
val path : _ t -> string
val body : 'b t -> 'b
val read_body_full : stream t -> string t

Read the whole body into a string. Potentially blocking.

\ No newline at end of file diff --git a/0.1/tiny_httpd/Tiny_httpd/Response/index.html b/0.1/tiny_httpd/Tiny_httpd/Response/index.html index 16d1ea9f..e44ad001 100644 --- a/0.1/tiny_httpd/Tiny_httpd/Response/index.html +++ b/0.1/tiny_httpd/Tiny_httpd/Response/index.html @@ -1,2 +1,2 @@ -Response (tiny_httpd.Tiny_httpd.Response)

Module Tiny_httpd.Response

type out_stream = bytes -> int -> int -> int
type t
val make_raw : ?⁠headers:Headers.t -> code:Response_code.t -> string -> t
val make_raw_chunked : ?⁠headers:Headers.t -> code:Response_code.t -> out_stream -> t
val make : ?⁠headers:Headers.t -> (string, Response_code.t * string) Pervasives.result -> t
val fail : ?⁠headers:Headers.t -> code:int -> ('a, unit, string, t) Pervasives.format4 -> 'a

Make the current request fail with the given code and message. Example: fail ~code:404 "oh noes, %s not found" "waldo"

val fail_raise : code:int -> ('a, unit, string, 'b) Pervasives.format4 -> 'a

Similar to fail but raises an exception that exits the current handler. This should not be used outside of a (path) handler. Example: fail_raise ~code:404 "oh noes, %s not found" "waldo"; never_executed()

val pp : Format.formatter -> t -> unit
\ No newline at end of file +Response (tiny_httpd.Tiny_httpd.Response)

Module Tiny_httpd.Response

Response

A response sent back to a client.

type body = [
| `String of string
| `Stream of stream
]

Body of a response, either as a simple string, or a stream of bytes.

type t = {
code : Response_code.t;

HTTP response code. See Response_code.

headers : Headers.t;

Headers of the reply. Some will be set by Tiny_httpd automatically.

body : body;

Body of the response. Can be empty.

}

A response.

val make_raw : ?⁠headers:Headers.t -> code:Response_code.t -> string -> t

Make a response from its raw components, with a string body. Use "" to not send a body at all.

val make_raw_stream : ?⁠headers:Headers.t -> code:Response_code.t -> stream -> t

Same as make_raw but with a stream body. The body will be sent with the chunked transfer-encoding.

val make : ?⁠headers:Headers.t -> (bodyResponse_code.t * string) Pervasives.result -> t

make r turns a result into a response.

  • make (Ok body) replies with 200 and the body.
  • make (Error (code,msg)) replies with the given error code and message as body.
val make_string : ?⁠headers:Headers.t -> (string, Response_code.t * string) Pervasives.result -> t

Same as make but with a string body.

val make_stream : ?⁠headers:Headers.t -> (streamResponse_code.t * string) Pervasives.result -> t

Same as make but with a stream body.

val fail : ?⁠headers:Headers.t -> code:int -> ('a, unit, string, t) Pervasives.format4 -> 'a

Make the current request fail with the given code and message. Example: fail ~code:404 "oh noes, %s not found" "waldo".

val fail_raise : code:int -> ('a, unit, string, 'b) Pervasives.format4 -> 'a

Similar to fail but raises an exception that exits the current handler. This should not be used outside of a (path) handler. Example: fail_raise ~code:404 "oh noes, %s not found" "waldo"; never_executed()

val pp : Format.formatter -> t -> unit

Pretty print the response.

\ No newline at end of file diff --git a/0.1/tiny_httpd/Tiny_httpd/Response_code/index.html b/0.1/tiny_httpd/Tiny_httpd/Response_code/index.html index 72f5c14b..672f636b 100644 --- a/0.1/tiny_httpd/Tiny_httpd/Response_code/index.html +++ b/0.1/tiny_httpd/Tiny_httpd/Response_code/index.html @@ -1,2 +1,2 @@ -Response_code (tiny_httpd.Tiny_httpd.Response_code)

Module Tiny_httpd.Response_code

type t = int
val descr : t -> string
\ No newline at end of file +Response_code (tiny_httpd.Tiny_httpd.Response_code)

Module Tiny_httpd.Response_code

Response code

type t = int

A standard HTTP code.

https://tools.ietf.org/html/rfc7231#section-6

val ok : t

The code 200

val not_found : t

The code 404

val descr : t -> string

A description of some of the error codes. NOTE: this is not complete (yet).

\ No newline at end of file diff --git a/0.1/tiny_httpd/Tiny_httpd/Stream_/index.html b/0.1/tiny_httpd/Tiny_httpd/Stream_/index.html new file mode 100644 index 00000000..2a42071e --- /dev/null +++ b/0.1/tiny_httpd/Tiny_httpd/Stream_/index.html @@ -0,0 +1,2 @@ + +Stream_ (tiny_httpd.Tiny_httpd.Stream_)

Module Tiny_httpd.Stream_

Generic stream of data

Streams are used to represent a series of bytes that can arrive progressively. For example, an uploaded file will be sent as a series of chunks.

type t = stream
val close : t -> unit
val of_chan : Pervasives.in_channel -> t

Make a buffered stream from the given channel.

val of_chan_close_noerr : Pervasives.in_channel -> t

Same as of_chan but the close method will never fail.

val of_bytes : ?⁠i:int -> ?⁠len:int -> bytes -> t

A stream that just returns the slice of bytes starting from i and of length len.

val with_file : string -> (t -> 'a) -> 'a

Open a file with given name, and obtain an input stream on its content. When the function returns, the stream (and file) are closed.

val read_line : ?⁠buf:Buf_.t -> t -> string

Read a line from the stream.

parameter buf

a buffer to (re)use. Its content will be cleared.

val read_all : ?⁠buf:Buf_.t -> t -> string

Read the whole stream into a string.

parameter buf

a buffer to (re)use. Its content will be cleared.

\ No newline at end of file diff --git a/0.1/tiny_httpd/Tiny_httpd/index.html b/0.1/tiny_httpd/Tiny_httpd/index.html index b49eb715..5a468e7d 100644 --- a/0.1/tiny_httpd/Tiny_httpd/index.html +++ b/0.1/tiny_httpd/Tiny_httpd/index.html @@ -1,2 +1,2 @@ -Tiny_httpd (tiny_httpd.Tiny_httpd)

Module Tiny_httpd

module Meth : sig ... end
module Headers : sig ... end
module Request : sig ... end
module Response_code : sig ... end
module Response : sig ... end
type t
val create : ?⁠masksigpipe:bool -> ?⁠fork:((unit -> unit) -> unit) -> ?⁠addr:string -> ?⁠port:int -> unit -> t
val addr : t -> string
val port : t -> int
val add_decode_request_cb : t -> (string Request.t -> string Request.t option) -> unit

Add a callback for every request. The callback can modify the request by returning Some r' where r' is the new request, or just perform side effects (logging?) and return None.

val add_encode_response_cb : t -> (string Request.t -> Response.t -> Response.t option) -> unit

Add a callback for every request/response pair. Similarly to add_encode_response_cb the callback can return a new response, for example to compress it.

val set_top_handler : t -> (string Request.t -> Response.t) -> unit

Setup a handler called by default. If not installed, unhandled paths will return a 404 not found.

val add_path_handler : ?⁠accept:(unit Request.t -> (unit, Response_code.t * string) Pervasives.result) -> ?⁠meth:Meth.t -> t -> ('a, Scanf.Scanning.in_channel, 'b'c -> string Request.t -> Response.t'a -> 'd'd) Pervasives.format6 -> 'c -> unit

add_path_handler server "/some/path/%s@/%d/" f calls f request "foo" 42 () when a request with path "some/path/foo/42/" is received. This uses Scanf's splitting, which has some gotchas (in particular, "%s" is eager, so it's generally necessary to delimit its scope with a "@/" delimiter. The "@" before a character indicates it's a separator.

parameter meth

if provided, only accept requests with the given method

parameter accept

should return true if the given request (before its body is read) should be accepted, false if it's to be rejected (e.g. because its content is too big, or for some permission error).

val stop : t -> unit
val run : t -> (unit, exn) Pervasives.result
\ No newline at end of file +Tiny_httpd (tiny_httpd.Tiny_httpd)

Module Tiny_httpd

Tiny Http Server

This library implements a very simple, basic HTTP/1.1 server using blocking IOs and threads. Basic routing based on Scanf is provided for convenience, so that several handlers can be registered.

It is possible to use a thread pool, see create's argument new_thread.

type stream = {
is_fill_buf : unit -> bytes * int * int;

See the current slice of the internal buffer as bytes, i, len, where the slice is bytes[i] .. [bytes[i+len-1]]. Can block to refill the buffer if there is currently no content. If len=0 then there is no more data.

is_consume : int -> unit;

Consume n bytes from the buffer. This should only be called with n <= len after a call to is_fill_buf that returns a slice of length len.

is_close : unit -> unit;

Close the stream.

}

A buffered stream, with a view into the current buffer (or refill if empty), and a function to consume n bytes. See Buf_ for more details.

module Buf_ : sig ... end
module Stream_ : sig ... end
module Meth : sig ... end
module Headers : sig ... end
module Request : sig ... end
module Response_code : sig ... end
module Response : sig ... end
type t

A HTTP server. See create for more details.

val create : ?⁠masksigpipe:bool -> ?⁠new_thread:((unit -> unit) -> unit) -> ?⁠addr:string -> ?⁠port:int -> unit -> t

Create a new webserver.

The server will not do anything until run is called on it. Before starting the server, one can use add_path_handler and set_top_handler to specify how to handle incoming requests.

parameter masksigpipe

if true, block the signal Sys.sigpipe which otherwise tends to kill client threads when they try to write on broken sockets. Default: true.

parameter new_thread

a function used to spawn a new thread to handle a new client connection. By default it is Thread.create but one could use a thread pool instead.

parameter addr

the address (IPv4) to listen on. Default "127.0.0.1".

parameter port

to listen on. Default 8080.

val addr : t -> string

Address on which the server listen.

val port : t -> int

Port on which the server listen.

val add_decode_request_cb : t -> (unit Request.t -> (unit Request.t * (stream -> stream)) option) -> unit

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 Transfer-Encoding header and returning a stream transformer that decompresses on the fly.

val add_encode_response_cb : t -> (string Request.t -> Response.t -> Response.t option) -> unit

Add a callback for every request/response pair. Similarly to add_encode_response_cb the callback can return a new response, for example to compress it. The callback is given the fully parsed query as well as the current response.

val set_top_handler : t -> (string Request.t -> Response.t) -> unit

Setup a handler called by default.

This handler is called with any request not accepted by any handler installed via add_path_handler. If no top handler is installed, unhandled paths will return a 404 not found.

val add_path_handler : ?⁠accept:(unit Request.t -> (unit, Response_code.t * string) Pervasives.result) -> ?⁠meth:Meth.t -> t -> ('a, Scanf.Scanning.in_channel, 'b'c -> string Request.t -> Response.t'a -> 'd'd) Pervasives.format6 -> 'c -> unit

add_path_handler server "/some/path/%s@/%d/" f calls f request "foo" 42 () when a request with path "some/path/foo/42/" is received.

This uses Scanf's splitting, which has some gotchas (in particular, "%s" is eager, so it's generally necessary to delimit its scope with a "@/" delimiter. The "@" before a character indicates it's a separator.

Note that the handlers are called in the reverse order of their addition, so the last registered handler can override previously registered ones.

parameter meth

if provided, only accept requests with the given method. Typically one could react to `GET or `PUT.

parameter accept

should return Ok() if the given request (before its body is read) should be accepted, Error (code,message) if it's to be rejected (e.g. because its content is too big, or for some permission error). See the http_of_dir program for an example of how to use accept to filter uploads that are too large before the upload even starts.

val stop : t -> unit

Ask the server to stop. This might not have an immediate effect as run might currently be waiting on IO.

val run : t -> (unit, exn) Pervasives.result

Run the main loop of the server, listening on a socket described at the server's creation time, using new_thread to start a thread for each new client.

This returns Ok () if the server exits gracefully, or Error e if it exits with an error.

\ No newline at end of file