Working on docs

svn: r6462
This commit is contained in:
Jay McCarthy 2007-06-02 20:31:07 +00:00
parent 4568dce304
commit 0c813cb47c
5 changed files with 345 additions and 20 deletions

View File

@ -77,7 +77,7 @@
(lambda (in) (read-string (file-size path) in))))
(provide/contract
[error-response ((natural-number/c string? string?) (listof (cons/c symbol? string?)) . ->* . (response?))]
[error-response ((natural-number/c string? path-string?) (listof (cons/c symbol? string?)) . ->* . (response?))]
[servlet-loading-responder (url? any/c . -> . response?)]
[gen-servlet-not-found (path-string? . -> . (url? . -> . response?))]
[gen-servlet-responder (path-string? . -> . (url? any/c . -> . response?))]

View File

@ -5,8 +5,8 @@
(define dispatcher?
(connection? request? . -> . void))
(define dispatcher-interface-version?
symbol?)
(define (dispatcher-interface-version? v)
(and (symbol? v) (eq? v 'v1)))
(define-struct exn:dispatcher ())
(define (next-dispatcher) (raise (make-exn:dispatcher)))

View File

@ -81,13 +81,14 @@ reading, writing, parsing, and printing @scheme[configuration-table]
structures.
@defproc[(sexpr->configuration-table (sexpr list?))
configuration-table?]
configuration-table?]{
This function converts a @scheme[configuration-table] from an S-expression.
}
@defproc[(configuration-table->sexpr (ctable configuration-table?))
list?]
These functions do the expected and convert a @scheme[configuration-table]
from (to) an S-expression. The format of this S-expresssion is:
list?]{
This function converts a @scheme[configuration-table] to an S-expression.
}
@schemeblock[
`((port ,integer?)
@ -131,12 +132,14 @@ where a @scheme[host-table-sexpr] is:
(password-authentication ,path-string?)))]
@defproc[(read-configuration-table (path path-string?))
configuration-table?]
@defproc[(write-configuration-table (ctable configuration-table?) (path path-string?))
void]
configuration-table?]{
This function reads a @scheme[configuration-table] from @scheme[path].
}
These functions do the expected and read (write) a @scheme[configuration-table]
from (to) the given @scheme[path].
@defproc[(write-configuration-table (ctable configuration-table?) (path path-string?))
void]{
This function writes a @scheme[configuration-table] to @scheme[path].
}
@; ------------------------------------------------------------
@section[#:tag "namespace"]{Servlet Namespaces}
@ -149,16 +152,23 @@ of @file{dispatchers/dispatch-servlets.ss} and @file{dispatchers/dispatch-lang.s
@; XXX Use actual keyword argument syntax
@; XXX Require for current-namespace
@; XXX Link to module-spec?
@defproc[(make-make-servlet-namespace (keyword to-be-copied-module-specs (listof module-spec?)))
@defproc[(make-make-servlet-namespace (#:to-be-copied-module-specs to-be-copied-module-specs (listof module-spec?)))
(key-> ([additional-specs (listof module-spec?)])
namespace?)]
namespace?)]{
This function creates a function that when called will construct a new @scheme[namespace] that
has all the modules from @scheme[to-be-copied-module-specs] and @scheme[additional-specs], as well
as @scheme[mzscheme] and @scheme[(lib "mred.ss" "mred")], provided they are already attached
to the @scheme[(current-namespace)] of the call-site.
Example:
@schemeblock[
(make-make-servlet-namespace
#:to-be-copied-module-specs `((lib "database.ss" "my-module")))
]
}
@subsection{Why this is useful}
A different namespace is needed for each servlet, so that if servlet A and servlet B both use
@ -177,4 +187,63 @@ of servlets can share different sets of modules.
@; ------------------------------------------------------------
@section[#:tag "responders"]{Standard Responders}
XXX
@file{configuration/responders.ss} provides some functions that help constructing HTTP responders.
These functions are used by the default dispatcher constructor (see @secref["web-server-unit"]) to
turn the paths given in the @scheme[configuration-table] into responders for the associated circumstance.
@; XXX Include response/full
@; XXX Rename error-response
@defproc[(error-response (http-code natural-number/c) (short-version string?) (text-file string?) (extra-header (cons/c symbol? string?)) ...0)
response?]{
Generates a @scheme[response/full] with the given @scheme[http-code] and @scheme[short-version]
as the corresponding fields; with the content of the @scheme[text-file] as the body; and, with
the @scheme[extra-header]s as, you guessed it, extra headers.
}
@defproc[(servlet-loading-responder (url url?) (exn any/c))
response?]{
Prints the @scheme[exn] to standard output and responds with a "Servlet didn't load."
message.
}
@defproc[(gen-servlet-not-found (file path-string?))
((url url?) . -> . response?)]{
Returns a function that generates a standard "Servlet not found." error with content from @scheme[file].
}
@defproc[(gen-servlet-responder (file path-string?))
((url url?) (exn any/c) . -> . response?)]{
Prints the @scheme[exn] to standard output and responds with a "Servlet error." message with content from @scheme[file].
}
@defproc[(gen-servlets-refreshed (file path-string?))
(-> response?)]{
Returns a function that generates a standard "Servlet cache refreshed." message with content from @scheme[file].
}
@defproc[(gen-passwords-refreshed (file path-string?))
(-> response?)]{
Returns a function that generates a standard "Passwords refreshed." message with content from @scheme[file].
}
@defproc[(gen-authentication-responder (file path-string?))
((url url?) (header (cons/c symbol? string?)) . -> . response?)]{
Returns a function that generates an authentication failure error with content from @scheme[file] and
@scheme[header] as the HTTP header.
}
@defproc[(gen-protocol-responder (file path-string?))
((url url?) . -> . response?)]{
Returns a function that generates a "Malformed request" error with content from @scheme[file].
}
@defproc[(gen-file-not-found-responder (file path-string?))
((req request?) . -> . response?)]{
Returns a function that generates a standard "File not found" error with content from @scheme[file].
}
@defproc[(gen-collect-garbage-responder (file path-string?))
(-> response?)]{
Returns a function that generates a standard "Garbage collection run" message with content from @scheme[file].
}

View File

@ -3,11 +3,266 @@
@title[#:style 'toc]{Dispatchers}
XXX
The @file{web-server} is really just a peculiar configuration of a
dispatching server. There are a number of dispatchers that are defined
to support the @file{web-server}. Other dispatching servers, or variants
of the @file{web-server}, may find these useful. In particular, if you want
a peculiar processing pipeline for your @file{web-server} installation, this
documentation will be useful.
@local-table-of-contents[]
@; XXX Include connection? and request?
@; ------------------------------------------------------------
@section[#:tag "example"]{Example}
@section[#:tag "dispatch"]{General}
@file{dispatchers/dispatch.ss} provides a few functions for dispatchers in general.
@defproc[(dispatcher? (any any/c))
boolean?]{
Applies the contract @scheme[(connection? request? . -> . void)] to @scheme[any].
}
@defproc[(dispatcher-interface-version? (any any/c)) boolean?]{
Returns @scheme[#t] if @scheme[any] is @scheme['v1]. Returns @scheme[#f] otherwise.
}
@defstruct[exn:dispatcher ()]{
An exception thrown to indicate that a dispatcher does not apply to a particular
request.
}
@defproc[(next-dispatcher) void]{
Raises a @scheme[exn:dispatcher]
}
As the @scheme[dispatcher?] contract suggests, a dispatcher is a function that takes a connection
and request object and does something to them. Mostly likely it will generate
some response and output it on the connection, but it may do something
different. For example, it may apply some test to the request object, perhaps
checking for a valid source IP address, and error if the test is not passed, and call @scheme[next-dispatcher]
otherwise.
@; XXX Rename const to lift
@; ------------------------------------------------------------
@section[#:tag "dispatch-const"]{Lifting Procedures}
@file{dispatchers/dispatch-const.ss} defines:
@defproc[(make (proc (request? . -> . response?)))
dispatcher?]{
Constructs a dispatcher that calls @scheme[proc] on the request
object, and outputs the response to the connection.
}
@; ------------------------------------------------------------
@section[#:tag "dispatch-files"]{Serving Files}
@file{dispatchers/dispatch-files.ss} allows files to be served.
It defines a dispatcher construction procedure:
@; XXX Change mime-types-path to path->mime-type
@; XXX Include make-get-mime-type
@defproc[(make [#:url->path url->path url->path?]
[#:mime-types-path mime-types-path path-string? "mime.types"]
[#:indices indices (listof string?) (list "index.html" "index.htm")])
dispatcher?]{
Uses @scheme[url->path] to extract a path from the URL in the request
object. If this path does not exist, then the dispatcher does not apply.
If the path is a directory, then the @scheme[indices] are checked in order
for an index file to serve. In that case, or in the case of a path that is
a file already, the @scheme[mime-types-path] file is consulted for the MIME
Type of the path, via @scheme[make-get-mime-type]. The file is then
streamed out the connection object.
This dispatcher supports HTTP Range GET requests and HEAD requests.}
@; XXX Change filtering to take predicate, rather than regexp
@; ------------------------------------------------------------
@section[#:tag "dispatch-filter"]{Filtering Requests}
@file{dispatchers/dispatch-filter.ss} defines a dispatcher constructer
that calls an underlying dispatcher
with all requests that pass a predicate.
@defproc[(make (regex regexp?) (inner dispatcher?))
dispatcher?]{
Calls @scheme[inner] if the URL path of the request, converted to
a string, matches @scheme[regex]. Otherwise, calls @scheme[next-dispatcher].
}
@; ------------------------------------------------------------
@section[#:tag "dispatch-host"]{Virtual Hosts}
@file{dispatchers/dispatch-host.ss} defines a dispatcher constructor
that calls a different dispatcher based upon the host requested.
@defproc[(make (lookup-dispatcher (symbol? . -> . dispatcher?)))
dispatcher?]{
Extracts a host from the URL requested, or the Host HTTP header,
calls @scheme[lookup-dispatcher] with the host, and invokes the
returned dispatcher. If no host can be extracted, then @scheme['<none>]
is used.
}
@; ------------------------------------------------------------
@section[#:tag "dispatch-lang"]{Serving Web Language Servlets}
@file{dispatchers/dispatch-lang.ss} defines a dispatcher constructor
that runs servlets written in the Web Language.
@; XXX Don't include timeout logic in here, put it outside.
@; XXX Include configuration.scrbl exports
@defproc[(make [#:url->path url->path url->path?]
[#:make-servlet-namespace make-servlet-namespace
make-servlet-namespace?
(make-make-servlet-namespace)]
[#:timeouts-servlet-connection timeouts-servlet-connection integer? (* 60 60 24)]
[#:responders-servlet-loading responders-servlet-loading servlet-loading-responder]
[#:responders-servlet responders-servlet (gen-servlet-responder "servlet-error.html")])
dispatcher?]{
Extends the timeout of the connection by @scheme[timeouts-servlet-connection].
If the request URL contains a serialized continuation, then it is invoked with the
request. Otherwise, @scheme[url->path] is used to resolve the URL to a path.
The path is evaluated as a module, in a namespace constructed by @scheme[make-servlet-namespace].
If this fails then @scheme[responders-servlet-loading] is used to format a response
with the exception. If it succeeds, then @scheme[start] export of the module is invoked.
If there is an error when a servlet is invoked, then @scheme[responders-servlet] is
used to format a response with the exception.
}
@; ------------------------------------------------------------
@section[#:tag "dispatch-log"]{Logging}
@file{dispatchers/dispatch-log.ss} defines a dispatcher constructer
for transparent logging of requests.
@; XXX Take formating procedure
@defproc[(make [#:log-format log-format symbol? 'parenthesized-default]
[#:log-path log-path (or/c path-string? false/c) #f])
dispatcher?]{
If @scheme[log-path] is not @scheme[#f] and @scheme[log-format] is
@scheme['parenthesized-default] or @scheme[extended], then the request
is logged to the @scheme[log-path]. In either case, @scheme[next-dispatcher]
is invoked after this.
If @scheme[log-format] is @scheme['parenthesized-default], then the
log looks like: @scheme[(list 'from (request-client-ip req)
'to (request-host-ip req)
'for (url->string (request-uri req)) 'at
(date->string (seconds->date (current-seconds)) #t))].
If @scheme[log-format] is @scheme['extended], then the log looks like:
@scheme[`((client-ip ,(request-client-ip req))
(host-ip ,(request-host-ip req))
(referer ,(or/c bytes? false/c))
(uri ,(url->string (request-uri req)))
(time ,(current-seconds)))].
}
@; ------------------------------------------------------------
@section[#:tag "dispatch-passwords"]{Password Protection}
@file{dispatchers/dispatch-passwords.ss} defines a dispatcher constructor
that performs HTTP Basic authentication filtering.
@defproc[(make [#:password-file password-file path-string? "passwords"]
[#:password-connection-timeout password-connection-timeout integer? 300]
[#:authentication-responder
authentication-responder
((url url?) (header (cons/c symbol? string?)) . -> . response?)
(gen-authentication-responder "forbidden.html")])
(values (-> void)
dispatcher?)]{
The first returned value is a procedure that refreshes the password
file used by the dispatcher.
The dispatcher that is returned does the following:
Extends connection timeout by @scheme[password-connection-timeout].
Checks if the request contains Basic authentication credentials, and that
they are included in @scheme[password-file]. If they are not,
@scheme[authentication-responder] is called with a @scheme[header] that
requests credentials. If they are, then @scheme[next-dispatcher] is
invoked.
}
@; ------------------------------------------------------------
@section[#:tag "dispatch-pathprocedure"]{Procedure Invocation upon Request}
@file{dispatchers/dispatch-pathprocedure.ss} defines a dispatcher constructor
for invoking a particular procedure when a request is given to a particular
URL path.
@defproc[(make (path string?) (proc (request? . -> . response?)))
dispatcher?]{
Checks if the request URL path as a string is equal to @scheme[path]
and if so, calls @scheme[proc] for a response.
}
This is used in the standard @file{web-server} pipeline to provide
a URL that refreshes the password file, servlet cache, etc.
@; ------------------------------------------------------------
@section[#:tag "dispatch-sequencer"]{Sequencing}
@file{dispatchers/dispatch-sequencer.ss} defines a dispatcher constructor
that invokes a sequence of dispatchers until one applies.
@defproc[(make (dispatcher dispatcher?) ...0)
dispatcher?]{
Invokes each @scheme[dispatcher], invoking the next if the first
calls @scheme[next-dispatcher]. If no @scheme[dispatcher] applies,
then it calls @scheme[next-dispatcher] itself.
}
@; ------------------------------------------------------------
@section[#:tag "dispatch-servlets"]{Serving Scheme Servlets}
@file{dispatchers/dispatch-servlets.ss} defines a dispatcher constructor
that runs servlets written in Scheme.
@; XXX Remove config:instances
@; XXX Define make-servlet-namespace?
@defproc[(make [config:instances any/c]
[config:scripts (box/c cache-table?)]
[config:make-servlet-namespace make-servlet-namespace?]
[#:url->path url->path url->path?]
[#:responders-servlet-loading
responders-servlet-loading
((url url?) (exn any/c) . -> . response?)
servlet-loading-responder]
[#:responders-servlet
responders-servlet
((url url?) (exn any/c) . -> . response?)
(gen-servlet-responder "servlet-error.html")]
[#:timeouts-servlet-connection
timeouts-servlet-connection
integer?
(* 60 60 24)]
[#:timeouts-default-servlet
timeouts-default-servlet
integer?
30])
(values (-> void)
dispatcher?)]{
The first returned value is a procedure that refreshes the servlet
code cache.
The dispatcher does the following:
Extends the timeout of the connection by @scheme[timeouts-servlet-connection].
If the request URL contains a continuation reference, then it is invoked with the
request. Otherwise, @scheme[url->path] is used to resolve the URL to a path.
The path is evaluated as a module, in a namespace constructed by @scheme[make-servlet-namespace].
If this fails then @scheme[responders-servlet-loading] is used to format a response
with the exception. If it succeeds, then @scheme[start] export of the module is invoked.
If there is an error when a servlet is invoked, then @scheme[responders-servlet] is
used to format a response with the exception.
Servlets that do not specify timeouts are given timeouts according to @scheme[timeouts-default-servlet].
}
@; ------------------------------------------------------------
@section[#:tag "filesystem-map"]{Mapping URLs to Paths}
XXX

View File

@ -206,6 +206,7 @@
(define ext:output-file
(ext:wrap output-file))
; XXX Check method in response
;; **************************************************
;; output-response/method: connection response/full symbol -> void
;; If it is a head request output headers only, otherwise output as usual