Next: , Previous: , Up: Web   [Contents][Index]

7.3.3 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, see Web Client, and see Web Server. Otherwise, load the HTTP module, and read on.

(use-modules (web http))

The focus of the (web http) module is to parse and unparse standard HTTP headers, representing them to Guile as native data structures. For example, a Date: header will be represented as a SRFI-19 date record (see SRFI-19), rather than as a string.

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.

Header names are represented as lower-case symbols.

Scheme Procedure: string->header name

Parse name to a symbolic header name.

Scheme Procedure: header->string sym

Return the string form for the header named sym.

For example:

(string->header "Content-Length")
⇒ content-length
(header->string 'content-length)
⇒ "Content-Length"

(string->header "FOO")
⇒ foo
(header->string 'foo)
⇒ "Foo"

Guile keeps a registry of known headers, their string names, and some parsing and serialization procedures. If a header is unknown, its string name is simply its symbol name in title-case.

Scheme Procedure: known-header? sym

Return #t if sym is a known header, with associated parsers and serialization procedures, or #f otherwise.

Scheme Procedure: header-parser sym

Return the value parser for headers named sym. The result is a procedure that takes one argument, a string, and returns the parsed value. If the header isn’t known to Guile, a default parser is returned that passes through the string unchanged.

Scheme Procedure: header-validator sym

Return a predicate which returns #t if the given value is valid for headers named sym. The default validator for unknown headers is string?.

Scheme Procedure: header-writer sym

Return a procedure that writes values for headers named sym to a port. The resulting procedure takes two arguments: a value and a port. The default writer is display.

For more on the set of headers that Guile knows about out of the box, see HTTP Headers. To add your own, use the declare-header! procedure:

Scheme Procedure: declare-header! name parser validator writer [#:multiple?=#f]

Declare a parser, validator, and writer for a given header.

For example, let’s say you are running a web server behind some sort of proxy, and your proxy adds an X-Client-Address header, indicating the IPv4 address of the original client. You would like for the HTTP request record to parse out this header to a Scheme value, instead of leaving it as a string. You could register this header with Guile’s HTTP stack like this:

(declare-header! "X-Client-Address"
  (lambda (str)
    (inet-aton str))
  (lambda (ip)
    (and (integer? ip) (exact? ip) (<= 0 ip #xffffffff)))
  (lambda (ip port)
    (display (inet-ntoa ip) port)))
Scheme Procedure: declare-opaque-header! name

A specialised version of declare-header! for the case in which you want a header’s value to be returned/written “as-is”.

Scheme Procedure: valid-header? sym val

Return a true value if val is a valid Scheme value for the header with name sym, or #f otherwise.

Now that we have a generic interface for reading and writing headers, we do just that.

Scheme Procedure: read-header port

Read one HTTP header from port. Return two values: the header name and the parsed Scheme value. May raise an exception if the header was known but the value was invalid.

Returns the end-of-file object for both values if the end of the message body was reached (i.e., a blank line).

Scheme Procedure: parse-header name val

Parse val, a string, with the parser for the header named name. Returns the parsed value.

Scheme Procedure: write-header name val port

Write the given header name and value to port, using the writer from header-writer.

Scheme Procedure: read-headers port

Read the headers of an HTTP message from port, returning them as an ordered alist.

Scheme Procedure: write-headers headers port

Write the given header alist to port. Doesn’t write the final ‘\r\n’, as the user might want to add another header.

The (web http) module also has some utility procedures to read and write request and response lines.

Scheme Procedure: parse-http-method str [start] [end]

Parse an HTTP method from str. The result is an upper-case symbol, like GET.

Scheme Procedure: parse-http-version str [start] [end]

Parse an HTTP version from str, returning it as a major–minor pair. For example, HTTP/1.1 parses as the pair of integers, (1 . 1).

Scheme Procedure: parse-request-uri str [start] [end]

Parse a URI from an HTTP request line. Note that URIs in requests do not have to have a scheme or host name. The result is a URI object.

Scheme Procedure: read-request-line port

Read the first line of an HTTP request from port, returning three values: the method, the URI, and the version.

Scheme Procedure: write-request-line method uri version port

Write the first line of an HTTP request to port.

Scheme Procedure: read-response-line port

Read the first line of an HTTP response from port, returning three values: the HTTP version, the response code, and the “reason phrase”.

Scheme Procedure: write-response-line version code reason-phrase port

Write the first line of an HTTP response to port.

Next: , Previous: , Up: Web   [Contents][Index]