package devkit
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=222f8ac131b1d970dab7eeb2714bfd6b9338b88b1082e6e01c136ae19e7eaef4
sha512=c9e6d93e3d21e5530c0f4d5baca51bf1f0a5d19248f8af7678d0665bb5cdf295d7aaaaa3e50eb2e44b8720e55097cc675af4dc8ec45acf9da39feb3eae1405d5
doc/devkit.core/Devkit_core/Httpev/index.html
Module Devkit_core.Httpev
Source
Very simple and incomplete HTTP server
Server
type config = {
connection : Unix.sockaddr;
backlog : int;
log_epipe : bool;
mutable debug : bool;
(*more logging
*)events : Ev.event_base;
access_log : out_channel ref;
access_log_enabled : bool;
name : string;
max_request_size : int;
auth : (string * string * string) option;
max_clients : int;
(*limit on total number of requests in processing at any point of time
*)max_data_childs : int;
max_data_waiting : int;
yield : bool;
(*do
*)Lwt_unix.yield ()
after accepting connection to give other lwt threads chance to run (set totrue
when http requests processing causes other threads to stuck)single : bool;
(*only process one request at a time (intended for preforked workers)
*)exit_thread : unit Lwt.t option;
(*if set, stop accepting connections as soon as exit_thread terminates (defaults to
*)Daemon.should_exit_lwt
)reuseport : bool;
nodelay : bool;
strict_args : bool;
(*default false, if enabled - will in particular fail on "/path?arg1&arg2", why would anyone want that?
*)max_time : max_time;
cors_allow_all : bool;
on_recv_timeout : [ `Reply_bad_request | `Drop_connection ];
(*what to do on receive timeout,
*)`Reply_bad_request
by default
}
server configuration
include module type of struct include Httpev_common end
type request = Httpev_common.request = {
addr : Unix.sockaddr;
url : string;
path : string;
args : (string * string) list;
conn : Time.t;
recv : Time.t;
meth : meth;
headers : (string * string) list;
body : string;
version : int * int;
id : int;
socket : Unix.file_descr;
line : string;
(*request line
*)mutable blocking : unit IO.output option;
encoding : encoding;
}
type reply_status = [
| `Ok
| `Created
| `Accepted
| `No_content
| `Found
| `Moved
| `Bad_request
| `Payment_required
| `Forbidden
| `Not_found
| `Method_not_allowed
| `Not_acceptable
| `Conflict
| `Length_required
| `Request_too_large
| `I'm_a_teapot
| `Unprocessable_content
| `Too_many_requests
| `Internal_server_error
| `Not_implemented
| `Version_not_supported
| `Custom of string
]
val method_of_string :
string ->
[> `DELETE | `GET | `HEAD | `OPTIONS | `PATCH | `POST | `PUT ]
type partial_body = {
line1 : string;
content_length : int option;
parsed_headers : (string * string) list;
buf : ExtLib.Buffer.t;
}
type request_state =
| Headers of ExtLib.Buffer.t
| Body of partial_body
| Body_lwt of int
| Ready of request
type client = {
fd : Unix.file_descr;
req_id : int;
time_conn : Time.t;
(*time when client connected
*)sockaddr : Unix.sockaddr;
mutable req : request_state;
server : server;
}
client state
and server = {
listen_socket : Unix.file_descr;
mutable total : int;
mutable active : int;
mutable errors : int;
mutable reject : int;
reqs : (int, request) ExtLib.Hashtbl.t;
clients : (int, client) ExtLib.Hashtbl.t;
config : config;
digest_auth : Digest_auth.t option;
h_childs : (int, unit) ExtLib.Hashtbl.t;
(*currently running forked childs
*)q_wait : (unit -> unit) Stack.t;
(*the stack of requests to fork
*)
}
server state
val write_f :
client ->
(string list ref * int ref) ->
Ev.event ->
Unix.file_descr ->
'a ->
unit
val log_status_apache :
out_channel ->
[< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported ] ->
int ->
request ->
unit
val wait :
Devkit_core.Async.Ev.event_base ->
Unix.file_descr ->
(unit -> unit) ->
Devkit_core.Async.Ev.event
Wait until fd
becomes readable and close it (for eventfd-backed notifications)
val send_reply_async :
client ->
encoding ->
(reply_status * (string * string) list * string) ->
unit
val send_reply_user :
client ->
request ->
([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported ]
* (string * string) list
* string) ->
unit
val handle_request :
client ->
partial_body ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
unit
val process_chunk :
client ->
Ev.event ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
string ->
bool ->
unit
val handle_client :
client ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
unit
val setup_server_fd :
Unix.file_descr ->
config ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
server
val setup_server :
config ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
server
val setup_fd :
Unix.file_descr ->
config ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
unit
val setup :
config ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
unit
val server :
config ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
unit
Utilities
functor version of Param
because somebody thought it is good idea
val run :
?ip:Unix.inet_addr ->
int ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
unit
val run_unix :
string ->
(server ->
request ->
(([< `Accepted
| `Bad_request
| `Conflict
| `Created
| `Custom of string
| `Forbidden
| `Found
| `I'm_a_teapot
| `Internal_server_error
| `Length_required
| `Method_not_allowed
| `Moved
| `No_content
| `No_reply
| `Not_acceptable
| `Not_found
| `Not_implemented
| `Ok
| `Payment_required
| `Request_too_large
| `Service_unavailable
| `Too_many_requests
| `Unauthorized
| `Unprocessable_content
| `Version_not_supported Unauthorized ]
* (string * string) list
* string) ->
unit) ->
unit) ->
unit
Forked workers
Lwt support
val send_reply :
client ->
Lwt_io.output_channel ->
[< `Body of reply_status * (string * string) list * string
| `Chunks of
reply_status
* (string * string) list
* ((string -> unit Lwt.t) ->
unit Lwt.t) ] ->
unit Lwt.t
val handle_lwt :
config ->
Lwt_unix.file_descr ->
((Lwt_unix.file_descr * Lwt_unix.sockaddr) -> unit Lwt.t) ->
unit Lwt.t
val setup_fd_lwt :
Lwt_unix.file_descr ->
config ->
(server ->
request ->
[< `Body of reply_status * (string * string) list * string
| `Chunks of
reply_status
* (string * string) list
* ((string -> unit Lwt.t) ->
unit Lwt.t)
| `No_reply Body No_reply ]
Lwt.t) ->
unit Lwt.t
val setup_lwt :
config ->
(server ->
request ->
[< `Body of reply_status * (string * string) list * string
| `Chunks of
reply_status
* (string * string) list
* ((string -> unit Lwt.t) ->
unit Lwt.t)
| `No_reply Body No_reply ]
Lwt.t) ->
unit Lwt.t
val server_lwt :
config ->
(server ->
request ->
[< `Body of reply_status * (string * string) list * string
| `Chunks of
reply_status
* (string * string) list
* ((string -> unit Lwt.t) ->
unit Lwt.t)
| `No_reply Body No_reply ]
Lwt.t) ->
unit