Removing obsolete files
svn: r6438
This commit is contained in:
parent
1090572e21
commit
15b97fa4f8
|
@ -1,347 +0,0 @@
|
|||
_prototype-web-server_
|
||||
|
||||
_Overview_
|
||||
|
||||
The prototype is intended to completely decouple the continuation mechanism
|
||||
for servlets from the rest of the server. The prototype-server knows
|
||||
nothing about continuations. Instead, the prototype-server provides a
|
||||
simple session-based model akin to traditional CGI.
|
||||
|
||||
See prototype-web-server/servlets/add01.ss for an example session-based
|
||||
servlet.
|
||||
|
||||
See Web Interactive Language, and Interactive Language for understanding
|
||||
how continuations are used with the prototype-web-server.
|
||||
|
||||
_Configuring the prototype-server_
|
||||
|
||||
Eliminated the dependency on web-server/configuration.ss and simply
|
||||
hard-coded the configuration in:
|
||||
prototype-web-server/hardcoded-configuration.ss
|
||||
|
||||
|
||||
_Running the prototype-server_
|
||||
> serve
|
||||
;; serve: -> -> void
|
||||
;; start the server and return a thunk to shut it down.
|
||||
|
||||
_Loading Servlets_
|
||||
|
||||
Steps:
|
||||
1. The URL is decoded. If the URL encodes a session-id, then the server
|
||||
looks up the session in the session table. If the session structure is
|
||||
found in the table, then the session-handler is called with the request
|
||||
to generate the response. If no session is found an error page is
|
||||
generated.
|
||||
|
||||
2. If the URL does not encode a session-id, then the servlet path is
|
||||
resolved to find an executable (see path resolution.) If no executable
|
||||
is found, an error page is generated.
|
||||
|
||||
3. If an executable is found a new session-structure is created. A unique
|
||||
session-id is generated for the session and all subsequent requests for
|
||||
this session should encode this id. A new custodian, new namespace, and
|
||||
a default handler are created for the session. The simplified url-path
|
||||
that located the servlet is used as the path in the session-url.
|
||||
|
||||
4. The servlet executable should be a module. The servlet is then invoked
|
||||
via dynamic-require within the new session-namespace. During this
|
||||
invocation, the servlet should make a call to start-session in order to
|
||||
install the session handler for the servlet. After the module is
|
||||
invoked, the session handler is called with the initial request.
|
||||
|
||||
_Path Resolution_
|
||||
|
||||
Steps:
|
||||
1. The url-path is simplified:
|
||||
(i) All path/params are removed from the url path and replaced with
|
||||
their corresponding path/param-path.
|
||||
(ii) Empty strings that show up as file names in the url-path are removed
|
||||
from the path, so that e.g. a path that looks like "foo////bar"
|
||||
would be simplified to "foo/bar".
|
||||
(iii) All ".."'s are removed from the path by replacing them with 'up.
|
||||
(iv) The path is simplified with respect to the root directory in order
|
||||
to prevent path chasing. I.e. if surplus ".." pile up they are
|
||||
discarded.
|
||||
2. The path is appended to the servlet-path of the virtual-host that is
|
||||
handling the request.
|
||||
3. The shortest prefix of the path from step 2 that specifies a servlet
|
||||
file is then computed. The resulting servlet file is the one.
|
||||
4. The same prefix in step 3, but without the servlet-path part, is used
|
||||
for the url-path in the session-url. The session-id will be encoded in
|
||||
this path.
|
||||
|
||||
_Sessions_
|
||||
_session.ss_
|
||||
|
||||
The prototype web-server creates a session each time a particular servlet
|
||||
is loaded. A servlet is loaded when the URL specifying the servlets
|
||||
filename does not encode a session id. A new namespace is created and
|
||||
stored as part of the session. The servlet is then dynamic-required using
|
||||
the new namespace. The module session.ss is attached to the servlets
|
||||
namespace.
|
||||
|
||||
NOTE: The session is analogous to the "servlet-instance" in the current
|
||||
web-server.
|
||||
|
||||
The servlet-writer should be aware of the following provides from
|
||||
session.ss:
|
||||
|
||||
[struct session ([id number?]
|
||||
[cust custodian?]
|
||||
[namespace namespace?]
|
||||
[handler (request? . -> . response?)]
|
||||
[url url?])]
|
||||
|
||||
> session-id
|
||||
A number that identifies the session. This number is encoded in the URL and
|
||||
used by the server to lookup the correct session for an incoming
|
||||
request. session-id's are encoded using a path/param.
|
||||
|
||||
> session-custodian
|
||||
The custodian that manages the session.
|
||||
|
||||
NOTE: Sessions currently do NOT time out. Ultimately I will need to add a
|
||||
timeout mechanism for sessions so that they don't pile up and consume
|
||||
memory. This is the same as the servlet-timeout.
|
||||
|
||||
> session-namespace
|
||||
The namespace in which the servlet runs.
|
||||
|
||||
NOTE: Each session gets its own namespace. It is presently NOT easy for two
|
||||
sessions to share state.
|
||||
|
||||
REQUIREMENT: Need a mechanism for sessions to share state through a common
|
||||
module. This includes sessions corresponding to different servlets.
|
||||
|
||||
> session-handler
|
||||
The session handler consumes a request and produces a response. All
|
||||
requests for the session go through the session handler. The
|
||||
session-handler is installed via a call to start-session.
|
||||
|
||||
> session-url
|
||||
The minimal url that refers to the servlet file. It is minimal in the sense
|
||||
that the url-path is the shortest path that would resolve to the
|
||||
servlet. This url-path also encodes the session id.
|
||||
|
||||
> current-session
|
||||
This parameter is set by the web-server and stores the value of the current
|
||||
session.
|
||||
|
||||
> lookup-session
|
||||
(number? . -> . (union session? boolean?))
|
||||
lookup-session is used internally by the web-server to lookup a session
|
||||
once the session-id is decoded from the URL.
|
||||
|
||||
> new-session
|
||||
(custodian? namespace? url? . -> . session?)
|
||||
new-session is used internally by the web-server to create a new session
|
||||
when a servlet is loaded.
|
||||
|
||||
> start-session
|
||||
((request? . -> . response?) . -> . any)
|
||||
start-session installs the session-handler for a servlets session. Start
|
||||
session should be called by the servlet exactly once before any responses
|
||||
are generated.
|
||||
|
||||
_utils.ss_
|
||||
|
||||
> split-url-path
|
||||
;; url url -> (union (listof string) #f)
|
||||
Useful when using the servlet-path to encode additional arguments to the
|
||||
server. Servlet writers should use this to recover the suffix of the
|
||||
url-path occurring after the servlet file.
|
||||
|
||||
> url->servlet-path
|
||||
url->servlet-path: path url -> (values (union path #f)
|
||||
(union (listof url->string) #f)
|
||||
(union (listof string) #f))
|
||||
Used by the server during servlet-path resolution.
|
||||
|
||||
> make-session-url
|
||||
url (listof string) -> url
|
||||
Used internally by the server to create the session-url when loading a
|
||||
servlet.
|
||||
|
||||
_Interaction Language_
|
||||
|
||||
The interaction language creates a module with multiple interaction
|
||||
points. The interaction point serves as a synchronization mechanism between
|
||||
the module and the outside world. When an interaction point is encountered,
|
||||
a response is generated by the module and then execution halts. Execution
|
||||
may be resumed later when a request is passed to the module. The
|
||||
interactive language, by itself does not restrict the number of times an
|
||||
interaction point can be resumed.
|
||||
|
||||
The syntax of an interactive module is as follows:
|
||||
|
||||
program ::= definition* expr
|
||||
|
||||
definition ::= (define-values (var) expr)
|
||||
|
||||
expr ::= var
|
||||
| (lambda (var ...) expr)
|
||||
| (if expr expr)
|
||||
| (if expr expr expr)
|
||||
| (let-values ([(var)] expr) expr)
|
||||
| (#%app expr ...)
|
||||
| (#%datum . datum)
|
||||
| (#%top . var)
|
||||
| (begin expr ...)
|
||||
|
||||
NOTE: The body of the module (excluding requires) is first expanded to
|
||||
core-mzscheme forms before execution.
|
||||
|
||||
NOTE: The interaction language is implemented using non-native
|
||||
continuations. I.e. occurrences of call/cc within the program are replaced
|
||||
by a new version when the module is expanded.
|
||||
|
||||
_Creating an Interactive Module_
|
||||
|
||||
An interactive module is created by specifying "interaction.ss" as the language
|
||||
for a module.
|
||||
|
||||
Example:
|
||||
(module my-module "interaction.ss"
|
||||
...)
|
||||
|
||||
The writer of an interactive module may then specify interaction points
|
||||
using the interface provided by interaction.ss
|
||||
|
||||
_interaction.ss_
|
||||
|
||||
> start-interaction
|
||||
(request -> continuation) -> request
|
||||
start-interaction establishes the initial interaction point for the
|
||||
interactive module and registers a procedure to be used for decoding
|
||||
requests. start-interaction stores the continuation of the call to
|
||||
start-interaction. This continuation is resumed using the client interface
|
||||
to the interactive module (see below.)
|
||||
|
||||
Example:
|
||||
(module m01 "../interaction.ss"
|
||||
(define (id x) x)
|
||||
(+ (* 1 2) (* 3 4) (start-interaction id)))
|
||||
|
||||
> send/suspend
|
||||
(continuation -> response) -> request
|
||||
Captures the continuation of the call to send/suspend and passes this as
|
||||
the argument to send/suspend. Execution then halts until the continuation
|
||||
is resumed via the client interface to the interactive module (see below.)
|
||||
|
||||
_client.ss_
|
||||
|
||||
> dispatch-start
|
||||
request -> response
|
||||
Pass the initial request to the interactive module. After the module is
|
||||
required, it should eventually make a call to start-interaction. After
|
||||
start-interaction is called, execution will halt until dispatch-start is
|
||||
called. When dispatch-start is called, the request is passed to the
|
||||
continuation of the call to start-interaction. The response produced is the
|
||||
response produced by the next interaction point of the module or, when no
|
||||
subsequent interaction point is encountered, is the result of evaluating
|
||||
the module's body expression.
|
||||
|
||||
> dispatch
|
||||
request -> response
|
||||
Resumes execution at the interaction point encoded in the request. When
|
||||
dispatch is called, the request handler installed via the last call to
|
||||
start-interaction is applied to the request, producing a continuation and
|
||||
then the resulting continuation is applied to the request. The response
|
||||
produced is the response produced by the next interaction point of the
|
||||
module or, when no subsequent interaction point is encountered, is the
|
||||
result of evaluating the module's body expression.
|
||||
|
||||
When only "one-shot" continuations are needed, make multiple calls to
|
||||
start-interaction.
|
||||
|
||||
Example:
|
||||
(module m02 "../interaction.ss"
|
||||
(define (id x) x)
|
||||
(+ (start-interaction id)
|
||||
(start-interaction id)))
|
||||
|
||||
(require m02)
|
||||
(void? (dispatch-start 1))
|
||||
(= 3 (dispatch-start 2))
|
||||
(= 0 (dispatch-start -1))
|
||||
|
||||
In the next example, send/suspend is used to establish re-usable
|
||||
interaction points. An auxiliary module, table, is used to store
|
||||
continuations so that they may be used multiple times. Keys are associated
|
||||
with continuations in a hash table. The module body evaluates to a number,
|
||||
while interaction points within the computation yield the continuation key
|
||||
corresponding to that particular continuation. So a response is either a
|
||||
number or a key. A request consists of a key paired with a number. The
|
||||
initial request is ignored.
|
||||
|
||||
Example:
|
||||
(module table mzscheme
|
||||
(provide store-k
|
||||
lookup-k)
|
||||
|
||||
(define the-table (make-hash-table))
|
||||
|
||||
;; store-k: continuation -> symbol
|
||||
(define (store-k k)
|
||||
(let ([key (string->symbol (symbol->string (gensym 'key)))])
|
||||
(hash-table-put! the-table key k)
|
||||
key))
|
||||
|
||||
;; lookup-key: (list symbol number) -> continuation
|
||||
(define (lookup-k key-pair)
|
||||
(hash-table-get the-table (car key-pair) (lambda () #f))))
|
||||
|
||||
(module m06 "../interaction.ss"
|
||||
(require table)
|
||||
|
||||
;; gn: string -> number
|
||||
;; Get a number from the client.
|
||||
(define (gn which)
|
||||
(cadr
|
||||
(send/suspend
|
||||
(lambda (k)
|
||||
(let ([ignore (printf "Please send the ~a number.~n" which)])
|
||||
(store-k k))))))
|
||||
|
||||
;; get two numbers from the client and produce their sum
|
||||
(let ([ignore (start-interaction lookup-k)])
|
||||
(let ([result (+ (gn "first") (gn "second"))])
|
||||
(let ([ignore (printf "The answer is: ~s~n" result)])
|
||||
result))))
|
||||
|
||||
(require m06)
|
||||
|
||||
;; client code.
|
||||
(let* ([first-key (dispatch-start 'foo)]
|
||||
[second-key (dispatch `(,first-key 1))]
|
||||
[third-key (dispatch `(,first-key -7))])
|
||||
(values
|
||||
(= 3 (dispatch `(,second-key 2)))
|
||||
(= 4 (dispatch `(,second-key 3)))
|
||||
(zero? (dispatch `(,second-key -1)))
|
||||
(= -7 (dispatch `(,third-key 0)))
|
||||
(zero? (dispatch `(,third-key 7)))))
|
||||
|
||||
_Web Interaction Language_
|
||||
|
||||
_web-interaction.ss_
|
||||
|
||||
Use this language for writing servlets.
|
||||
|
||||
> start-servlet
|
||||
-> request
|
||||
Set the initial interaction point for the servlet. This analogous to
|
||||
start-interaction the request handler is built-in and decodes the
|
||||
continuation-id from the URL. The return value of start-servlet is the
|
||||
initial HTTP request.
|
||||
|
||||
> send/suspend
|
||||
(url -> response) -> request
|
||||
Send a response to the client and wait for the request. The continuation of
|
||||
the call to send/suspend is encoded in the URL that is passed to the
|
||||
argument of send/suspend. The argument should produce a request (usually an
|
||||
xexpr).
|
||||
|
||||
See collects/prototype-web-server/servlets/
|
||||
for examples of servlets written using the "web-interaction.ss" language.
|
|
@ -1,4 +0,0 @@
|
|||
(module info (lib "infotab.ss" "setup")
|
||||
(define name "Prototype Web Server")
|
||||
(define doc.txt "doc.txt"))
|
||||
|
Loading…
Reference in New Issue
Block a user