~ubuntu-branches/ubuntu/trusty/ocamlnet/trusty

« back to all changes in this revision

Viewing changes to src/nethttpd/nethttpd_intro.txt

  • Committer: Bazaar Package Importer
  • Author(s): Stéphane Glondu
  • Date: 2011-09-02 14:12:33 UTC
  • mfrom: (18.2.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110902141233-zbj0ygxb92u6gy4z
Tags: 3.4-1
* New upstream release
  - add a new NetcgiRequire directive to ease dependency management
    (Closes: #637147)
  - remove patches that were applied upstream:
    + Added-missing-shebang-lines-in-example-shell-scripts
    + Try-also-ocamlc-for-POSIX-threads

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
{2:overview Overview over the HTTP daemon}
 
2
 
 
3
This library implements an HTTP 1.1 server. Because it is a library and not
 
4
a stand-alone server like Apache, it can be used in very flexible ways.
 
5
The disadvantage is that the user of the library must do more to get
 
6
a running program than just configuring the daemon.
 
7
 
 
8
The daemon has five modules:
 
9
 
 
10
- {!Nethttpd_types} is just a module with common type definitions used
 
11
  by the other modules
 
12
- {!Nethttpd_kernel} is the implementation of the HTTP protocol. If we
 
13
  talk about the "kernel" we mean this module. The kernel has two 
 
14
  interface sides: There is the "socket side" and the "message side"
 
15
  that are connected by bidirectional data flow.
 
16
  The task of the kernel is to decode input received by the socket side
 
17
  and to deliver it to a consumer on the message side, and conversely
 
18
  to encode input coming in through the message side and to send it
 
19
  to the socket. The kernel is a quite low-level module; the socket
 
20
  is accessed in a multiplexing-compatible style, and the messages
 
21
  are sequences of tokens like "status line", "header", "body chunk"
 
22
  and so on. Normally a user of the daemon does not program the kernel
 
23
  directly. It is, however, possible to pass certain configuration
 
24
  options to the kernel even if an encapsulation is used.
 
25
- {!Nethttpd_reactor} is an encapsulation of the kernel with a nicer
 
26
  interface. An instance of the reactor processes, like the kernel,
 
27
  only a single HTTP connection. It is used as follows: The user
 
28
  of the reactor pulls the arriving HTTP requests from the reactor,
 
29
  processes them, and writes the responses back to the reactor. This
 
30
  means that the requests are processed in a strictly sequential
 
31
  way. The reactor hides the details of the HTTP protocol. The
 
32
  reactor is able to perform socket input and output at the same time,
 
33
  i.e. when the response is sent to the client the next request(s) can
 
34
  already be read (pipelining). The reactor can be configured such that
 
35
  buffering of requests and responses is avoided, even if large
 
36
  messages are transferred. As mentioned, the reactor can only
 
37
  deal with one connection at the same time. In order to serve
 
38
  several connections, one must use multi-threading.
 
39
- {!Nethttpd_engine} is another encapsulation of the kernel. It is
 
40
  event-based, and this makes it possible that several instances
 
41
  can work at the same time without using multi-threading. The user
 
42
  of the engine is called back when the beginning of the next HTTP
 
43
  request arrives and at certain other events. The user processes
 
44
  the event, and generates the response. 
 
45
  The engine is a
 
46
  highly efficient implementation of an HTTP server, but there are
 
47
  also drawbacks, so user may feel more comfortable with the reactor.
 
48
  Especially, the engine needs large buffers for input and output
 
49
  (there is an idea to use helper threads to avoid these buffers,
 
50
  but this has not been implemented yet). Of course, the engine
 
51
  also supports pipelining.
 
52
- {!Nethttpd_services} has functions to compose complex service
 
53
  functions from simpler ones. In particular, one can configure
 
54
  name- or IP-based virtual hosting, one can bind services to
 
55
  URLs, and one can define static file serving, directory listings,
 
56
  and dynamic services. It is quite easy to turn a Netcgi program
 
57
  into a dynamic service for Nethttpd.
 
58
- {!Nethttpd_plex} provides nice integration into [netplex].
 
59
  Most features provided by {!Nethttpd_services} can be activated
 
60
  by simply referencing them in the netplex configuration file.
 
61
 
 
62
It is also important to mention what Nethttpd does not include:
 
63
 
 
64
- There is no function to create the socket, and to accept connections.
 
65
 
 
66
- There is no function to manage threads or subprocesses
 
67
 
 
68
Ocamlnet provides this in the [netplex] library.
 
69
 
 
70
{2 Suggested strategy}
 
71
 
 
72
First, look at {!Nethttpd_services}. This module allows the user
 
73
to define the services of the web server. For example, the following
 
74
code defines a single host with an URL space:
 
75
 
 
76
{[
 
77
let fs_spec =
 
78
  { file_docroot = "/data/docroot";
 
79
    file_uri = "/";
 
80
    file_suffix_types = [ "txt", "text/plain";
 
81
                          "html", "text/html" ];
 
82
    file_default_type = "application/octet-stream";
 
83
    file_options = [ `Enable_gzip;
 
84
                     `Enable_listings simple_listing
 
85
                   ]
 
86
  }
 
87
 
 
88
let srv =
 
89
  host_distributor
 
90
    [ default_host ~pref_name:"localhost" ~pref_port:8765 (),
 
91
      uri_distributor
 
92
        [ "*", (options_service());
 
93
          "/files", (file_service fs_spec);
 
94
          "/service", (dynamic_service
 
95
                           { dyn_handler = process_request;
 
96
                             dyn_activation = std_activation `Std_activation_buffered;
 
97
                             dyn_uri = Some "/service";
 
98
                             dyn_translator = file_translator fs_spec;
 
99
                             dyn_accept_all_conditionals = false
 
100
                           })
 
101
        ]
 
102
    ]
 
103
]}
 
104
 
 
105
The [/files] path is bound to a static service, i.e. the files found in
 
106
the directory [/data/docroot] can be accessed over the web. The record
 
107
[fs_spec] configures the static service.
 
108
 
 
109
The [/service] path is bound to a dynamic service, i.e. the requests
 
110
are processed by the user-defined function [process_request]. This function
 
111
is very similar to the request processors used in Netcgi.
 
112
 
 
113
The symbolic [*] path is only bound for the [OPTIONS] method. This is
 
114
recommended, because clients can use this method to find out the
 
115
capabilities of the server.
 
116
 
 
117
Second, select an encapsulation. As mentioned, the reactor is much simpler
 
118
to use, but you must take a multi-threaded approach to serve multiple
 
119
connections simultaneously. The engine is more efficient, but may use
 
120
more memory (unless it is only used for static pages).
 
121
 
 
122
Third, write the code to create the socket and to accept connections.
 
123
For the reactor, you should do this in a multi-threaded way (but
 
124
multi-processing is also possible). For the engine, you should do this in
 
125
an event-based way.
 
126
 
 
127
Now, just call {!Nethttpd_reactor.process_connection} or 
 
128
{!Nethttpd_engine.process_connection}, and pass the socket descriptor
 
129
as argument. These functions do all the rest.
 
130
 
 
131
The Ocamlnet source tarball includes examples for several approaches.
 
132
Especially look at [file_reactor.ml], [file_mt_reactor.ml], and 
 
133
[file_engine.ml].
 
134
 
 
135
{2 Configuration}
 
136
 
 
137
One of the remaining questions is: How to set all these configuration 
 
138
options.
 
139
 
 
140
The user configures the daemon by passing a configuration object.
 
141
This object has a number of methods that usually return constants, but
 
142
there are also a few functions, e.g.
 
143
 
 
144
{[
 
145
  let config : http_reactor_config =
 
146
    object
 
147
      method config_timeout_next_request = 15.0
 
148
      method config_timeout = 300.0
 
149
      method config_reactor_synch = `Write
 
150
      method config_cgi = Netcgi_env.default_config
 
151
      method config_error_response n = "<html>Error " ^ string_of_int n ^ "</html>"
 
152
      method config_log_error _ _ _ _ msg =
 
153
        printf "Error log: %s\n" msg
 
154
      method config_max_reqline_length = 256
 
155
      method config_max_header_length = 32768
 
156
      method config_max_trailer_length = 32768
 
157
      method config_limit_pipeline_length = 5
 
158
      method config_limit_pipeline_size = 250000
 
159
    end 
 
160
]}
 
161
 
 
162
Some of the options are interpreted by the encapsulation, and some by the
 
163
kernel. The object approach has been taken, because it can be arranged that
 
164
the layers of the daemon correspond to a hierarchy of class types.
 
165
 
 
166
The options are documented in the modules where the class types are
 
167
defined. Some of them are difficult to understand. In doubt, it is
 
168
recommended to just copy the values found in the examples, because these
 
169
are quite reasonable for typical usage scenarios.
 
170
 
 
171
{2 Linking}
 
172
 
 
173
In Ocamlnet 3 the nethttpd library can be both referenced as
 
174
[-package nethttpd] or [-package nethttpd-for-netcgi2] (the
 
175
latter being an alias). As the [netcgi1] library was dropped, there
 
176
is no reason for [nethttpd-for-netcgi1] anymore - this name is
 
177
now unavailable.