mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-10 22:10:21 +02:00
update web.texi
* doc/ref/web.texi (URIs, HTTP): Update these sections.
This commit is contained in:
parent
8db7e0947d
commit
299cd1a229
1 changed files with 128 additions and 92 deletions
220
doc/ref/web.texi
220
doc/ref/web.texi
|
@ -42,44 +42,58 @@ the thing? Read on!
|
|||
@node URIs
|
||||
@subsection Universal Resource Identifiers
|
||||
|
||||
Guile provides a standard data type for Universal Resource Identifiers
|
||||
(URIs), as defined in RFC 3986.
|
||||
|
||||
The generic URI syntax is as follows:
|
||||
|
||||
@example
|
||||
URI := scheme ":" ["//" [userinfo "@"] host [":" port]] path \
|
||||
[ "?" query ] [ "#" fragment ]
|
||||
@end example
|
||||
|
||||
So, all URIs have a scheme and a path. Some URIs have a host, and some
|
||||
of those have ports and userinfo. Any URI might have a query part or a
|
||||
fragment.
|
||||
|
||||
Userinfo is something of an abstraction, as some legacy URI schemes
|
||||
allowed userinfo of the form @code{@var{username}:@var{passwd}}.
|
||||
Passwords don't belong in URIs, so the RFC does not want to condone
|
||||
this, but neither can it say that what is before the @code{@} sign is
|
||||
just a username, so the RFC punts on the issue and calls it
|
||||
@dfn{userinfo}.
|
||||
|
||||
Also, strictly speaking, a URI with a fragment is a @dfn{URI
|
||||
reference}. A fragment is typically not serialized when sending a URI
|
||||
over the wire; that is, it is not part of the identifier of a resource.
|
||||
It only identifies a part of a given resource. But it's useful to have
|
||||
a field for it in the URI record itself, so we hope you will forgive the
|
||||
inconsistency.
|
||||
|
||||
@example
|
||||
(use-modules (web uri))
|
||||
@end example
|
||||
|
||||
@verbatim
|
||||
A data type for Universal Resource Identifiers, as defined in RFC
|
||||
3986.
|
||||
@end verbatim
|
||||
|
||||
@defspec uri?
|
||||
@end defspec
|
||||
|
||||
@defspec uri-scheme
|
||||
@end defspec
|
||||
|
||||
@defspec uri-userinfo
|
||||
@end defspec
|
||||
|
||||
@defspec uri-host
|
||||
@end defspec
|
||||
|
||||
@defspec uri-port
|
||||
@end defspec
|
||||
|
||||
@defspec uri-path
|
||||
@end defspec
|
||||
|
||||
@defspec uri-query
|
||||
@end defspec
|
||||
|
||||
@defspec uri-fragment
|
||||
@end defspec
|
||||
The following procedures can be found in the @code{(web uri)}
|
||||
module. Load it into your Guile, using a form like the above, to have
|
||||
access to them.
|
||||
|
||||
@defun build-uri scheme [#:userinfo] [#:host] [#:port] [#:path] [#:query] [#:fragment] [#:validate?]
|
||||
Construct a URI object. If @var{validate?} is true, also run some
|
||||
consistency checks to make sure that the constructed URI is valid.
|
||||
@end defun
|
||||
|
||||
@defun uri? x
|
||||
@defun uri-scheme uri
|
||||
@defunx uri-userinfo uri
|
||||
@defunx uri-host uri
|
||||
@defunx uri-port uri
|
||||
@defunx uri-path uri
|
||||
@defunx uri-query uri
|
||||
@defunx uri-fragment uri
|
||||
A predicate and field accessors for the URI record type.
|
||||
@end defun
|
||||
|
||||
@defun declare-default-port! scheme port
|
||||
Declare a default port for the given URI scheme.
|
||||
|
||||
|
@ -136,41 +150,66 @@ strings, and join the parts together with @code{/} as a delimiter.
|
|||
@node HTTP
|
||||
@subsection The Hyper-Text Transfer Protocol
|
||||
|
||||
The initial motivation for including web functionality in Guile, rather
|
||||
than rely on an external package, was to establish a standard base on
|
||||
which people can share code. To that end, we continue the focus on data
|
||||
types by providing a number of low-level parsers and unparsers for
|
||||
elements of the HTTP protocol.
|
||||
|
||||
If you are want to skip the low-level details for now and move on to web
|
||||
pages, @pxref{Web Server}. Otherwise, load the HTTP module, and read
|
||||
on.
|
||||
|
||||
@example
|
||||
(use-modules (web http))
|
||||
@end example
|
||||
|
||||
This module has a number of routines to parse textual
|
||||
representations of HTTP data into native Scheme data structures.
|
||||
The focus of the @code{(web http)} module is to parse and unparse
|
||||
standard HTTP headers, representing them to Guile as native data
|
||||
structures. For example, a @code{Date:} header will be represented as a
|
||||
SRFI-19 date record (@pxref{SRFI-19}), rather than as a string.
|
||||
|
||||
It tries to follow RFCs fairly strictly---the road to perdition
|
||||
being paved with compatibility hacks---though some allowances are
|
||||
made for not-too-divergent texts (like a quality of .2 which should
|
||||
be 0.2, etc).
|
||||
Guile tries to follow RFCs fairly strictly---the road to perdition being
|
||||
paved with compatibility hacks---though some allowances are made for
|
||||
not-too-divergent texts.
|
||||
|
||||
@defspec header-decl?
|
||||
@end defspec
|
||||
The first bit is to define a registry of parsers, validators, and
|
||||
unparsers, keyed by header name. That is the function of the
|
||||
@code{<header-decl>} object.
|
||||
|
||||
@defspec make-header-decl
|
||||
@end defspec
|
||||
@defun make-header-decl sym name multiple? parser validator writer
|
||||
@defunx header-decl? x
|
||||
@defunx header-decl-sym decl
|
||||
@defunx header-decl-name decl
|
||||
@defunx header-decl-multiple? decl
|
||||
@defunx header-decl-parser decl
|
||||
@defunx header-decl-validator decl
|
||||
@defunx header-decl-writer decl.
|
||||
A constructor, predicate, and field accessors for the
|
||||
@code{<header-decl>} type. The fields are as follows:
|
||||
|
||||
@defspec header-decl-sym
|
||||
@end defspec
|
||||
@table @code
|
||||
@item sym
|
||||
The symbol name for this header field, always in lower-case. For
|
||||
example, @code{"Content-Length"} has a symbolic name of
|
||||
@code{content-length}.
|
||||
@item name
|
||||
The string name of the header, in its preferred capitalization.
|
||||
@item multiple?
|
||||
@code{#t} iff this header may appear multiple times in a message.
|
||||
@item parser
|
||||
A procedure which takes a string and returns a parsed value.
|
||||
@item validator
|
||||
A predicate, returning @code{#t} iff the value is valid for this header.
|
||||
@item writer
|
||||
A writer, which writes a value to the port given in the second argument.
|
||||
@end table
|
||||
@end defun
|
||||
|
||||
@defspec header-decl-name
|
||||
@end defspec
|
||||
|
||||
@defspec header-decl-multiple?
|
||||
@end defspec
|
||||
|
||||
@defspec header-decl-parser
|
||||
@end defspec
|
||||
|
||||
@defspec header-decl-validator
|
||||
@end defspec
|
||||
|
||||
@defspec header-decl-writer
|
||||
@end defspec
|
||||
@defun declare-header! sym name [#:multiple?] [#:parser] [#:validator] [#:writer]
|
||||
Make a header declaration, as above, and register it by symbol and by
|
||||
name.
|
||||
@end defun
|
||||
|
||||
@defun lookup-header-decl name
|
||||
Return the @var{header-decl} object registered for the given @var{name}.
|
||||
|
@ -179,15 +218,14 @@ Return the @var{header-decl} object registered for the given @var{name}.
|
|||
a case-insensitive fashion.
|
||||
@end defun
|
||||
|
||||
@defun declare-header! sym name [#:multiple?] [#:parser] [#:validator] [#:writer]
|
||||
Define a parser, validator, and writer for the HTTP header, @var{name}.
|
||||
|
||||
@var{parser} should be a procedure that takes a string and returns a
|
||||
Scheme value. @var{validator} is a predicate for whether the given
|
||||
Scheme value is valid for this header. @var{writer} takes a value and a
|
||||
port, and writes the value to the port.
|
||||
@defun valid-header? sym val
|
||||
Returns a true value iff @var{val} is a valid Scheme value for the
|
||||
header with name @var{sym}.
|
||||
@end defun
|
||||
|
||||
Now that we have a generic interface for reading and writing headers, we
|
||||
do just that.
|
||||
|
||||
@defun read-header port
|
||||
Reads one HTTP header from @var{port}. Returns two values: the header
|
||||
name and the parsed Scheme value. May raise an exception if the header
|
||||
|
@ -206,11 +244,6 @@ found, the header name will be returned as a symbol. If a parser was not
|
|||
found, both the header name and the value are returned as strings.
|
||||
@end defun
|
||||
|
||||
@defun valid-header? sym val
|
||||
Returns a true value iff @var{val} is a valid Scheme value for the
|
||||
header with name @var{sym}.
|
||||
@end defun
|
||||
|
||||
@defun write-header name val port
|
||||
Writes the given header name and value to @var{port}. If @var{name} is a
|
||||
symbol, looks up a declared header and uses that writer. Otherwise the
|
||||
|
@ -227,6 +260,9 @@ Write the given header alist to @var{port}. Doesn't write the final
|
|||
\r\n, as the user might want to add another header.
|
||||
@end defun
|
||||
|
||||
The @code{(web http)} module also has some utility procedures to read
|
||||
and write request and response lines.
|
||||
|
||||
@defun parse-http-method str [start] [end]
|
||||
Parse an HTTP method from @var{str}. The result is an upper-case symbol,
|
||||
like @code{GET}.
|
||||
|
@ -269,26 +305,26 @@ Write the first line of an HTTP response to @var{port}.
|
|||
(use-modules (web request))
|
||||
@end example
|
||||
|
||||
@defspec request?
|
||||
@end defspec
|
||||
@defun request?
|
||||
@end defun
|
||||
|
||||
@defspec request-method
|
||||
@end defspec
|
||||
@defun request-method
|
||||
@end defun
|
||||
|
||||
@defspec request-uri
|
||||
@end defspec
|
||||
@defun request-uri
|
||||
@end defun
|
||||
|
||||
@defspec request-version
|
||||
@end defspec
|
||||
@defun request-version
|
||||
@end defun
|
||||
|
||||
@defspec request-headers
|
||||
@end defspec
|
||||
@defun request-headers
|
||||
@end defun
|
||||
|
||||
@defspec request-meta
|
||||
@end defspec
|
||||
@defun request-meta
|
||||
@end defun
|
||||
|
||||
@defspec request-port
|
||||
@end defspec
|
||||
@defun request-port
|
||||
@end defun
|
||||
|
||||
@defun read-request port [meta]
|
||||
Read an HTTP request from @var{port}, optionally attaching the given
|
||||
|
@ -389,25 +425,25 @@ request @var{r}.
|
|||
@end example
|
||||
|
||||
|
||||
@defspec response?
|
||||
@end defspec
|
||||
@defun response?
|
||||
@end defun
|
||||
|
||||
@defspec response-version
|
||||
@end defspec
|
||||
@defun response-version
|
||||
@end defun
|
||||
|
||||
@defspec response-code
|
||||
@end defspec
|
||||
@defun response-code
|
||||
@end defun
|
||||
|
||||
@defun response-reason-phrase response
|
||||
Return the reason phrase given in @var{response}, or the standard reason
|
||||
phrase for the response's code.
|
||||
@end defun
|
||||
|
||||
@defspec response-headers
|
||||
@end defspec
|
||||
@defun response-headers
|
||||
@end defun
|
||||
|
||||
@defspec response-port
|
||||
@end defspec
|
||||
@defun response-port
|
||||
@end defun
|
||||
|
||||
@defun read-response port
|
||||
Read an HTTP response from @var{port}, optionally attaching the given
|
||||
|
@ -569,8 +605,8 @@ If the user interrupts the loop, the @code{close} hook is called on
|
|||
the server socket.
|
||||
@end enumerate
|
||||
|
||||
@defspec define-server-impl name open read write close
|
||||
@end defspec
|
||||
@defun define-server-impl name open read write close
|
||||
@end defun
|
||||
|
||||
@defun lookup-server-impl impl
|
||||
Look up a server implementation. If @var{impl} is a server
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue