package devkit
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=222f8ac131b1d970dab7eeb2714bfd6b9338b88b1082e6e01c136ae19e7eaef4
sha512=c9e6d93e3d21e5530c0f4d5baca51bf1f0a5d19248f8af7678d0665bb5cdf295d7aaaaa3e50eb2e44b8720e55097cc675af4dc8ec45acf9da39feb3eae1405d5
doc/devkit.core/Devkit_core/Httpev/index.html
Module Devkit_core.HttpevSource
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 totruewhen 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_requestby 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 ->
unitval 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 ->
unitval wait :
Devkit_core.Async.Ev.event_base ->
Unix.file_descr ->
(unit -> unit) ->
Devkit_core.Async.Ev.eventWait until fd becomes readable and close it (for eventfd-backed notifications)
val send_reply_async :
client ->
encoding ->
(reply_status * (string * string) list * string) ->
unitval 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) ->
unitval 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) ->
unitval 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 ->
unitval 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) ->
unitval 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) ->
serverval 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) ->
serverval 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) ->
unitval 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) ->
unitval 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) ->
unitUtilities
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) ->
unitval 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) ->
unitForked 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.tval handle_lwt :
config ->
Lwt_unix.file_descr ->
((Lwt_unix.file_descr * Lwt_unix.sockaddr) -> unit Lwt.t) ->
unit Lwt.tval 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.tval 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.tval 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