1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4
<link rel="stylesheet" href="style.css" type="text/css">
5
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
6
<link rel="Start" href="index.html">
7
<link rel="previous" href="Nethttpd_kernel.http_response_impl.html">
8
<link rel="next" href="Nethttpd_kernel.lingering_close.html">
9
<link rel="Up" href="Nethttpd_kernel.html">
10
<link title="Index of types" rel=Appendix href="index_types.html">
11
<link title="Index of exceptions" rel=Appendix href="index_exceptions.html">
12
<link title="Index of values" rel=Appendix href="index_values.html">
13
<link title="Index of class attributes" rel=Appendix href="index_attributes.html">
14
<link title="Index of class methods" rel=Appendix href="index_methods.html">
15
<link title="Index of classes" rel=Appendix href="index_classes.html">
16
<link title="Index of class types" rel=Appendix href="index_class_types.html">
17
<link title="Index of modules" rel=Appendix href="index_modules.html">
18
<link title="Index of module types" rel=Appendix href="index_module_types.html">
19
<link title="Uq_gtk" rel="Chapter" href="Uq_gtk.html">
20
<link title="Equeue" rel="Chapter" href="Equeue.html">
21
<link title="Unixqueue" rel="Chapter" href="Unixqueue.html">
22
<link title="Uq_engines" rel="Chapter" href="Uq_engines.html">
23
<link title="Uq_socks5" rel="Chapter" href="Uq_socks5.html">
24
<link title="Unixqueue_mt" rel="Chapter" href="Unixqueue_mt.html">
25
<link title="Equeue_intro" rel="Chapter" href="Equeue_intro.html">
26
<link title="Uq_ssl" rel="Chapter" href="Uq_ssl.html">
27
<link title="Uq_tcl" rel="Chapter" href="Uq_tcl.html">
28
<link title="Netcgi_common" rel="Chapter" href="Netcgi_common.html">
29
<link title="Netcgi" rel="Chapter" href="Netcgi.html">
30
<link title="Netcgi_ajp" rel="Chapter" href="Netcgi_ajp.html">
31
<link title="Netcgi_scgi" rel="Chapter" href="Netcgi_scgi.html">
32
<link title="Netcgi_cgi" rel="Chapter" href="Netcgi_cgi.html">
33
<link title="Netcgi_fcgi" rel="Chapter" href="Netcgi_fcgi.html">
34
<link title="Netcgi_dbi" rel="Chapter" href="Netcgi_dbi.html">
35
<link title="Netcgi1_compat" rel="Chapter" href="Netcgi1_compat.html">
36
<link title="Netcgi_test" rel="Chapter" href="Netcgi_test.html">
37
<link title="Netcgi_porting" rel="Chapter" href="Netcgi_porting.html">
38
<link title="Netcgi_plex" rel="Chapter" href="Netcgi_plex.html">
39
<link title="Http_client" rel="Chapter" href="Http_client.html">
40
<link title="Telnet_client" rel="Chapter" href="Telnet_client.html">
41
<link title="Ftp_data_endpoint" rel="Chapter" href="Ftp_data_endpoint.html">
42
<link title="Ftp_client" rel="Chapter" href="Ftp_client.html">
43
<link title="Nethttpd_types" rel="Chapter" href="Nethttpd_types.html">
44
<link title="Nethttpd_kernel" rel="Chapter" href="Nethttpd_kernel.html">
45
<link title="Nethttpd_reactor" rel="Chapter" href="Nethttpd_reactor.html">
46
<link title="Nethttpd_engine" rel="Chapter" href="Nethttpd_engine.html">
47
<link title="Nethttpd_services" rel="Chapter" href="Nethttpd_services.html">
48
<link title="Nethttpd_plex" rel="Chapter" href="Nethttpd_plex.html">
49
<link title="Nethttpd_intro" rel="Chapter" href="Nethttpd_intro.html">
50
<link title="Netplex_types" rel="Chapter" href="Netplex_types.html">
51
<link title="Netplex_mp" rel="Chapter" href="Netplex_mp.html">
52
<link title="Netplex_mt" rel="Chapter" href="Netplex_mt.html">
53
<link title="Netplex_log" rel="Chapter" href="Netplex_log.html">
54
<link title="Netplex_controller" rel="Chapter" href="Netplex_controller.html">
55
<link title="Netplex_container" rel="Chapter" href="Netplex_container.html">
56
<link title="Netplex_sockserv" rel="Chapter" href="Netplex_sockserv.html">
57
<link title="Netplex_workload" rel="Chapter" href="Netplex_workload.html">
58
<link title="Netplex_main" rel="Chapter" href="Netplex_main.html">
59
<link title="Netplex_config" rel="Chapter" href="Netplex_config.html">
60
<link title="Netplex_kit" rel="Chapter" href="Netplex_kit.html">
61
<link title="Rpc_netplex" rel="Chapter" href="Rpc_netplex.html">
62
<link title="Netplex_cenv" rel="Chapter" href="Netplex_cenv.html">
63
<link title="Netplex_intro" rel="Chapter" href="Netplex_intro.html">
64
<link title="Netshm" rel="Chapter" href="Netshm.html">
65
<link title="Netshm_data" rel="Chapter" href="Netshm_data.html">
66
<link title="Netshm_hashtbl" rel="Chapter" href="Netshm_hashtbl.html">
67
<link title="Netshm_array" rel="Chapter" href="Netshm_array.html">
68
<link title="Netshm_intro" rel="Chapter" href="Netshm_intro.html">
69
<link title="Netconversion" rel="Chapter" href="Netconversion.html">
70
<link title="Netchannels" rel="Chapter" href="Netchannels.html">
71
<link title="Netstream" rel="Chapter" href="Netstream.html">
72
<link title="Mimestring" rel="Chapter" href="Mimestring.html">
73
<link title="Netmime" rel="Chapter" href="Netmime.html">
74
<link title="Netsendmail" rel="Chapter" href="Netsendmail.html">
75
<link title="Neturl" rel="Chapter" href="Neturl.html">
76
<link title="Netaddress" rel="Chapter" href="Netaddress.html">
77
<link title="Netbuffer" rel="Chapter" href="Netbuffer.html">
78
<link title="Netdate" rel="Chapter" href="Netdate.html">
79
<link title="Netencoding" rel="Chapter" href="Netencoding.html">
80
<link title="Netulex" rel="Chapter" href="Netulex.html">
81
<link title="Netaccel" rel="Chapter" href="Netaccel.html">
82
<link title="Netaccel_link" rel="Chapter" href="Netaccel_link.html">
83
<link title="Nethtml" rel="Chapter" href="Nethtml.html">
84
<link title="Netstring_str" rel="Chapter" href="Netstring_str.html">
85
<link title="Netstring_pcre" rel="Chapter" href="Netstring_pcre.html">
86
<link title="Netstring_mt" rel="Chapter" href="Netstring_mt.html">
87
<link title="Netmappings" rel="Chapter" href="Netmappings.html">
88
<link title="Netaux" rel="Chapter" href="Netaux.html">
89
<link title="Nethttp" rel="Chapter" href="Nethttp.html">
90
<link title="Netchannels_tut" rel="Chapter" href="Netchannels_tut.html">
91
<link title="Netmime_tut" rel="Chapter" href="Netmime_tut.html">
92
<link title="Netsendmail_tut" rel="Chapter" href="Netsendmail_tut.html">
93
<link title="Netulex_tut" rel="Chapter" href="Netulex_tut.html">
94
<link title="Neturl_tut" rel="Chapter" href="Neturl_tut.html">
95
<link title="Netsys" rel="Chapter" href="Netsys.html">
96
<link title="Netpop" rel="Chapter" href="Netpop.html">
97
<link title="Rpc_auth_dh" rel="Chapter" href="Rpc_auth_dh.html">
98
<link title="Rpc_key_service" rel="Chapter" href="Rpc_key_service.html">
99
<link title="Rpc_time" rel="Chapter" href="Rpc_time.html">
100
<link title="Rpc_auth_local" rel="Chapter" href="Rpc_auth_local.html">
101
<link title="Rtypes" rel="Chapter" href="Rtypes.html">
102
<link title="Xdr" rel="Chapter" href="Xdr.html">
103
<link title="Rpc" rel="Chapter" href="Rpc.html">
104
<link title="Rpc_program" rel="Chapter" href="Rpc_program.html">
105
<link title="Rpc_portmapper_aux" rel="Chapter" href="Rpc_portmapper_aux.html">
106
<link title="Rpc_packer" rel="Chapter" href="Rpc_packer.html">
107
<link title="Rpc_transport" rel="Chapter" href="Rpc_transport.html">
108
<link title="Rpc_client" rel="Chapter" href="Rpc_client.html">
109
<link title="Rpc_simple_client" rel="Chapter" href="Rpc_simple_client.html">
110
<link title="Rpc_portmapper_clnt" rel="Chapter" href="Rpc_portmapper_clnt.html">
111
<link title="Rpc_portmapper" rel="Chapter" href="Rpc_portmapper.html">
112
<link title="Rpc_server" rel="Chapter" href="Rpc_server.html">
113
<link title="Rpc_auth_sys" rel="Chapter" href="Rpc_auth_sys.html">
114
<link title="Rpc_intro" rel="Chapter" href="Rpc_intro.html">
115
<link title="Rpc_mapping_ref" rel="Chapter" href="Rpc_mapping_ref.html">
116
<link title="Rpc_ssl" rel="Chapter" href="Rpc_ssl.html">
117
<link title="Rpc_xti_client" rel="Chapter" href="Rpc_xti_client.html">
118
<link title="Shell_sys" rel="Chapter" href="Shell_sys.html">
119
<link title="Shell" rel="Chapter" href="Shell.html">
120
<link title="Shell_uq" rel="Chapter" href="Shell_uq.html">
121
<link title="Shell_mt" rel="Chapter" href="Shell_mt.html">
122
<link title="Shell_intro" rel="Chapter" href="Shell_intro.html">
123
<link title="Netsmtp" rel="Chapter" href="Netsmtp.html"><title>Ocamlnet 2 Reference Manual : Nethttpd_kernel.http_protocol</title>
126
<div class="navbar"><a href="Nethttpd_kernel.http_response_impl.html">Previous</a>
127
<a href="Nethttpd_kernel.html">Up</a>
128
<a href="Nethttpd_kernel.lingering_close.html">Next</a>
130
<center><h1>Class <a href="type_Nethttpd_kernel.http_protocol.html">Nethttpd_kernel.http_protocol</a></h1></center>
132
<pre><span class="keyword">class</span> <a name="TYPEhttp_protocol"></a>http_protocol : <code class="type">#<a href="Nethttpd_kernel.http_protocol_config.html">http_protocol_config</a> -> Unix.file_descr -> </code><code class="code">object</code> <a href="Nethttpd_kernel.http_protocol.html">..</a> <code class="code">end</code></pre>The core event loop of the HTTP daemon<br>
134
<a name="2_ExchangeofHTTPmessages"></a>
135
<h2>Exchange of HTTP messages</h2>
138
In <code class="code">fd</code> one must pass the already connected socket. It must be in non-
142
How to use this class: Basically, one invokes <code class="code">cycle</code> until the whole
143
message exchange on <code class="code">fd</code> is processed. <code class="code">cycle</code> receives data from the
144
socket and sends data to the socket. There are two internal queues:
147
The receive queue stores parts of received requests as <code class="code">req_token</code>.
148
One can take values from the front of this queue by calling <code class="code">receive</code>.
151
The response queue stores <code class="code">http_response</code> objects. Each of the objects
152
corresponds to a request that was received before. This queue is handled
153
fully automatically, but one can watch its length to see whether all responses
154
are actually transmitted over the wire.
157
The basic algorithm to process messages is:
160
<pre><code class="code"> let rec next_token () =
161
if proto # recv_queue_len = 0 then (
168
let cur_token = ref (next_token()) in
169
while !cur_token <> `Eof do
170
(* Process first token of next request: *)
171
match !cur_token with
172
| `Req_header(req_line, header, resp) ->
173
(* Depending on [req_line], read further tokens until [`Req_end] *)
175
(* Switch to the first token of the next message: *)
176
cur_token := next_token()
178
| `Bad_request_error(e,resp) ->
179
(* Generate 400 error, send it to [resp] *)
181
(* Switch to the first token of the next message: *)
182
cur_token := next_token()
183
| `Fatal_error e -> failwith "Crash"
184
| _ -> assert false
186
while proto # resp_queue_len > 0 do
193
See the file <code class="code">tests/easy_daemon.ml</code> for a complete implementation of this.
196
As one can see, it is essential to watch the lengths of the queues in order
197
to figure out what has happened during <code class="code">cycle</code>.
200
When the body of the request is empty, <code class="code">`Req_body</code> tokens are omitted.
201
Note that for requests like <code class="code">GET</code> that always have an empty body, it is
202
still possible that an errorneous client sends a body, and that <code class="code">`Req_body</code>
203
tokens arrive. One must accept and ignore these tokens.
206
Error handling: For serious errors, the connection is immediately aborted.
207
In this case, <code class="code">receive</code> returns a <code class="code">`Fatal_error</code> token. Note that the
208
queued responses cannot be sent! An example of this is <code class="code">`Broken_pipe</code>.
211
There is a large class of non-serious errors, esp. format errors
212
in the header and body. It is typical of these errors that one cannot determine
213
the end of the request properly. For this reason, the daemon stops reading
214
further data from the request, but the response queue is still delivered.
215
For these errors, <code class="code">receive</code> returns a <code class="code">`Bad_request_error</code> token.
216
This token contains a <code class="code">http_response</code> object that must be filled with a
217
400 error response.<pre><span class="keyword">method</span> <a name="METHODcycle"></a>cycle : <code class="type">?block:float -> unit -> unit</code></pre><div class="info">
218
Looks at the file descriptor. If there is data to read from the descriptor,
219
and there is free space in the input buffer, additional data is read into
220
the buffer. It is also tried to interpret the new data as <code class="code">req_token</code>s,
221
and if possible, new <code class="code">req_token</code>s are appended to the receive queue.
224
If the response queue has objects, and there is really data one can send,
225
and if the socket allows one to send data, it is tried to send as much
229
The option <code class="code">block</code> (default: 0) can be set to wait until data
230
can be exchanged with the socket. This avoids busy waiting. The number
231
is the duration in seconds to wait until the connection times out
232
(0 means not to wait at all, -1 means to wait infinitely). When a timeout
233
happens, and there is nothing to send, and the last request was fully
234
processed, <code class="code">receive</code> will simply return <code class="code">`Timeout</code> (i.e. when
235
<code class="code">waiting_for_next_message</code> is <code class="code">true</code>). Otherwise, the
236
fatal error <code class="code">`Timeout</code> is generated.<br>
238
<pre><span class="keyword">method</span> <a name="METHODreceive"></a>receive : <code class="type">unit -> <a href="Nethttpd_kernel.html#TYPEreq_token">req_token</a></code></pre><div class="info">
239
Returns the first <code class="code">req_token</code> from the receive queue. Raises
240
<code class="code">Recv_queue_empty</code> when the queue is empty (= has no new data)<br>
242
<pre><span class="keyword">method</span> <a name="METHODpeek_recv"></a>peek_recv : <code class="type">unit -> <a href="Nethttpd_kernel.html#TYPEreq_token">req_token</a></code></pre><div class="info">
243
Peeks the first token, but leaves it in the queue.
244
Raises <code class="code">Recv_queue_empty</code> when the queue is empty.<br>
246
<pre><span class="keyword">method</span> <a name="METHODrecv_queue_len"></a>recv_queue_len : <code class="type">int</code></pre><div class="info">
247
Returns the length of the receive queue (number of tokens)<br>
249
<pre><span class="keyword">method</span> <a name="METHODresp_queue_len"></a>resp_queue_len : <code class="type">int</code></pre><div class="info">
250
Returns the length of the internal response queue (number of <code class="code">http_response</code>
251
objects that have not yet fully processed)<br>
253
<pre><span class="keyword">method</span> <a name="METHODpipeline_len"></a>pipeline_len : <code class="type">int</code></pre><div class="info">
254
Returns the number of unanswered requests = Number of received <code class="code">`Req_end</code> tokens
255
minus number of responses in state <code class="code">`Processed</code>. Note that <code class="code">pipeline_len</code>
256
can become <code class="code">-1</code> when bad requests are responded.<br>
258
<pre><span class="keyword">method</span> <a name="METHODrecv_queue_byte_size"></a>recv_queue_byte_size : <code class="type">int</code></pre><div class="info">
259
Returns the (estimated) size of the input queue in bytes<br>
261
<pre><span class="keyword">method</span> <a name="METHODwaiting_for_next_message"></a>waiting_for_next_message : <code class="type">bool</code></pre><div class="info">
262
Whether the kernel is currently waiting for the beginning of a new
263
arriving HTTP request. This is <code class="code">false</code> while the request is being
266
<pre><span class="keyword">method</span> <a name="METHODinput_timeout_class"></a>input_timeout_class : <code class="type">[ `Next_message | `None | `Normal ]</code></pre><div class="info">
267
Suggests the calculation of a timeout value for input:<ul>
268
<li><code class="code">`Normal</code>: The normal timeout value applies</li>
269
<li><code class="code">`Next_message</code>: The timeout value applies while waiting for the next message</li>
270
<li><code class="code">`None</code>: The connection is output-driven, no input timeout value</li>
274
<pre><span class="keyword">method</span> <a name="METHODshutdown"></a>shutdown : <code class="type">unit -> unit</code></pre><div class="info">
275
Shuts the socket down. Note: the descriptor is not closed.<br>
277
<pre><span class="keyword">method</span> <a name="METHODtimeout"></a>timeout : <code class="type">unit -> unit</code></pre><div class="info">
278
Process a timeout condition as <code class="code">cycle</code> does<br>
280
<pre><span class="keyword">method</span> <a name="METHODabort"></a>abort : <code class="type"><a href="Nethttpd_kernel.html#TYPEfatal_error">fatal_error</a> -> unit</code></pre><div class="info">
281
Stops the transmission of data. The receive queue is cleared and filled
282
with the two tokens <code class="code">`Fatal_error</code> and <code class="code">`Eof</code>.
283
The response queue is cleared. The <code class="code">cycle</code>
284
method will return immediately without doing anything.<br>
286
<pre><span class="keyword">method</span> <a name="METHODfd"></a>fd : <code class="type">Unix.file_descr</code></pre><div class="info">
287
Just returns the socket<br>
289
<pre><span class="keyword">method</span> <a name="METHODdo_input"></a>do_input : <code class="type">bool</code></pre><div class="info">
290
Returns <code class="code">true</code> iff the protocol engine is interested in new data from the
291
socket. Returns <code class="code">false</code> after EOF and after errors.<br>
293
<pre><span class="keyword">method</span> <a name="METHODdo_output"></a>do_output : <code class="type">bool</code></pre><div class="info">
294
Returns <code class="code">true</code> iff the protocol engine has data to output to the socket<br>
296
<pre><span class="keyword">method</span> <a name="METHODneed_linger"></a>need_linger : <code class="type">bool</code></pre><div class="info">
297
Returns <code class="code">true</code> when a lingering close operation is needed to reliably shut
298
down the socket. In many cases, this expensive operation is not necessary.
299
See the class <code class="code">lingering_close</code> below.<br>
301
<pre><span class="keyword">method</span> <a name="METHODconfig"></a>config : <code class="type"><a href="Nethttpd_kernel.http_protocol_config.html">http_protocol_config</a></code></pre><div class="info">
302
Just returns the configuration<br>
304
<pre><span class="keyword">method</span> <a name="METHODtest_coverage"></a>test_coverage : <code class="type">string list</code></pre><div class="info">
305
For testing: returns a list of tokens indicating into which cases the program
b'\\ No newline at end of file'