\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}