On this page:
2.1 Supplements to net/  head
extract-http-ver
extract-http-code
extract-http-text
extract-field/  number
maybe-insert-field
coalesce-fields
validate-tx-or-rx-header
2.2 Heads as a dict
heads-string->dict
heads-dict->string
maybe-dict-set
maybe-dict-set*

2 Head

 (require (planet gh/http:1:=3/head))

2.1 Supplements to net/head

These stick with net/head’s respresentation of headers as a string?, and add a few functions that are "missing" or would be convenient.

procedure

(extract-http-ver h)  string?

  h : string?

procedure

(extract-http-code h)  exact-positive-integer?

  h : string?

procedure

(extract-http-text h)  string?

  h : string?
From an HTTP response header, get the HTTP version (such as 1.0 or 1.1), status code number (such as 200), and the status text description (such as OK).

procedure

(extract-field/number field h [radix])  (or/c #f number?)

  field : string?
  h : string?
  radix : exact-positive-integer? = 10
Convenience wrapper for net/head’s extract-field for fields whose values are supposed to be a number, such as Content-Length. From the header h extract the value of field as a number using radix. If the field does not exist or its value cannot be converted to a number, return #f.

procedure

(maybe-insert-field field value h)  string?

  field : (or/c symbol? string?)
  value : any/c
  h : string?
Like insert-field, but inserts only if field does not already exist in h. Otherwise the field and its value already present in h remain unchanged.

Use case: You want to ensure the header is present, but not disrupt any existing value—for example, Date or Content-Length.

procedure

(coalesce-fields h)  string?

  h : string?
Combine header fields with the same name into one, with the values as a comma separated list (with no space between values), as prescribed by RFC 2616, section 4.2. For example, the two headers x-foo: fred and x-foo: barney would be combined into the single header x-foo: fred,barney.

Some web services (hello Amazon) require this as part of "signing" a request for authentication, which means it has to be done exactly right.

procedure

(validate-tx-or-rx-header h)  string?

  h : string?
Similar to net/head’s validate-header, but permits response headers (with their initial status line, such as HTTP/1.1 200 OK) as well as request headers. Also, if the header is valid and no exception is thrown, returns h (making it more convenient to use this in an expression that both validates and returns a header).

2.2 Heads as a dict

procedure

(heads-string->dict s [dupe-sep])  dict?

  s : string?
  dupe-sep : string? = "\n"
Convert headers represented as a string of the form specified in net/head, to a dict? where the keys are symbol? and the values are any/c.

Specifically, handle the case of duplicate headers. A real-world example of such duplicate headers is Set-Cookie. Other than association lists, most types of dicts don’t permit duplicate keys, so we can’t store duplicate headers using those. Instead, duplicate headers are stored in the dict under the same key, with the various values separated by dupe-sep.

Examples:
> (heads-string->dict "Host: Foo\r\nKey: Value\r\n\r\n")
'#hash((Host . "Foo") (Key . "Value"))
> (heads-string->dict "Key: Value 1\r\nKey: Value 2\r\n\r\n")
'#hash((Key . "Value 1\nValue 2"))

procedure

(heads-dict->string d)  string?

  d : dict?
Convert headers represented as a dict? into a string? of the form specified in net/head, including the terminating \r\n to end all the headers. This is the reverse of heads-string->dict including its handling of duplicate headers.

Examples:
> (heads-dict->string '#hash((Host . "Foo") (Key . "Value")))
"Host: Foo\r\nKey: Value\r\n\r\n"
> (heads-dict->string '((Host . "Foo") (Key . "Value")))
"Host: Foo\r\nKey: Value\r\n\r\n"

procedure

(maybe-dict-set d k v)  (and/c dict? dict-can-functional-set?)

  d : (and/c dict? dict-can-functional-set?)
  k : symbol?
  v : any/c
Like dict-set, but will set the new value v for the key k only if the key does not already exist in the dict.

Examples:
> (maybe-dict-set '() 'a "New")
'((a . "New"))
> (maybe-dict-set '([a . "Old"]) 'a "New")
'((a . "Old"))

procedure

(maybe-dict-set* d kvs)  (and/c dict? dict-can-functional-set?)

  d : (and/c dict? dict-can-functional-set?)
  kvs : list?
Like dict-set*, but will set the new value for a key only if the key does not already exist in the dict.