mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-13 07:10:20 +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
|
@node URIs
|
||||||
@subsection Universal Resource Identifiers
|
@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
|
@example
|
||||||
(use-modules (web uri))
|
(use-modules (web uri))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@verbatim
|
The following procedures can be found in the @code{(web uri)}
|
||||||
A data type for Universal Resource Identifiers, as defined in RFC
|
module. Load it into your Guile, using a form like the above, to have
|
||||||
3986.
|
access to them.
|
||||||
@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
|
|
||||||
|
|
||||||
@defun build-uri scheme [#:userinfo] [#:host] [#:port] [#:path] [#:query] [#:fragment] [#:validate?]
|
@defun build-uri scheme [#:userinfo] [#:host] [#:port] [#:path] [#:query] [#:fragment] [#:validate?]
|
||||||
Construct a URI object. If @var{validate?} is true, also run some
|
Construct a URI object. If @var{validate?} is true, also run some
|
||||||
consistency checks to make sure that the constructed URI is valid.
|
consistency checks to make sure that the constructed URI is valid.
|
||||||
@end defun
|
@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
|
@defun declare-default-port! scheme port
|
||||||
Declare a default port for the given URI scheme.
|
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
|
@node HTTP
|
||||||
@subsection The Hyper-Text Transfer Protocol
|
@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
|
@example
|
||||||
(use-modules (web http))
|
(use-modules (web http))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
This module has a number of routines to parse textual
|
The focus of the @code{(web http)} module is to parse and unparse
|
||||||
representations of HTTP data into native Scheme data structures.
|
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
|
Guile tries to follow RFCs fairly strictly---the road to perdition being
|
||||||
being paved with compatibility hacks---though some allowances are
|
paved with compatibility hacks---though some allowances are made for
|
||||||
made for not-too-divergent texts (like a quality of .2 which should
|
not-too-divergent texts.
|
||||||
be 0.2, etc).
|
|
||||||
|
|
||||||
@defspec header-decl?
|
The first bit is to define a registry of parsers, validators, and
|
||||||
@end defspec
|
unparsers, keyed by header name. That is the function of the
|
||||||
|
@code{<header-decl>} object.
|
||||||
|
|
||||||
@defspec make-header-decl
|
@defun make-header-decl sym name multiple? parser validator writer
|
||||||
@end defspec
|
@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
|
@table @code
|
||||||
@end defspec
|
@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
|
@defun declare-header! sym name [#:multiple?] [#:parser] [#:validator] [#:writer]
|
||||||
@end defspec
|
Make a header declaration, as above, and register it by symbol and by
|
||||||
|
name.
|
||||||
@defspec header-decl-multiple?
|
@end defun
|
||||||
@end defspec
|
|
||||||
|
|
||||||
@defspec header-decl-parser
|
|
||||||
@end defspec
|
|
||||||
|
|
||||||
@defspec header-decl-validator
|
|
||||||
@end defspec
|
|
||||||
|
|
||||||
@defspec header-decl-writer
|
|
||||||
@end defspec
|
|
||||||
|
|
||||||
@defun lookup-header-decl name
|
@defun lookup-header-decl name
|
||||||
Return the @var{header-decl} object registered for the given @var{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.
|
a case-insensitive fashion.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defun declare-header! sym name [#:multiple?] [#:parser] [#:validator] [#:writer]
|
@defun valid-header? sym val
|
||||||
Define a parser, validator, and writer for the HTTP header, @var{name}.
|
Returns a true value iff @var{val} is a valid Scheme value for the
|
||||||
|
header with name @var{sym}.
|
||||||
@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.
|
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
|
Now that we have a generic interface for reading and writing headers, we
|
||||||
|
do just that.
|
||||||
|
|
||||||
@defun read-header port
|
@defun read-header port
|
||||||
Reads one HTTP header from @var{port}. Returns two values: the header
|
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
|
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.
|
found, both the header name and the value are returned as strings.
|
||||||
@end defun
|
@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
|
@defun write-header name val port
|
||||||
Writes the given header name and value to @var{port}. If @var{name} is a
|
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
|
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.
|
\r\n, as the user might want to add another header.
|
||||||
@end defun
|
@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]
|
@defun parse-http-method str [start] [end]
|
||||||
Parse an HTTP method from @var{str}. The result is an upper-case symbol,
|
Parse an HTTP method from @var{str}. The result is an upper-case symbol,
|
||||||
like @code{GET}.
|
like @code{GET}.
|
||||||
|
@ -269,26 +305,26 @@ Write the first line of an HTTP response to @var{port}.
|
||||||
(use-modules (web request))
|
(use-modules (web request))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@defspec request?
|
@defun request?
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec request-method
|
@defun request-method
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec request-uri
|
@defun request-uri
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec request-version
|
@defun request-version
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec request-headers
|
@defun request-headers
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec request-meta
|
@defun request-meta
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec request-port
|
@defun request-port
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defun read-request port [meta]
|
@defun read-request port [meta]
|
||||||
Read an HTTP request from @var{port}, optionally attaching the given
|
Read an HTTP request from @var{port}, optionally attaching the given
|
||||||
|
@ -389,25 +425,25 @@ request @var{r}.
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
|
||||||
@defspec response?
|
@defun response?
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec response-version
|
@defun response-version
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec response-code
|
@defun response-code
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defun response-reason-phrase response
|
@defun response-reason-phrase response
|
||||||
Return the reason phrase given in @var{response}, or the standard reason
|
Return the reason phrase given in @var{response}, or the standard reason
|
||||||
phrase for the response's code.
|
phrase for the response's code.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
@defspec response-headers
|
@defun response-headers
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defspec response-port
|
@defun response-port
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defun read-response port
|
@defun read-response port
|
||||||
Read an HTTP response from @var{port}, optionally attaching the given
|
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.
|
the server socket.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
@defspec define-server-impl name open read write close
|
@defun define-server-impl name open read write close
|
||||||
@end defspec
|
@end defun
|
||||||
|
|
||||||
@defun lookup-server-impl impl
|
@defun lookup-server-impl impl
|
||||||
Look up a server implementation. If @var{impl} is a server
|
Look up a server implementation. If @var{impl} is a server
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue