File: Nethttpd_intro.html

package info (click to toggle)
ocamlnet 2.2.9-8
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 17,724 kB
  • ctags: 10,053
  • sloc: ml: 63,928; ansic: 1,973; makefile: 800; sh: 651
file content (369 lines) | stat: -rw-r--r-- 18,343 bytes parent folder | download | duplicates (2)
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
<link rel="Start" href="index.html">
<link rel="previous" href="Nethttpd_plex.html">
<link rel="next" href="Netplex_types.html">
<link rel="Up" href="index.html">
<link title="Index of types" rel=Appendix href="index_types.html">
<link title="Index of exceptions" rel=Appendix href="index_exceptions.html">
<link title="Index of values" rel=Appendix href="index_values.html">
<link title="Index of class attributes" rel=Appendix href="index_attributes.html">
<link title="Index of class methods" rel=Appendix href="index_methods.html">
<link title="Index of classes" rel=Appendix href="index_classes.html">
<link title="Index of class types" rel=Appendix href="index_class_types.html">
<link title="Index of modules" rel=Appendix href="index_modules.html">
<link title="Index of module types" rel=Appendix href="index_module_types.html">
<link title="Uq_gtk" rel="Chapter" href="Uq_gtk.html">
<link title="Equeue" rel="Chapter" href="Equeue.html">
<link title="Unixqueue" rel="Chapter" href="Unixqueue.html">
<link title="Uq_engines" rel="Chapter" href="Uq_engines.html">
<link title="Uq_socks5" rel="Chapter" href="Uq_socks5.html">
<link title="Unixqueue_mt" rel="Chapter" href="Unixqueue_mt.html">
<link title="Equeue_intro" rel="Chapter" href="Equeue_intro.html">
<link title="Uq_ssl" rel="Chapter" href="Uq_ssl.html">
<link title="Uq_tcl" rel="Chapter" href="Uq_tcl.html">
<link title="Netcgi_common" rel="Chapter" href="Netcgi_common.html">
<link title="Netcgi" rel="Chapter" href="Netcgi.html">
<link title="Netcgi_ajp" rel="Chapter" href="Netcgi_ajp.html">
<link title="Netcgi_scgi" rel="Chapter" href="Netcgi_scgi.html">
<link title="Netcgi_cgi" rel="Chapter" href="Netcgi_cgi.html">
<link title="Netcgi_fcgi" rel="Chapter" href="Netcgi_fcgi.html">
<link title="Netcgi_dbi" rel="Chapter" href="Netcgi_dbi.html">
<link title="Netcgi1_compat" rel="Chapter" href="Netcgi1_compat.html">
<link title="Netcgi_test" rel="Chapter" href="Netcgi_test.html">
<link title="Netcgi_porting" rel="Chapter" href="Netcgi_porting.html">
<link title="Netcgi_plex" rel="Chapter" href="Netcgi_plex.html">
<link title="Http_client" rel="Chapter" href="Http_client.html">
<link title="Telnet_client" rel="Chapter" href="Telnet_client.html">
<link title="Ftp_data_endpoint" rel="Chapter" href="Ftp_data_endpoint.html">
<link title="Ftp_client" rel="Chapter" href="Ftp_client.html">
<link title="Nethttpd_types" rel="Chapter" href="Nethttpd_types.html">
<link title="Nethttpd_kernel" rel="Chapter" href="Nethttpd_kernel.html">
<link title="Nethttpd_reactor" rel="Chapter" href="Nethttpd_reactor.html">
<link title="Nethttpd_engine" rel="Chapter" href="Nethttpd_engine.html">
<link title="Nethttpd_services" rel="Chapter" href="Nethttpd_services.html">
<link title="Nethttpd_plex" rel="Chapter" href="Nethttpd_plex.html">
<link title="Nethttpd_intro" rel="Chapter" href="Nethttpd_intro.html">
<link title="Netplex_types" rel="Chapter" href="Netplex_types.html">
<link title="Netplex_mp" rel="Chapter" href="Netplex_mp.html">
<link title="Netplex_mt" rel="Chapter" href="Netplex_mt.html">
<link title="Netplex_log" rel="Chapter" href="Netplex_log.html">
<link title="Netplex_controller" rel="Chapter" href="Netplex_controller.html">
<link title="Netplex_container" rel="Chapter" href="Netplex_container.html">
<link title="Netplex_sockserv" rel="Chapter" href="Netplex_sockserv.html">
<link title="Netplex_workload" rel="Chapter" href="Netplex_workload.html">
<link title="Netplex_main" rel="Chapter" href="Netplex_main.html">
<link title="Netplex_config" rel="Chapter" href="Netplex_config.html">
<link title="Netplex_kit" rel="Chapter" href="Netplex_kit.html">
<link title="Rpc_netplex" rel="Chapter" href="Rpc_netplex.html">
<link title="Netplex_cenv" rel="Chapter" href="Netplex_cenv.html">
<link title="Netplex_intro" rel="Chapter" href="Netplex_intro.html">
<link title="Netshm" rel="Chapter" href="Netshm.html">
<link title="Netshm_data" rel="Chapter" href="Netshm_data.html">
<link title="Netshm_hashtbl" rel="Chapter" href="Netshm_hashtbl.html">
<link title="Netshm_array" rel="Chapter" href="Netshm_array.html">
<link title="Netshm_intro" rel="Chapter" href="Netshm_intro.html">
<link title="Netconversion" rel="Chapter" href="Netconversion.html">
<link title="Netchannels" rel="Chapter" href="Netchannels.html">
<link title="Netstream" rel="Chapter" href="Netstream.html">
<link title="Mimestring" rel="Chapter" href="Mimestring.html">
<link title="Netmime" rel="Chapter" href="Netmime.html">
<link title="Netsendmail" rel="Chapter" href="Netsendmail.html">
<link title="Neturl" rel="Chapter" href="Neturl.html">
<link title="Netaddress" rel="Chapter" href="Netaddress.html">
<link title="Netbuffer" rel="Chapter" href="Netbuffer.html">
<link title="Netdate" rel="Chapter" href="Netdate.html">
<link title="Netencoding" rel="Chapter" href="Netencoding.html">
<link title="Netulex" rel="Chapter" href="Netulex.html">
<link title="Netaccel" rel="Chapter" href="Netaccel.html">
<link title="Netaccel_link" rel="Chapter" href="Netaccel_link.html">
<link title="Nethtml" rel="Chapter" href="Nethtml.html">
<link title="Netstring_str" rel="Chapter" href="Netstring_str.html">
<link title="Netstring_pcre" rel="Chapter" href="Netstring_pcre.html">
<link title="Netstring_mt" rel="Chapter" href="Netstring_mt.html">
<link title="Netmappings" rel="Chapter" href="Netmappings.html">
<link title="Netaux" rel="Chapter" href="Netaux.html">
<link title="Nethttp" rel="Chapter" href="Nethttp.html">
<link title="Netchannels_tut" rel="Chapter" href="Netchannels_tut.html">
<link title="Netmime_tut" rel="Chapter" href="Netmime_tut.html">
<link title="Netsendmail_tut" rel="Chapter" href="Netsendmail_tut.html">
<link title="Netulex_tut" rel="Chapter" href="Netulex_tut.html">
<link title="Neturl_tut" rel="Chapter" href="Neturl_tut.html">
<link title="Netsys" rel="Chapter" href="Netsys.html">
<link title="Netpop" rel="Chapter" href="Netpop.html">
<link title="Rpc_auth_dh" rel="Chapter" href="Rpc_auth_dh.html">
<link title="Rpc_key_service" rel="Chapter" href="Rpc_key_service.html">
<link title="Rpc_time" rel="Chapter" href="Rpc_time.html">
<link title="Rpc_auth_local" rel="Chapter" href="Rpc_auth_local.html">
<link title="Rtypes" rel="Chapter" href="Rtypes.html">
<link title="Xdr" rel="Chapter" href="Xdr.html">
<link title="Rpc" rel="Chapter" href="Rpc.html">
<link title="Rpc_program" rel="Chapter" href="Rpc_program.html">
<link title="Rpc_portmapper_aux" rel="Chapter" href="Rpc_portmapper_aux.html">
<link title="Rpc_packer" rel="Chapter" href="Rpc_packer.html">
<link title="Rpc_transport" rel="Chapter" href="Rpc_transport.html">
<link title="Rpc_client" rel="Chapter" href="Rpc_client.html">
<link title="Rpc_simple_client" rel="Chapter" href="Rpc_simple_client.html">
<link title="Rpc_portmapper_clnt" rel="Chapter" href="Rpc_portmapper_clnt.html">
<link title="Rpc_portmapper" rel="Chapter" href="Rpc_portmapper.html">
<link title="Rpc_server" rel="Chapter" href="Rpc_server.html">
<link title="Rpc_auth_sys" rel="Chapter" href="Rpc_auth_sys.html">
<link title="Rpc_intro" rel="Chapter" href="Rpc_intro.html">
<link title="Rpc_mapping_ref" rel="Chapter" href="Rpc_mapping_ref.html">
<link title="Rpc_ssl" rel="Chapter" href="Rpc_ssl.html">
<link title="Rpc_xti_client" rel="Chapter" href="Rpc_xti_client.html">
<link title="Shell_sys" rel="Chapter" href="Shell_sys.html">
<link title="Shell" rel="Chapter" href="Shell.html">
<link title="Shell_uq" rel="Chapter" href="Shell_uq.html">
<link title="Shell_mt" rel="Chapter" href="Shell_mt.html">
<link title="Shell_intro" rel="Chapter" href="Shell_intro.html">
<link title="Netsmtp" rel="Chapter" href="Netsmtp.html"><link title="Overview over the HTTP daemon" rel="Section" href="#overview">
<link title="Suggested strategy" rel="Section" href="#2_Suggestedstrategy">
<link title="Configuration" rel="Section" href="#2_Configuration">
<link title="Linking" rel="Section" href="#2_Linking">
<title>Ocamlnet 2 Reference Manual : Nethttpd_intro</title>
</head>
<body>
<div class="navbar"><a href="Nethttpd_plex.html">Previous</a>
&nbsp;<a href="index.html">Up</a>
&nbsp;<a href="Netplex_types.html">Next</a>
</div>
<center><h1>Nethttpd_intro</h1></center>
<br>
<br>
<a name="overview"></a>
<h2>Overview over the HTTP daemon</h2>
<p>

This library implements an HTTP 1.1 server. Because it is a library and not
a stand-alone server like Apache, it can be used in very flexible ways.
The disadvantage is that the user of the library must do more to get
a running program than just configuring the daemon.
<p>

The daemon has five modules:
<p>
<ul>
<li><a href="Nethttpd_types.html"><code class="code">Nethttpd_types</code></a> is just a module with common type definitions used
  by the other modules</li>
<li><a href="Nethttpd_kernel.html"><code class="code">Nethttpd_kernel</code></a> is the implementation of the HTTP protocol. If we
  talk about the "kernel" we mean this module. The kernel has two 
  interface sides: There is the "socket side" and the "message side"
  that are connected by bidirectional data flow.
  The task of the kernel is to decode input received by the socket side
  and to deliver it to a consumer on the message side, and conversely
  to encode input coming in through the message side and to send it
  to the socket. The kernel is a quite low-level module; the socket
  is accessed in a multiplexing-compatible style, and the messages
  are sequences of tokens like "status line", "header", "body chunk"
  and so on. Normally a user of the daemon does not program the kernel
  directly. It is, however, possible to pass certain configuration
  options to the kernel even if an encapsulation is used.</li>
<li><a href="Nethttpd_reactor.html"><code class="code">Nethttpd_reactor</code></a> is an encapsulation of the kernel with a nicer
  interface. An instance of the reactor processes, like the kernel,
  only a single HTTP connection. It is used as follows: The user
  of the reactor pulls the arriving HTTP requests from the reactor,
  processes them, and writes the responses back to the reactor. This
  means that the requests are processed in a strictly sequential
  way. The reactor hides the details of the HTTP protocol. The
  reactor is able to perform socket input and output at the same time,
  i.e. when the response is sent to the client the next request(s) can
  already be read (pipelining). The reactor can be configured such that
  buffering of requests and responses is avoided, even if large
  messages are transferred. As mentioned, the reactor can only
  deal with one connection at the same time. In order to serve
  several connections, one must use multi-threading.</li>
<li><a href="Nethttpd_engine.html"><code class="code">Nethttpd_engine</code></a> is another encapsulation of the kernel. It is
  event-based, and this makes it possible that several instances
  can work at the same time without using multi-threading. The user
  of the engine is called back when the beginning of the next HTTP
  request arrives and at certain other events. The user processes
  the event, and generates the response. 
  The engine is a
  highly efficient implementation of an HTTP server, but there are
  also drawbacks, so user may feel more comfortable with the reactor.
  Especially, the engine needs large buffers for input and output
  (there is an idea to use helper threads to avoid these buffers,
  but this has not been implemented yet). Of course, the engine
  also supports pipelining.</li>
<li><a href="Nethttpd_services.html"><code class="code">Nethttpd_services</code></a> has functions to compose complex service
  functions from simpler ones. In particular, one can configure
  name- or IP-based virtual hosting, one can bind services to
  URLs, and one can define static file serving, directory listings,
  and dynamic services. It is quite easy to turn a Netcgi program
  into a dynamic service for Nethttpd.</li>
</ul>

It is also important to mention what Nethttpd does not include:
<p>
<ul>
<li>There is no function to create the socket, and to accept connections.</li>
</ul>
<ul>
<li>There is no function to manage threads or subprocesses</li>
</ul>

It is hoped to add this functionality later in a generic way (i.e.
not only for Nethttpd).
<p>

<a name="2_Suggestedstrategy"></a>
<h2>Suggested strategy</h2>
<p>

First, look at <a href="Nethttpd_services.html"><code class="code">Nethttpd_services</code></a>. This module allows the user
to define the services of the web server. For example, the following
code defines a single host with an URL space:
<p>

<pre><code class="code">let fs_spec =
  { file_docroot = "/data/docroot";
    file_uri = "/";
    file_suffix_types = [ "txt", "text/plain";
                          "html", "text/html" ];
    file_default_type = "application/octet-stream";
    file_options = [ `Enable_gzip;
                     `Enable_listings simple_listing
                   ]
  }

let srv =
  host_distributor
    [ default_host ~pref_name:"localhost" ~pref_port:8765 (),
      uri_distributor
        [ "*", (options_service());
          "/files", (file_service fs_spec);
          "/service", (dynamic_service
                           { dyn_handler = process_request;
                             dyn_activation = std_activation `Std_activation_buffered;
                             dyn_uri = Some "/service";
                             dyn_translator = file_translator fs_spec;
                             dyn_accept_all_conditionals = false
                           })
        ]
    ]
</code></pre>
<p>

The <code class="code">/files</code> path is bound to a static service, i.e. the files found in
the directory <code class="code">/data/docroot</code> can be accessed over the web. The record
<code class="code">fs_spec</code> configures the static service.
<p>

The <code class="code">/service</code> path is bound to a dynamic service, i.e. the requests
are processed by the user-defined function <code class="code">process_request</code>. This function
is very similar to the request processors used in Netcgi.
<p>

The symbolic <code class="code">*</code> path is only bound for the <code class="code">OPTIONS</code> method. This is
recommended, because clients can use this method to find out the
capabilities of the server.
<p>

Second, select an encapsulation. As mentioned, the reactor is much simpler
to use, but you must take a multi-threaded approach to serve multiple
connections simultaneously. The engine is more efficient, but may use
more memory (unless it is only used for static pages).
<p>

Third, write the code to create the socket and to accept connections.
For the reactor, you should do this in a multi-threaded way (but
multi-processing is also possible). For the engine, you should do this in
an event-based way.
<p>

Now, just call <a href="Nethttpd_reactor.html#VALprocess_connection"><code class="code">Nethttpd_reactor.process_connection</code></a> or 
<a href="Nethttpd_engine.html#VALprocess_connection"><code class="code">Nethttpd_engine.process_connection</code></a>, and pass the socket descriptor
as argument. These functions do all the rest.
<p>

The Ocamlnet source tarball includes examples for several approaches.
Especially look at <code class="code">file_reactor.ml</code>, <code class="code">file_mt_reactor.ml</code>, and 
<code class="code">file_engine.ml</code>.
<p>

<a name="2_Configuration"></a>
<h2>Configuration</h2>
<p>

One of the remaining questions is: How to set all these configuration 
options.
<p>

The user configures the daemon by passing a configuration object.
This object has a number of methods that usually return constants, but
there are also a few functions, e.g.
<p>

<pre><code class="code">  let config : http_reactor_config =
    object
      method config_timeout_next_request = 15.0
      method config_timeout = 300.0
      method config_reactor_synch = `Write
      method config_cgi = Netcgi_env.default_config
      method config_error_response n = "&lt;html&gt;Error " ^ string_of_int n ^ "&lt;/html&gt;"
      method config_log_error _ _ _ _ msg =
        printf "Error log: %s\n" msg
      method config_max_reqline_length = 256
      method config_max_header_length = 32768
      method config_max_trailer_length = 32768
      method config_limit_pipeline_length = 5
      method config_limit_pipeline_size = 250000
    end 
</code></pre>
<p>

Some of the options are interpreted by the encapsulation, and some by the
kernel. The object approach has been taken, because it can be arranged that
the layers of the daemon correspond to a hierarchy of class types.
<p>

The options are documented in the modules where the class types are
defined. Some of them are difficult to understand. In doubt, it is
recommended to just copy the values found in the examples, because these
are quite reasonable for typical usage scenarios.
<p>

<a name="2_Linking"></a>
<h2>Linking</h2>
<p>

Nethttpd needs some CGI functions. There are currently have two CGI
implementations, <code class="code">netcgi1</code> and <code class="code">netcgi2</code>, and it is required to know
at compile time against which library to link. For that reason, there
are also two Nethttpd libraries called <code class="code">nethttpd-for-netcgi1</code> and
<code class="code">nethttpd-for-netcgi2</code>. They are identical except the first is linked
against <code class="code">netcgi1</code> and the latter is linked against <code class="code">netcgi2</code>.
<p>

The name <code class="code">nethttpd</code> resolves to either of the two mentioned libraries,
depending on which CGI library is the "preferred" one (at config time).
<p>

So do
<p>

<pre><code class="code">	ocamlfind ocamlc -package nethttpd-for-netcgi1 ...
</code></pre>
<p>

to use the version working together with <code class="code">netcgi1</code>, or
<p>

<pre><code class="code">	ocamlfind ocamlc -package nethttpd-for-netcgi2 ...
</code></pre>
<p>

to use the version working together with <code class="code">netcgi2</code>, or
<p>

<pre><code class="code">	ocamlfind ocamlc -package nethttpd ...
</code></pre>
<p>

if either version is ok.
<br>
</body></html>