@code{(require 'html-form)} @defvar *html:output-port* Procedure names starting with @samp{html:} send their output to the port @var{*html:output-port*}. @var{*html:output-port*} is initially the current output port. @end defvar @defun html:atval txt Returns a string with character substitutions appropriate to send @var{txt} as an @dfn{attribute-value}. @cindex attribute-value @end defun @defun html:plain txt Returns a string with character substitutions appropriate to send @var{txt} as an @dfn{plain-text}. @cindex plain-text @end defun @defun html:comment line @dots{} Writes (using @code{html:printf}) the strings @var{lines} as HTML comments. @end defun @defun html:start-form method action The symbol @var{method} is either @code{get}, @code{head}, @code{post}, @code{put}, or @code{delete}. @code{html:start-form} prints the header for an HTML @dfn{form}. @cindex form @end defun @defun html:end-form pname submit-label @code{html:end-form} prints the footer for an HTML @dfn{form}. The string @var{submit-label} @cindex form appears on the button which submits the form. @end defun @defun html:start-page title Outputs headers for an HTML page named @var{title}. @end defun @defun html:end-page Outputs HTML codes to end a page. @end defun @defun command->html rdb command-table command method action The symbol @var{command-table} names a command table in the @var{rdb} relational database. @code{command->html} writes an HTML-2.0 @dfn{form} for command @var{command} to the @cindex form current-output-port. The @samp{SUBMIT} button, which is labeled @var{command}, invokes the URI @var{action} with method @var{method} with a hidden attribute @code{*command*} bound to the command symbol submitted. An action may invoke a CGI script (@samp{http://www.my-site.edu/cgi-bin/search.cgi}) or HTTP daemon (@samp{http://www.my-site.edu:8001}). This example demonstrates how to create a HTML-form for the @samp{build} command. @example (require (in-vicinity (implementation-vicinity) "build.scm")) (call-with-output-file "buildscm.html" (lambda (port) (fluid-let ((*html:output-port* port)) (html:start-page 'commands) (command->html build '*commands* 'build 'post (or "/cgi-bin/build.cgi" "http://localhost:8081/buildscm")) html:end-page))) @end example @end defun @c node HTTP and CGI service, Printing Scheme, HTML Forms, Textual Conversion Packages @section HTTP and CGI service @code{(require 'html-form)} @defun cgi:serve-command rdb command-table Reads a @samp{"POST"} or @samp{"GET"} query from @code{(current-input-port)} and executes the encoded command from @var{command-table} in relational-database @var{rdb}. This example puts up a plain-text page in response to a CGI query. @example (display "Content-Type: text/plain") (newline) (newline) (require 'html-form) (load (in-vicinity (implementation-vicinity) "build.scm")) (cgi:serve-command build '*commands*) @end example @end defun @defun serve-urlencoded-command rdb command-table urlencoded Reads attribute-value pairs from @var{urlencoded}, converts them to parameters and invokes the @var{rdb} command named by the parameter @code{*command*}. @end defun @defvar http:crlf @end defvar @defun http:send-status-line status-code reason @defunx http:send-header alist @end defun @defun http:serve-query input-port output-port serve-proc reads the @dfn{query-string} from @var{input-port}. If this is a valid @cindex query-string @samp{"POST"} or @samp{"GET"} query, then @code{http:serve-query} calls @var{serve-proc} with two arguments, the query-string and the header-alist. Otherwise, @code{http:serve-query} replies (to @var{output-port}) with appropriate HTML describing the problem. @end defun This example services HTTP queries from port 8081: @example (define socket (make-stream-socket AF_INET 0)) (socket:bind socket 8081) (socket:listen socket 10) (dynamic-wind (lambda () #f) (lambda () (do ((port (socket:accept socket) (socket:accept socket))) (#f) (dynamic-wind (lambda () #f) (lambda () (fluid-let ((*html:output-port* port)) (http:serve-query port port (lambda (query-string header) (http:send-header '(("Content-Type" . "text/plain"))) (with-output-to-port port (lambda () (serve-urlencoded-command build '*commands* query-string))))))) (lambda () (close-port port))))) (lambda () (close-port socket))) @end example @defun http:read-request-line port Reads the first non-blank line from @var{port} and, if successful, returns a list of three itmes from the request-line: @enumerate 0 @item Method Either one of the symbols @code{options}, @code{get}, @code{head}, @code{post}, @code{put}, @code{delete}, or @code{trace}; Or a string. @item Request-URI A string. At the minimum, it will be the string @samp{"/"}. @item HTTP-Version A string. For example, @samp{HTTP/1.0}. @end enumerate @end defun @defun cgi:read-query-string Reads the @dfn{query-string} from @code{(current-input-port)}. @cindex query-string @code{cgi:read-query-string} reads a @samp{"POST"} or @samp{"GET"} queries, depending on the value of @code{(getenv "REQUEST_METHOD")}. @end defun