The (www server-utils big-dishing-loop)
module provides procedures
that facilitate generation of a customized listener/dispatch proc.
Keywords: socket-setup
Return a new socket in protocol family with address name.
First, evaluate
(socket
familySOCK_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
, andINADDR_foo
are names of variables that have constant values, not symbols.
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).
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 thebind
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 boston 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 asGET
; 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 isshutdown
in both (r/w) directions. When operating concurrently, this is done on the child side of the split. See Network Sockets and Communication.- #: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