Working on docs
svn: r6462
This commit is contained in:
parent
4568dce304
commit
0c813cb47c
|
@ -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?))]
|
||||
|
|
|
@ -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)))
|
||||
|
||||
|
|
|
@ -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].
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user