sunet/scheme/httpd/surflets/latex/surflet.tex

307 lines
12 KiB
TeX

\documentclass{article}
\usepackage[latin1]{inputenc}
\usepackage{alltt}
\usepackage{tex2page}
\author{Andreas Bernauer \and Martin Gasbichler}
\title{The Servlet Handler of the \textit{SUnet} Web Server}
\input{../../../doc/latex/decls}
\begin{document}
\maketitle
\begin{abstract}
\noindent The Scheme Untergrund Network Package (\textit{SUnet} for
short) comes along with a modular web server. The servlet handler
described here extends it by the capability of writing programs in
Scheme, that yield an HTML page.
Suspending of servlet computation.
Using Oleg's SXML.
blabla and something more.
\end{abstract}
\section{How to write a servlet}
Use this skeleton to get started quickly:
\begin{alltt}
(define-structure servlet servlet-interface
(open servlets
scsh
scheme
; more packages...
)
(begin
(define (main req)
; This is the entry point.
)
;; Add more definitions here.
))
\end{alltt}
See the examples for further informations.
\section{The \texttt{servlets} structure}
\defun{send/suspend}{response-maker}{request}
\defunx{send/finish}{response}{\noreturn}
\defunx{send}{response}{\noreturn}
\defunx{send-html/suspend}{SXML-maker}{request}
\defunx{send-html/finish}{SXML}{\noreturn}
\defunx{send-html}{SXML}{\noreturn}
\begin{desc}
These procedures let the server send a response to the client. From
the servlet's point of view, \ex{send/suspend} suspends the current
computation, calls \semvar{response-maker} with an argument and lets
the server send it to the client. \semvar{response-maker} is a
procedure getting one argument, the ``continuation address'' and
yielding a valid response---\ie an \ex{httpd} \ex{response}
object. See the manual of the \ex{httpd} for details about
generating such an object. If you use SXML, you won't need the
details, though. If the browser sends a request to the
``continuation address'', the computation of the servlet is resumed
and \ex{send/suspend} returns the browser's request. Note that,
technically, the computation is not really suspended---it just
looks this way from the servlet's point of view.
\ex{send/finish} returns the \semvar{response} to the server and
finishes the computation of the servlet---\ie the instance of the
servlet will not accept any more requests. \semvar{response} must be
a valid \ex{httpd} \ex{response} object.
\ex{send} returns the \semvar{response} to the server. It does not
finish the computation of the servlet, although it does not
return---\ie the instance of the servlet may accept future
requests. Usually, you won't need this procedure.
The \ex{send-html...} procedures do the same as their counterparts
sans \ex{-html}, except that the expect SXML objects rather than
response objects. SXML objects are lists that describe an HTML
page---\eg
\begin{alltt}
`(html (title "My Homepage")
(body (h1 "Welcome to my homepage!")
(p "How are you?")))
\end{alltt}
\end{desc}
\defun{form-query}{string}{bindings}
\defunx{get-bindings}{req}{bindings}
\begin{desc}
\ex{form-query} does the same as \ex{cgi-form-query}: It parses the
\semvar{string} that may be the search part of a \ex{GET} request
line into an association list of bindings---\eg
\begin{alltt}
(form-query "button=on&select=13")
==> '(("button" . "on") ("select" . "13"))
\end{alltt}
You can get the search part of a \ex{GET} request \ex{request} by
using \codex{(http-url:search (request:url request))} This is how
\semvar{get-bindings} accesses the search part, if \ex{req} is a
\ex{GET} request. If it is a \ex{POST} request, though, it reads the
string from the associated input port. In both cases, \ex{GET} or
\ex{POST} request it returns an association list of bindings as
\ex{form-query} does. Note that as \ex{get-bindings} reads from the
associated input port, you must not invoke it more than once for a
specific \ex{POST} request---doing so on a \ex{GET} request does not
harm. This restriction should be removed in future versions.
\end{desc}
\defun{extract-bindings}{bindings name}{strings}
\defunx{extract-single-binding}{bindings name}{string}
\begin{desc}
\ex{extract-bindings} returns a list of \semvar{strings}, that are
values of the \semvar{name} in \semvar{bindings}.
\ex{extract-single-binding} returns the value of \semvar{name} in
\semvar{bindings}. If there are more than one or zero \semvar{name}s
in \semvar{bindings}, an error is signalled. \Eg
\begin{alltt}
(extract-bindings (form-query "button=on&select=13") "select")
==> '("13")
(extract-single-binding (form-query "button=on&select=13") "button")
==> "on"
\end{alltt}
\end{desc}
\subsection{Forms and Input Fields}
\FIXME{Prolog to input fields}
\defun{generate-input-field-name}{prefix}{string}
\begin{desc}
Generates a pseudo-unique name with prefix
\semvar{prefix}. Precisely, a continuously increased number is
append to \semvar{prefix}. This gives us good chances, that the name
is unique---we cannot check the uniqueness, though.
\end{desc}
\defun{make-input-field}{name transformer SXML}{input-field}
\defunx{make-upper-input-field}{transformer SXML}{input-field}
\begin{desc}
\ex{make-input-field} creates an input field for a web
form. \semvar{SXML} is an SXML-reprentation of the
input-field. \semvar{transformer} gets the value of the input field
as a string and returns the scheme value of the input field. \Eg you
can do a string to number conversion with this (see
\ex{make-number-input-field below}). \semvar{name} Is used to acces
the value of the input field out of a request---it should be
included in \semvar{SXML} to let the machinery work. This package
provides several constructors for various types of input fields, so
you usually don't have to bother about it.
\ex{make-upper-input-field} creates a special kind of an
input-field: the \semvar{transformer} function does not get only one
value, but the whole bindings list. See the byte input widget for an
example.
The returned \semvar{input-field}s can be used as-is in SXML.
\end{desc}
\defun{make-text-input-field}{\ovar{default-text \ovar{attributes}}}{input-field}
\defunx{make-hidden-input-field}{value \ovar{attributes}}{input-field}
\defunx{make-password-input-field}{\ovar{attributes}}{input-field}
\defunx{make-number-input-field}{\ovar{default \ovar{attributes}}}{input-field}
\defunx{make-textarea-input-field}{\ovar{default-text \ovar{attributes}}}{input-field}
\defunx{make-select-input-field}{options \ovar{attributes}}{input-field}
\defunx{make-checkbox-input-field}{\ovar{value \ovar{attributes}}}{input-field}
\defunx{make-radio-input-fields}{values \ovar{attributes}}{input-fields}
\begin{desc}
These functions generate various kind of \semvar{input-field}s. The
\semvar{attributes} argument contains a list of attributes in SXML
notation---\eg \ex{'(@ (id 13))}. It is appended to the attributes
of the input field that are generated by the functions.
\ex{make-text-input-field} creates a text input field, optionally
filled out with \semvar{default-text}. \ex{make-hidden-input-field}
creates a hidden input field with value
\semvar{value}. \ex{make-password-input-field} creates a password
input field. \ex{make-number-input-field} creates a text input
field, whose value is a number. An error is signalled, if the string
cannot be interpreted as a number in the sense of
\ex{string->number}. The number input field may have a default
filling of \semvar{default}, that may be a string, a symbol or a
number. \ex{make-textarea-input-field} creates a textarea input
field, optionally filled out with \semvar{default-text}. You may
want to give the \ex{cols} and \ex{rows} attributes
explicitly. \ex{make-select-input-field} creates a select input
field that is either displayed as scrollable list (the \ex{size}
attribute is not given or greater than 1) or a drop down list (the
\ex{size} attribute is equal to 1). The items of the list is given
in \semvar{options} and the result of the select input field is a
list of all selected items in \semvar{options}.\FIXME{let select
input fields really return a list of values in
servlets.scm}\ex{make-checkbox-input-field} creats a checkbox input
field, optional with a value of \semvar{value}. If \semvar{value} is
not given, the browser usually returns
``on''. \ex{make-radio-input-fields} is somewhat special as it
returns a \emph{list} of radio button input fields. The reason is
that radio input fields must have the same name, but the text that
surrounds the radio input fields is not included in the definition
of the input field. \Ie you must split the resulting list up into
its parts and distribute them among your HTML text. The value of the
\textit{n}th radio input field is the \textit{n}th element of
\semvar{values}.
\end{desc}
\defun{make-submit-button}{\ovar{caption \ovar{attributes}}}{input-field}
\defunx{make-reset-button}{\ovar{caption \ovar{attributes}}}{input-field}
\defunx{make-image-button}{source \ovar{attributes}}{input-field}
\begin{desc}
The \semvar{attributes} of all functions are appended to the
generated attributes of the input fields.
\ex{make-submit-button} creates a submit button with an optional
caption \semvar{caption}. If you omit the caption, the browser will
choose a default value like ``Submit''. \ex{make-reset-button}
creates a reset button that clears all entry fields of the form. If
you omit the \semvar{cpation}, the browser will choose a default
value for the caption of the button---\eg ``Reset''---otherwise
\semvar{caption}. \ex{make-image-button} creates an image
button using the image located at \semvar{source}.
\end{desc}
\defun{input-field-binding}{input-field bindings}{binding}
\defunx{input-field-value}{input-field bindings}{value}
\begin{desc}
\ex{input-field-binding} returns the binding for
\semvar{input-field} out of \semvar{bindings}.
\ex{input-field-value} returns the value for the input field, using
the transformer function of the input field.
\end{desc}
\subsection{Return addresses}
\FIXME{Prolog to return addresses}
\defun{make-address}{}{address}
\begin{desc}
\ex{make-address} creates a return \semvar{address}, that may be
used to create links in the output of the servlet. With this, the
servlet can check which link was clicked by the user.
\semvar{address} is a procedure expecting the prefix of the
URL. Usually, it is called with the contination address given by
\ex{send-html/suspend} (or \ex{send/suspend}).
\end{desc}
\defun{returned-via?}{address bindings}{boolean}
\begin{desc}
Returns \sharpt, if the user has clicked on the link generated by
\semvar{address}.
\end{desc}
\defun{make-callback}{procedure}{url}
\begin{desc}
\semvar{procedure} Is a function accepting one argument, a request
object. If the browser requests to a \semvar{url} returned by
\ex{make-callback}, \semvar{procedure} will be called.
\end{desc}
\subsection{Servlet data}
\FIXME{Prolog to servlet data}
\defun{set-instance-data!}{new-value}{\undefined}
\defunx{get-instance-data}{}{value}
\begin{desc}
\ex{set-instance-data!} saves \semvar{new-value} linked with the
current instance of the servlet. \ex{get-instance-data} returns this
linked value.
\end{desc}
\subsection{Data out of date}
\FIXME{Prolog to data ouf of date}
\defun{make-outdater}{}{outdater}
\begin{desc}
Creates an \ex{outdater} object. In conjunction with
\ex{if-outdated} if ensures, that a specific part of you program is
executed only once.
\end{desc}
\dfn{if-outdated}{outdater consequence alternative}{value(s)}{syntax}
\begin{desc}
This form ensures that code protected by \semvar{outdater} is
executed only once. If outdater hasn't been used in this form
previously, the \semvar{alternative} is evaluated and
\ex{if-outdated} returns whatever \semvar{alternative} returns. As a
side effect, \semvar{outdater} is marked used. In future uses of
this form with the same \semvar{outdater}, the \semvar{consequence}
is evaluated and \ex{if-outdated} returns whatever
\semvar{consequence} returns.
\end{desc}
\defun{show-outdated}{new-url}{\noreturn}
\begin{desc}
\ex{show-outdated} sends a message to the browser indicating that
the data is out of date. If \semvar{url} has a true value, it is
shown as a reload address. This procedure is helpful in conjunction
with \ex{if-outdated}.
\end{desc}
\end{document}