7.3.6 HTTP Requests

(use-modules (web request))

The request module contains a data type for HTTP requests.

7.3.6.1 An Important Note on Character Sets

HTTP requests consist of two parts: the request proper, consisting of a request line and a set of headers, and (optionally) a body. The body might have a binary content-type, and even in the textual case its length is specified in bytes, not characters.

Therefore, HTTP is a fundamentally binary protocol. However the request line and headers are specified to be in a subset of ASCII, so they can be treated as text, provided that the port’s encoding is set to an ASCII-compatible one-byte-per-character encoding. ISO-8859-1 (latin-1) is just such an encoding, and happens to be very efficient for Guile.

So what Guile does when reading requests from the wire, or writing them out, is to set the port’s encoding to latin-1, and treating the request headers as text.

The request body is another issue. For binary data, the data is probably in a bytevector, so we use the R6RS binary output procedures to write out the binary payload. Textual data usually has to be written out to some character encoding, usually UTF-8, and then the resulting bytevector is written out to the port.

In summary, Guile reads and writes HTTP over latin-1 sockets, without any loss of generality.

7.3.6.2 Request API

Scheme Procedure: request? obj
Scheme Procedure: request-method request
Scheme Procedure: request-uri request
Scheme Procedure: request-version request
Scheme Procedure: request-headers request
Scheme Procedure: request-meta request
Scheme Procedure: request-port request

A predicate and field accessors for the request type. The fields are as follows:

method

The HTTP method, for example, GET.

uri

The URI as a URI record.

version

The HTTP version pair, like (1 . 1).

headers

The request headers, as an alist of parsed values.

meta

An arbitrary alist of other data, for example information returned in the sockaddr from accept (see Network Sockets and Communication).

port

The port on which to read or write a request body, if any.

Scheme Procedure: read-request port [meta=’()]

Read an HTTP request from port, optionally attaching the given metadata, meta.

As a side effect, sets the encoding on port to ISO-8859-1 (latin-1), so that reading one character reads one byte. See the discussion of character sets above, for more information.

Note that the body is not part of the request. Once you have read a request, you may read the body separately, and likewise for writing requests.

Scheme Procedure: build-request uri [#:method=’GET] [#:version=’(1 . 1)] [#:headers=’()] [#:port=#f] [#:meta=’()] [#:validate-headers?=#t]

Construct an HTTP request object. If validate-headers? is true, the headers are each run through their respective validators.

Scheme Procedure: write-request r port

Write the given HTTP request to port.

Return a new request, whose request-port will continue writing on port, perhaps using some transfer encoding.

Scheme Procedure: read-request-body r

Reads the request body from r, as a bytevector. Return #f if there was no request body.

Scheme Procedure: write-request-body r bv

Write bv, a bytevector, to the port corresponding to the HTTP request r.

The various headers that are typically associated with HTTP requests may be accessed with these dedicated accessors. See HTTP Headers, for more information on the format of parsed headers.

Scheme Procedure: request-accept request [default=’()]
Scheme Procedure: request-accept-charset request [default=’()]
Scheme Procedure: request-accept-encoding request [default=’()]
Scheme Procedure: request-accept-language request [default=’()]
Scheme Procedure: request-allow request [default=’()]
Scheme Procedure: request-authorization request [default=#f]
Scheme Procedure: request-cache-control request [default=’()]
Scheme Procedure: request-connection request [default=’()]
Scheme Procedure: request-content-encoding request [default=’()]
Scheme Procedure: request-content-language request [default=’()]
Scheme Procedure: request-content-length request [default=#f]
Scheme Procedure: request-content-location request [default=#f]
Scheme Procedure: request-content-md5 request [default=#f]
Scheme Procedure: request-content-range request [default=#f]
Scheme Procedure: request-content-type request [default=#f]
Scheme Procedure: request-date request [default=#f]
Scheme Procedure: request-expect request [default=’()]
Scheme Procedure: request-expires request [default=#f]
Scheme Procedure: request-from request [default=#f]
Scheme Procedure: request-host request [default=#f]
Scheme Procedure: request-if-match request [default=#f]
Scheme Procedure: request-if-modified-since request [default=#f]
Scheme Procedure: request-if-none-match request [default=#f]
Scheme Procedure: request-if-range request [default=#f]
Scheme Procedure: request-if-unmodified-since request [default=#f]
Scheme Procedure: request-last-modified request [default=#f]
Scheme Procedure: request-max-forwards request [default=#f]
Scheme Procedure: request-pragma request [default=’()]
Scheme Procedure: request-proxy-authorization request [default=#f]
Scheme Procedure: request-range request [default=#f]
Scheme Procedure: request-referer request [default=#f]
Scheme Procedure: request-te request [default=#f]
Scheme Procedure: request-trailer request [default=’()]
Scheme Procedure: request-transfer-encoding request [default=’()]
Scheme Procedure: request-upgrade request [default=’()]
Scheme Procedure: request-user-agent request [default=#f]
Scheme Procedure: request-via request [default=’()]
Scheme Procedure: request-warning request [default=’()]

Return the given request header, or default if none was present.

Scheme Procedure: request-absolute-uri r [default-host=#f] [default-port=#f] [default-scheme=#f]

A helper routine to determine the absolute URI of a request, using the host header and the default scheme, host and port. If there is no default scheme and the URI is not itself absolute, an error is signaled.