@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