358 lines
15 KiB
TeX
358 lines
15 KiB
TeX
\documentclass{article}
|
|
|
|
\usepackage[latin1]{inputenc}
|
|
\usepackage{alltt}
|
|
\usepackage{tex2page}
|
|
|
|
\author{Andreas Bernauer \and Martin Gasbichler}
|
|
\title{The SUrflet Handler of the \textit{SUnet} Web Server}
|
|
|
|
\input{../../../doc/latex/decls}
|
|
\newcommand{\attrib}[1]{\textsf{#1}}
|
|
\newcommand{\ovar}[1]{\mbox{\textnormal{[}\frenchspacing\it{#1}\textnormal{]}}}
|
|
%FIXME-command: types out the desired FIXME
|
|
\newcommand{\FIXME}[1]%
|
|
{\typeout{}\typeout{****** FIXME ***** #1}\typeout{}%
|
|
\textsf{[#1]}}
|
|
|
|
\begin{document}
|
|
\maketitle
|
|
\begin{abstract}
|
|
\noindent [THIS FILE IS NOT AT ALL UP TO DATE. However, some specs
|
|
are still true. See the sources and the example SUrflets for up to
|
|
date info.]\\ \noindent The Scheme Untergrund Network Package
|
|
(\textit{SUnet} for short) comes along with a modular web
|
|
server. The SUrflet handler described here extends it by the
|
|
capability of writing programs in Scheme, that yield an HTML page.
|
|
|
|
Suspending of SUrflet computation.
|
|
Using Oleg's SXML.
|
|
|
|
blabla and something more.
|
|
\end{abstract}
|
|
|
|
\section{How to write a SUrflet}
|
|
|
|
Use this skeleton to get started quickly:
|
|
\begin{alltt}
|
|
(define-structure surflet surflet-interface
|
|
(open surflets
|
|
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{surflets} 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 SUrflet'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 SUrflet 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 SUrflet's point of view.
|
|
|
|
\ex{send/finish} returns the \semvar{response} to the server and
|
|
finishes the computation of the SUrflet---\ie{} the instance of the
|
|
SUrflet 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 SUrflet, although it does not
|
|
return---\ie{} the instance of the SUrflet 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}
|
|
|
|
The SXML object is translated into plain HTML by the
|
|
procedures. They recognize higher the following order tags. You may
|
|
specify your own tags using the SSAX library.
|
|
\end{desc}
|
|
|
|
\dfn{URL}{target \ovar{SXML ...}}{link}{tag}
|
|
\begin{desc}
|
|
The \ex{URL} tag creates a hyper link to \semvar{target}, described
|
|
with \semvar{SXML}. This corresponds to the \ex{a} tag in HTML.
|
|
\end{desc}
|
|
|
|
\dfn{plain-html}{\ovar{text ...}}{HTML}{tag}
|
|
\begin{desc}
|
|
This is for quoting text, that you want to be put into the resulting
|
|
HTML page as-is. Of course, you can blow up the created HTML page
|
|
with this, you've been warned.
|
|
\end{desc}
|
|
|
|
\dfn{surflet-form}{address \ovar{method} \ovar{attributes} \ovar{SXML
|
|
...}}{form}{tag}
|
|
\begin{desc}
|
|
This creates an HTML form. Its \attrib{action} attribute will be
|
|
\semvar{address}---\ie{} the browser will send the form data to
|
|
\semvar{address}. With \semvar{method} you can specify how the form
|
|
data will be sent: \ex{'get} or \ex{'GET} denote a \ex{GET} request,
|
|
\ex{'post} or \ex{'POST} denote a \ex{POST} request. Any other value
|
|
will cause en error. \semvar{attributes} Are further attributes you
|
|
want to add to the form---\eg{}\attrib{target}. Note if you specify
|
|
the \attrib{enctype} to be something else than
|
|
\ex{application/x-www-form-urlencoded} you have to decode the
|
|
response on yourself---\ie{} you must not use the helper functions
|
|
listed below.
|
|
\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{multiple?} \ovar{attributes}}{input-field}
|
|
\defunx{make-checkbox-input-field}{\ovar{checked?} \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 \attrib{cols} and \attrib{rows} attributes
|
|
explicitly. \ex{make-select-input-field} creates a select input
|
|
field of the items given in \semvar{options}. Depending on a given
|
|
\attrib{size} attribute the select input field will be displayed as
|
|
a scrollable list or a dropdown list (see a reference to HTML for
|
|
details). If \semvar{multiple?} is true, the select input field will
|
|
allow multiple selections. In this case, \ex{input-field-value} will
|
|
return a (possibly empty) list of all selected items. Otherwise, the
|
|
selected string is returned. \ex{make-checkbox-input-field} creates
|
|
a checkbox input field, optionally with a value of
|
|
\semvar{value}. If \semvar{value} is not given, the browser usually
|
|
returns ``on''. If \semvar{checked?} has a true value, the checkbox
|
|
will initially be checked. \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{raw-input-field-value}{input-field bindings}{value}
|
|
\defunx{input-field-value}{input-field bindings \ovar{default}}{value}
|
|
\begin{desc}
|
|
\ex{input-field-binding} returns the binding for
|
|
\semvar{input-field} in \semvar{bindings}.
|
|
\ex{raw-input-field-value} returns the value for
|
|
\semvar{input-field}, using the transformer function of the input
|
|
field that was specified at its creation time. It is an error, if
|
|
\semvar{input-field}'s value is not specified by the
|
|
\semvar{bindings} or the transformer function yields an error.
|
|
\semvar{input-field-value} does the same as
|
|
\semvar{raw-input-field-value}, except that it will return
|
|
\semvar{default}, that defaults to \sharpf, in case of an
|
|
error.
|
|
\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 SUrflet. With this, the
|
|
SUrflet 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{SUrflet data}
|
|
\FIXME{Prolog to SUrflet 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 SUrflet. \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}
|