Next: , Previous: , Up: Top   [Contents][Index]


6 (www server-utils big-dishing-loop)

The (www server-utils big-dishing-loop) module provides procedures that facilitate generation of a customized listener/dispatch proc.

Procedure: named-socket family name [keyword value…]
Keywords: socket-setup 

Return a new socket in protocol family with address name.

First, evaluate (socket family SOCK_STREAM 0) to create a new socket sock. Next, handle #:socket-setup, with value setup, like so:

#f

Do nothing. This is the default.

procedure

Call procedure on sock.

((opt . val) …)

For each pair in this alist, call setsockopt on sock with the pair’s opt and val.

Lastly, bind sock to name, which should be in a form that is appopriate for family. Two common cases are:

PF_INET

(AF_INET ipaddr portno), made, for example, by
(list AF_INET INADDR_ANY 4242).

PF_UNIX

(AF_UNIX filename), made, for example, by
(list AF_UNIX "/tmp/foo-control").

Note that PF_foo, AF_foo, and INADDR_foo are names of variables that have constant values, not symbols.

Procedure: echo-upath M upath [extra-args…]

Use mouthpiece M (see answer) to compose and send a "text/plain" response which has the given upath (a string) and any extra-args as its content. Shut down the socket for both transmission and reception, then return #t.

This proc can be used to ensure basic network connectivity (i.e., aliveness testing).

Procedure: make-big-dishing-loop [keyword value…]

Return a proc dish that loops serving http requests from a socket. dish takes one arg ear, which may be a pre-configured socket, a TCP port number, or a list of the form: (family address …). When ear is a TCP port number, it is taken to be the list (PF_INET AF_INET INADDR_ANY ear).

In the latter two cases, the socket is realized by calling named-socket with parameters family and name taken from the CAR and CDR, respectively, of the list, with the #:socket-setup paramater (see below) passed along unchanged.

dish behavior is controlled by the keyword arguments given to make-big-dishing-loop. The following table is presented roughly in order of the steps involved in processing a request, with default values shown next to the keyword.

#:socket-setup #f

This may be a proc that takes a socket, or a list of opt/val pairs which are passed to setsockopt. Socket setup is done for newly created sockets (when dish is passed a TCP port number), prior to the bind call.

#:queue-length 0

The number of clients to queue, as set by the listen system call. Setting the queue length is done for both new and pre-configured sockets.

#:concurrency #:new-process

The type of concurrency (or none if the value is not recognized). Here are the recognized values:

#:new-process
#:new-process/nowait

Fork a new process for each request. The latter does not wait for the child process to terminate before continuing the listen loop.

#f

Handle everything in the current in process (no concurrency). Unrecognized values are treated the same as #f.

#:bad-request-handler #f

If the first line of an HTTP message is not in the proper form, this specifies a proc that takes a mouthpiece m. Its return value should be the opposite boolean value of the #:loop-break-bool value, below. See answer.

#:method-handlers ()

This alist describes how to handle the (valid) HTTP methods. Each element has the form (method . handler). method is a symbol, such as GET; and handler is a procedure that handles the request for method.

handler normally takes two arguments, the mouthpiece m and the upath (string), composes and sends a response, and returns non-#f to indicate that the big dishing loop should continue.

The proc’s argument list is configured by #:need-headers, #:need-input-port and #:explicit-return. Interpretation of the proc’s return value is configured by #:explicit-return and #:loop-break-bool. See below.

#:need-headers #f
#:need-input-port #f

If non-#f, these cause additional arguments to be supplied to the handler proc. If present, the headers arg precedes the input port arg. See parse-request. The input port is always positioned at the beginning of the HTTP message body.

If #:need-input-port is #f, after the handler proc returns, the port is shutdown in both (r/w) directions. When operating concurrently, this is done on the child side of the split. See Network Sockets and Communication in The Guile Reference Manual.

#:explicit-return #f

If non-#f, this arranges for a continuation to be passed (as the last argument) to the handler proc, and ignores that proc’s normal return value in favor of one explicitly passed through the continuation. If the continuation is not used, the effective return value is computed as (not #:loop-break-bool).

#:loop-break-bool #f

Looping stops if the effective return value of the handler is eq? to this value.

#:unknown-http-method-handler #f

If #f, silently ignore unknown HTTP methods, i.e., those not specified in #:method-handlers. The value may also be a procedure that takes three arguments: a mouthpiece m, the method (symbol) and the upath (string). Its return value should be the opposite boolean value of the #:loop-break-bool value, below. See answer.

#:parent-finish close-port

When operating concurrently (#:concurrency non-#f), the “parent” applies this proc to the port after the split.

#:log #f

This proc is called after the handler proc returns. Note that if ear is a unix-domain socket, the client parameter will be simply "localhost". See log.

#:status-box-size #f

This may be a non-negative integer, typically 0, 1 or 2. It is used by #:log (has no meaning if #:log is #f). See log.

#:style #f

An object specifying the syntax of the first-line and headers. The default specifies a normal HTTP message (see http).

The combination of #:need-headers, #:need-input-port and #:explicit-return mean that the #:GET-upath proc can receive anywhere from two to five arguments. Here is a table of all the possible combinations (1 means non-#f and 0 means #f):

+----- #:explicit-return
| +--- #:need-input-port
| | +- #:need-headers
| | |
| | |  args to #:GET-upath proc
=====  ==============================
0 0 0  M upath
0 0 1  M upath headers
0 1 0  M upath in-port
0 1 1  M upath headers in-port
1 0 0  M upath return
1 0 1  M upath headers return
1 1 0  M upath in-port return
1 1 1  M upath headers in-port return

Next: , Previous: , Up: Top   [Contents][Index]