7.3.4 HTTP Headers

In addition to defining the infrastructure to parse headers, the (web http) module defines specific parsers and unparsers for all headers defined in the HTTP/1.1 standard.

For example, if you receive a header named ‘Accept-Language’ with a value ‘en, es;q=0.8’, Guile parses it as a quality list (defined below):

(parse-header 'accept-language "en, es;q=0.8")
⇒ ((1000 . "en") (800 . "es"))

The format of the value for ‘Accept-Language’ headers is defined below, along with all other headers defined in the HTTP standard. (If the header were unknown, the value would have been returned as a string.)

For brevity, the header definitions below are given in the form, Type name, indicating that values for the header name will be of the given Type. Since Guile internally treats header names in lower case, in this document we give types title-cased names. A short description of the each header’s purpose and an example follow.

For full details on the meanings of all of these headers, see the HTTP 1.1 standard, RFC 2616.

7.3.4.1 HTTP Header Types

Here we define the types that are used below, when defining headers.

HTTP Header Type: Date

A SRFI-19 date.

HTTP Header Type: KVList

A list whose elements are keys or key-value pairs. Keys are parsed to symbols. Values are strings by default. Non-string values are the exception, and are mentioned explicitly below, as appropriate.

HTTP Header Type: SList

A list of strings.

HTTP Header Type: Quality

An exact integer between 0 and 1000. Qualities are used to express preference, given multiple options. An option with a quality of 870, for example, is preferred over an option with quality 500.

(Qualities are written out over the wire as numbers between 0.0 and 1.0, but since the standard only allows three digits after the decimal, it’s equivalent to integers between 0 and 1000, so that’s what Guile uses.)

HTTP Header Type: QList

A quality list: a list of pairs, the car of which is a quality, and the cdr a string. Used to express a list of options, along with their qualities.

HTTP Header Type: ETag

An entity tag, represented as a pair. The car of the pair is an opaque string, and the cdr is #t if the entity tag is a “strong” entity tag, and #f otherwise.

7.3.4.2 General Headers

General HTTP headers may be present in any HTTP message.

HTTP Header: KVList cache-control

A key-value list of cache-control directives. See RFC 2616, for more details.

If present, parameters to max-age, max-stale, min-fresh, and s-maxage are all parsed as non-negative integers.

If present, parameters to private and no-cache are parsed as lists of header names, as symbols.

(parse-header 'cache-control "no-cache,no-store"
⇒ (no-cache no-store)
(parse-header 'cache-control "no-cache=\"Authorization,Date\",no-store"
⇒ ((no-cache . (authorization date)) no-store)
(parse-header 'cache-control "no-cache=\"Authorization,Date\",max-age=10"
⇒ ((no-cache . (authorization date)) (max-age . 10))
HTTP Header: List connection

A list of header names that apply only to this HTTP connection, as symbols. Additionally, the symbol ‘close’ may be present, to indicate that the server should close the connection after responding to the request.

(parse-header 'connection "close")
⇒ (close)
HTTP Header: Date date

The date that a given HTTP message was originated.

(parse-header 'date "Tue, 15 Nov 1994 08:12:31 GMT")
⇒ #<date ...>
HTTP Header: KVList pragma

A key-value list of implementation-specific directives.

(parse-header 'pragma "no-cache, broccoli=tasty")
⇒ (no-cache (broccoli . "tasty"))
HTTP Header: List trailer

A list of header names which will appear after the message body, instead of with the message headers.

(parse-header 'trailer "ETag")
⇒ (etag)
HTTP Header: List transfer-encoding

A list of transfer codings, expressed as key-value lists. The only transfer coding defined by the specification is chunked.

(parse-header 'transfer-encoding "chunked")
⇒ ((chunked))
HTTP Header: List upgrade

A list of strings, indicating additional protocols that a server could use in response to a request.

(parse-header 'upgrade "WebSocket")
⇒ ("WebSocket")

FIXME: parse out more fully?

HTTP Header: List via

A list of strings, indicating the protocol versions and hosts of intermediate servers and proxies. There may be multiple via headers in one message.

(parse-header 'via "1.0 venus, 1.1 mars")
⇒ ("1.0 venus" "1.1 mars")
HTTP Header: List warning

A list of warnings given by a server or intermediate proxy. Each warning is a itself a list of four elements: a code, as an exact integer between 0 and 1000, a host as a string, the warning text as a string, and either #f or a SRFI-19 date.

There may be multiple warning headers in one message.

(parse-header 'warning "123 foo \"core breach imminent\"")
⇒ ((123 "foo" "core-breach imminent" #f))

7.3.4.3 Entity Headers

Entity headers may be present in any HTTP message, and refer to the resource referenced in the HTTP request or response.

HTTP Header: List allow

A list of allowed methods on a given resource, as symbols.

(parse-header 'allow "GET, HEAD")
⇒ (GET HEAD)
HTTP Header: List content-encoding

A list of content codings, as symbols.

(parse-header 'content-encoding "gzip")
⇒ (gzip)
HTTP Header: List content-language

The languages that a resource is in, as strings.

(parse-header 'content-language "en")
⇒ ("en")
HTTP Header: UInt content-length

The number of bytes in a resource, as an exact, non-negative integer.

(parse-header 'content-length "300")
⇒ 300
HTTP Header: URI content-location

The canonical URI for a resource, in the case that it is also accessible from a different URI.

(parse-header 'content-location "http://example.com/foo")
⇒ #<<uri> ...>
HTTP Header: String content-md5

The MD5 digest of a resource.

(parse-header 'content-md5 "ffaea1a79810785575e29e2bd45e2fa5")
⇒ "ffaea1a79810785575e29e2bd45e2fa5"
HTTP Header: List content-range

Range specification as a list of three elements: the symbol bytes, either the symbol * or a pair of integers indicating the byte range, and either * or an integer indicating the instance length. Used to indicate that a response only includes part of a resource.

(parse-header 'content-range "bytes 10-20/*")
⇒ (bytes (10 . 20) *)
HTTP Header: List content-type

The MIME type of a resource, as a symbol, along with any parameters.

(parse-header 'content-type "text/plain")
⇒ (text/plain)
(parse-header 'content-type "text/plain;charset=utf-8")
⇒ (text/plain (charset . "utf-8"))

Note that the charset parameter is something of a misnomer, and the HTTP specification admits this. It specifies the encoding of the characters, not the character set.

HTTP Header: Date expires

The date/time after which the resource given in a response is considered stale.

(parse-header 'expires "Tue, 15 Nov 1994 08:12:31 GMT")
⇒ #<date ...>
HTTP Header: Date last-modified

The date/time on which the resource given in a response was last modified.

(parse-header 'expires "Tue, 15 Nov 1994 08:12:31 GMT")
⇒ #<date ...>

7.3.4.4 Request Headers

Request headers may only appear in an HTTP request, not in a response.

HTTP Header: List accept

A list of preferred media types for a response. Each element of the list is itself a list, in the same format as content-type.

(parse-header 'accept "text/html,text/plain;charset=utf-8")
⇒ ((text/html) (text/plain (charset . "utf-8")))

Preference is expressed with quality values:

(parse-header 'accept "text/html;q=0.8,text/plain;q=0.6")
⇒ ((text/html (q . 800)) (text/plain (q . 600)))
HTTP Header: QList accept-charset

A quality list of acceptable charsets. Note again that what HTTP calls a “charset” is what Guile calls a “character encoding”.

(parse-header 'accept-charset "iso-8859-5, unicode-1-1;q=0.8")
⇒ ((1000 . "iso-8859-5") (800 . "unicode-1-1"))
HTTP Header: QList accept-encoding

A quality list of acceptable content codings.

(parse-header 'accept-encoding "gzip,identity=0.8")
⇒ ((1000 . "gzip") (800 . "identity"))
HTTP Header: QList accept-language

A quality list of acceptable languages.

(parse-header 'accept-language "cn,en=0.75")
⇒ ((1000 . "cn") (750 . "en"))
HTTP Header: Pair authorization

Authorization credentials. The car of the pair indicates the authentication scheme, like basic. For basic authentication, the cdr of the pair will be the base64-encoded ‘user:pass’ string. For other authentication schemes, like digest, the cdr will be a key-value list of credentials.

(parse-header 'authorization "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
⇒ (basic . "QWxhZGRpbjpvcGVuIHNlc2FtZQ==")
HTTP Header: List expect

A list of expectations that a client has of a server. The expectations are key-value lists.

(parse-header 'expect "100-continue")
⇒ ((100-continue))
HTTP Header: String from

The email address of a user making an HTTP request.

(parse-header 'from "bob@example.com")
⇒ "bob@example.com"
HTTP Header: Pair host

The host for the resource being requested, as a hostname-port pair. If no port is given, the port is #f.

(parse-header 'host "gnu.org:80")
⇒ ("gnu.org" . 80)
(parse-header 'host "gnu.org")
⇒ ("gnu.org" . #f)
HTTP Header: *|List if-match

A set of etags, indicating that the request should proceed if and only if the etag of the resource is in that set. Either the symbol *, indicating any etag, or a list of entity tags.

(parse-header 'if-match "*")
⇒ *
(parse-header 'if-match "asdfadf")
⇒ (("asdfadf" . #t))
(parse-header 'if-match W/"asdfadf")
⇒ (("asdfadf" . #f))
HTTP Header: Date if-modified-since

Indicates that a response should proceed if and only if the resource has been modified since the given date.

(parse-header 'if-modified-since "Tue, 15 Nov 1994 08:12:31 GMT")
⇒ #<date ...>
HTTP Header: *|List if-none-match

A set of etags, indicating that the request should proceed if and only if the etag of the resource is not in the set. Either the symbol *, indicating any etag, or a list of entity tags.

(parse-header 'if-none-match "*")
⇒ *
HTTP Header: ETag|Date if-range

Indicates that the range request should proceed if and only if the resource matches a modification date or an etag. Either an entity tag, or a SRFI-19 date.

(parse-header 'if-range "\"original-etag\"")
⇒ ("original-etag" . #t)
HTTP Header: Date if-unmodified-since

Indicates that a response should proceed if and only if the resource has not been modified since the given date.

(parse-header 'if-not-modified-since "Tue, 15 Nov 1994 08:12:31 GMT")
⇒ #<date ...>
HTTP Header: UInt max-forwards

The maximum number of proxy or gateway hops that a request should be subject to.

(parse-header 'max-forwards "10")
⇒ 10
HTTP Header: Pair proxy-authorization

Authorization credentials for a proxy connection. See the documentation for authorization above for more information on the format.

(parse-header 'proxy-authorization "Digest foo=bar,baz=qux"
⇒ (digest (foo . "bar") (baz . "qux"))
HTTP Header: Pair range

A range request, indicating that the client wants only part of a resource. The car of the pair is the symbol bytes, and the cdr is a list of pairs. Each element of the cdr indicates a range; the car is the first byte position and the cdr is the last byte position, as integers, or #f if not given.

(parse-header 'range "bytes=10-30,50-")
⇒ (bytes (10 . 30) (50 . #f))
HTTP Header: URI referer

The URI of the resource that referred the user to this resource. The name of the header is a misspelling, but we are stuck with it.

(parse-header 'referer "http://www.gnu.org/")
⇒ #<uri ...>
HTTP Header: List te

A list of transfer codings, expressed as key-value lists. A common transfer coding is trailers.

(parse-header 'te "trailers")
⇒ ((trailers))
HTTP Header: String user-agent

A string indicating the user agent making the request. The specification defines a structured format for this header, but it is widely disregarded, so Guile does not attempt to parse strictly.

(parse-header 'user-agent "Mozilla/5.0")
⇒ "Mozilla/5.0"

7.3.4.5 Response Headers

HTTP Header: List accept-ranges

A list of range units that the server supports, as symbols.

(parse-header 'accept-ranges "bytes")
⇒ (bytes)
HTTP Header: UInt age

The age of a cached response, in seconds.

(parse-header 'age "3600")
⇒ 3600
HTTP Header: ETag etag

The entity-tag of the resource.

(parse-header 'etag "\"foo\"")
⇒ ("foo" . #t)
HTTP Header: URI-reference location

A URI reference on which a request may be completed. Used in combination with a redirecting status code to perform client-side redirection.

(parse-header 'location "http://example.com/other")
⇒ #<uri ...>
HTTP Header: List proxy-authenticate

A list of challenges to a proxy, indicating the need for authentication.

(parse-header 'proxy-authenticate "Basic realm=\"foo\"")
⇒ ((basic (realm . "foo")))
HTTP Header: UInt|Date retry-after

Used in combination with a server-busy status code, like 503, to indicate that a client should retry later. Either a number of seconds, or a date.

(parse-header 'retry-after "60")
⇒ 60
HTTP Header: String server

A string identifying the server.

(parse-header 'server "My first web server")
⇒ "My first web server"
HTTP Header: *|List vary

A set of request headers that were used in computing this response. Used to indicate that server-side content negotiation was performed, for example in response to the accept-language header. Can also be the symbol *, indicating that all headers were considered.

(parse-header 'vary "Accept-Language, Accept")
⇒ (accept-language accept)
HTTP Header: List www-authenticate

A list of challenges to a user, indicating the need for authentication.

(parse-header 'www-authenticate "Basic realm=\"foo\"")
⇒ ((basic (realm . "foo")))