-
Notifications
You must be signed in to change notification settings - Fork 170
/
s.ml
199 lines (165 loc) · 6.42 KB
/
s.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
(** Portable Lwt implementation of HTTP client and server, without
depending on a particular I/O implementation. The various [Make]
functors must be instantiated by an implementation that provides
a concrete IO monad. *)
module type IO = sig
include Cohttp.S.IO with type 'a t = 'a Lwt.t
type error
val catch : (unit -> 'a t) -> ('a, error) result t
(** [catch f] is [f () >|= Result.ok], unless [f] fails with an IO error,
in which case it returns the error. *)
val pp_error : Format.formatter -> error -> unit
end
(** The IO module is specialized for the [Lwt] monad. *)
(** The [Net] module type defines how to connect to a remote node
and close the resulting channels to clean up. *)
module type Net = sig
module IO : IO
type ctx [@@deriving sexp_of]
val default_ctx: ctx
val connect_uri : ctx:ctx -> Uri.t -> (IO.conn * IO.ic * IO.oc) Lwt.t
val close_in : IO.ic -> unit
val close_out : IO.oc -> unit
val close : IO.ic -> IO.oc -> unit
end
(** The [Client] module implements non-pipelined single HTTP client
calls. Each call will open a separate {! Net } connection. For
best results, the {! Body } that is returned should be
consumed in order to close the file descriptor in a timely
fashion. It will still be finalized by a GC hook if it is not used
up, but this can take some additional time to happen. *)
module type Client = sig
type ctx [@@deriving sexp_of]
val default_ctx : ctx
(** [call ?ctx ?headers ?body ?chunked meth uri] will resolve the
[uri] to a concrete network endpoint using the resolver initialized
in [ctx]. It will then issue an HTTP request with method [meth],
adding request headers from [headers] if present. If a [body]
is specified then that will be included with the request, using
chunked encoding if [chunked] is true. The default is to disable
chunked encoding for HTTP request bodies for compatibility reasons.
In most cases you should use the more specific helper calls in the
interface rather than invoke this function directly. See {!head},
{!get} and {!post} for some examples. *)
val call :
?ctx:ctx ->
?headers:Cohttp.Header.t ->
?body:Body.t ->
?chunked:bool ->
Cohttp.Code.meth ->
Uri.t -> (Cohttp.Response.t * Body.t) Lwt.t
val head :
?ctx:ctx ->
?headers:Cohttp.Header.t ->
Uri.t -> Cohttp.Response.t Lwt.t
val get :
?ctx:ctx ->
?headers:Cohttp.Header.t ->
Uri.t -> (Cohttp.Response.t * Body.t) Lwt.t
val delete :
?ctx:ctx ->
?body:Body.t ->
?chunked:bool ->
?headers:Cohttp.Header.t ->
Uri.t -> (Cohttp.Response.t * Body.t) Lwt.t
val post :
?ctx:ctx ->
?body:Body.t ->
?chunked:bool ->
?headers:Cohttp.Header.t ->
Uri.t -> (Cohttp.Response.t * Body.t) Lwt.t
val put :
?ctx:ctx ->
?body:Body.t ->
?chunked:bool ->
?headers:Cohttp.Header.t ->
Uri.t -> (Cohttp.Response.t * Body.t) Lwt.t
val patch :
?ctx:ctx ->
?body:Body.t ->
?chunked:bool ->
?headers:Cohttp.Header.t ->
Uri.t -> (Cohttp.Response.t * Body.t) Lwt.t
val post_form :
?ctx:ctx ->
?headers:Cohttp.Header.t ->
params:(string * string list) list ->
Uri.t -> (Cohttp.Response.t * Body.t) Lwt.t
val callv :
?ctx:ctx ->
Uri.t ->
(Cohttp.Request.t * Body.t) Lwt_stream.t ->
(Cohttp.Response.t * Body.t) Lwt_stream.t Lwt.t
end
(** The [Server] module implements a pipelined HTTP/1.1 server. *)
module type Server = sig
module IO : IO
type conn = IO.conn * Cohttp.Connection.t
(** A request handler can respond in two ways:
- Using [`Response], with a {!Response.t} and a {!Body.t}.
- Using [`Expert], with a {!Response.t} and an IO function that is
expected to write the response body. The IO function has access to the
underlying {!IO.ic} and {!IO.oc}, which allows writing a response body
more efficiently, stream a response or to switch protocols entirely
(e.g. websockets). Processing of pipelined requests continue after the
{!unit Lwt.t} is resolved. The connection can be closed by closing the
{!IO.ic}. *)
type response_action =
[ `Expert of Cohttp.Response.t
* (IO.ic
-> IO.oc
-> unit Lwt.t)
| `Response of Cohttp.Response.t * Body.t ]
type t
val make_response_action :
?conn_closed:(conn -> unit) ->
callback:(conn -> Cohttp.Request.t -> Body.t ->
response_action Lwt.t) ->
unit ->
t
val make_expert :
?conn_closed:(conn -> unit) ->
callback:(conn -> Cohttp.Request.t -> Body.t ->
(Cohttp.Response.t * (IO.ic -> IO.oc -> unit Lwt.t)) Lwt.t) ->
unit ->
t
val make :
?conn_closed:(conn -> unit) ->
callback:(conn -> Cohttp.Request.t -> Body.t ->
(Cohttp.Response.t * Body.t) Lwt.t) ->
unit ->
t
(** Resolve a URI and a docroot into a concrete local filename. *)
val resolve_local_file : docroot:string -> uri:Uri.t -> string
(** [respond ?headers ?flush ~status ~body] will respond to an HTTP
request with the given [status] code and response [body]. If
[flush] is true, then every response chunk will be flushed to
the network rather than being buffered. [flush] is true by default.
The transfer encoding will be detected from the [body] value and
set to chunked encoding if it cannot be determined immediately.
You can override the encoding by supplying an appropriate [Content-length]
or [Transfer-encoding] in the [headers] parameter. *)
val respond :
?headers:Cohttp.Header.t ->
?flush:bool ->
status:Cohttp.Code.status_code ->
body:Body.t -> unit -> (Cohttp.Response.t * Body.t) Lwt.t
val respond_string :
?flush:bool ->
?headers:Cohttp.Header.t ->
status:Cohttp.Code.status_code ->
body:string -> unit -> (Cohttp.Response.t * Body.t) Lwt.t
val respond_error :
?headers:Cohttp.Header.t ->
?status:Cohttp.Code.status_code ->
body:string -> unit -> (Cohttp.Response.t * Body.t) Lwt.t
val respond_redirect :
?headers:Cohttp.Header.t ->
uri:Uri.t -> unit -> (Cohttp.Response.t * Body.t) Lwt.t
val respond_need_auth :
?headers:Cohttp.Header.t ->
auth:Cohttp.Auth.challenge -> unit -> (Cohttp.Response.t * Body.t) Lwt.t
val respond_not_found :
?uri:Uri.t -> unit -> (Cohttp.Response.t * Body.t) Lwt.t
val callback : t -> IO.conn -> IO.ic -> IO.oc -> unit Lwt.t
end