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

1 (www http)

The (www http) module includes module-configuration fluids, procedures for high-level HTTP operation, low-level HTTP message object access, and common messages.

1.1 Dynamic Configuration

Fluid: protocol-version

A pair of integers representing the major and minor portions of the protocol version this module should support. The default value is (1 . 0). Users:

http:post-form   ; via http:request

1.2 High-Level HTTP Operation

Procedure: http:connect proto addrfam address [address-rest…]

Return a TCP stream socket connected to the location specified by protocol proto, addrfam and address. proto is PF_INET or PF_UNIX, and the other args take corresponding forms:


(AF_INET ipaddr portno), where ipaddr is an integer. Use (car (hostent:addr-list (gethost host))) to compute the ipaddr of host (a string).


(AF_UNIX filename), made, for example, by
(list AF_UNIX "/tmp/foo-control").

Note that PF_foo and AF_foo are names of variables that have constant values, not symbols.

Procedure: http:open host [port]

Return an HTTP connection (a socket) to host (a string) on TCP port port (default 80 if unspecified).

Procedure: send-request sock method url [keyword value…]
Keywords: headers, body, flags, protocol-version 

Submit to socket sock an HTTP request using method (a symbol) and url, an object returned by url:parse, forming the message with additional headers, a list of strings, each of which should have one of the forms:


and body, which may be #f (which means no body), a string or list of them, a u8 vector or list of them, or a procedure m which manages the transmission of the body data by supporting the body transmission protocol. This means m takes one arg, command (symbol):


This is called if the transfer is not “chunked” (see below). m returns the total length (in bytes) of the data.


Return two values: the length (in bytes) of the next chunk of data to send, and either a string, or a procedure w that does the actual writing to its port arg (which will be sock). If there is no more data, both values should be #f, i.e., m should return (values #f #f).

If flags contains the symbol chunked, send the body with “chunked” Transfer-Encoding. Otherwise, compute and add to the headers its total Content-Length.

If flags contains the symbol close, add Connection: close to the headers.

The protocol-version is a pair specifying the major and minor version numbers of HTTP to send as. It defaults to (1 . 1). For HTTP 1.x (x >= 1), automatically add chunked to flags as well as the headers:

TE: trailers
Connection: TE

Return an unspecified object pending that can be passed to receive-response.

Procedure: receive-response pending [keyword value…]
Keywords: s2s, intervene, flags 

Receive the pending (from send-request) response. Return an HTTP message object. The header names are symbols made by (string->symbol (s2s orig)), where s2s defaults to string-titlecase. The status code is a 3-digit integer. The body of the message may be #f if there is no body possible (per HTTP). Otherwise, its value depends on intervene and flags.

Here is an example that uses receive-response argument intervene to arrange for the message body to be a u8 vector if the Content-Type is not “text/*”.

 (srfi srfi-13)   ; string-prefix?
 (www url))       ; url:parse

(define (text? type)
  (string-prefix? "text/" type))

(define (u8-maybe hget flags)
  (cond ((hget 'Content-Type)
         => (lambda (type)
              (values #f (and (not (text? type))
                              (cons 'u8 flags)))))
         (values #f #f))))

(define SOCK (http:open …))

(define (gimme string)
  (send-request SOCK 'GET (url:parse string)))

(define (ok pending)
  (receive-response pending #:intervene u8-maybe))

(define ICO (ok (gimme "http://localhost/favicon.ico")))
(define IDX (ok (gimme "http://localhost/index.html")))

(http:message-body ICO)
⇒ #u8(0 0 1 0 1 0 46 …)

(http:message-body IDX)
⇒ "<?xml version=\"1.0\" …"

Note that to find the content type in u8-maybe, we rely on the default header-name normalization of string-titlecase, since we know ok does not specify #:s2s s2s in its call to receive-response. To enable u8-maybe to work with any pending response, you can instead use (hget "Content-Type") (i.e., a string name).

Procedure: http:request method url [headers [body]]

Submit an HTTP request using method and url, wait for a response, and return the response as an HTTP message object. The field types and values of this message object are as described in receive-response, with two exceptions (for backward compatability): the status code is a string; the header names are symbols, all lower-case.

method is the symbolic name of some HTTP method, e.g., GET or POST. It may also be a string. url is a url object returned by url:parse. Optional args headers and body are lists of strings that comprise the lines of an HTTP message. The header strings should not end with ‘CR’ or ‘LF’ or ‘CRLF’; http:request handles that. Also, the Content-Length header and Host header are calculated automatically and should not be supplied. Here are two examples:

(http:request 'GET parsed-url
  (list "User-Agent: Anonymous/0.1"
        "Content-Type: text/plain"))

(http:request 'POST parsed-url
  (list "User-Agent: Fred/0.1"
        "Content-Type: application/x-www-form-urlencoded")
  (list "search=Gosper"

In the second example, the Content-Length header is computed to have value 33 (the sum of 13, 8 and 12).

1.3 Low-Level HTTP Message Object Access

Procedure: http:message-version msg

Return the HTTP version in use in HTTP message msg.

Procedure: http:message-status-code msg

Return the status code returned in HTTP message msg.

Procedure: http:message-status-text msg

Return the text of the status line from HTTP message msg.

Procedure: http:message-status-ok? msg

Return #t iff status code of msg indicates a successful request.

Procedure: http:status-ok? status

Return #t iff status (string or integer) is 2xx.

Procedure: http:message-body msg

Return the body of the HTTP message msg.

An HTTP message header is represented by a pair. The CAR is a symbol representing the header name, and the CDR is a string containing the header text. E.g.:

'((date . "Thu, 29 May 1997 23:48:27 GMT")
  (server . "NCSA/1.5.1")
  (last-modified . "Tue, 06 May 1997 18:32:03 GMT")
  (content-type . "text/html")
  (content-length . "8097"))

Note: these symbols are all lowercase, although the original headers may be mixed-case. Clients using this library should keep this in mind, since Guile symbols are case-sensitive.

Procedure: http:message-headers msg

Return a list of the headers from HTTP message msg.

Procedure: http:message-header header msg

Return the header field named header from HTTP message msg, or #f if no such header is present in the message.

1.4 Common Messages

Procedure: http:post-form url extra-headers fields

Submit an http request using the POST method on the url. extra-headers is a list of extra headers, each a string of form "name: value …".

The "Content-Type" and "Host" headers are sent automatically and do not need to be specified. fields is a list of elements of the form (fkey . fvalue), where fkey is a symbol and fvalue is normally a string.

fvalue can also be a list of file-upload specifications, each of which has the form (source name mime-type transfer-encoding). source can be a string or a thunk that returns a string.

The rest of the elements are strings or symbols: name is the filename (only the non-directory part is used); mime-type is a type/subtype pair such as "image/jpeg", or #f to mean "text/plain". transfer-encoding is one of the tokens specified by RFC 1521, or #f to mean "binary". File-upload spec elements with invalid types result in a "bad upload spec" error prior to the http request.

Note that source is used directly without further processing; it is the caller’s responsibility to ensure that the MIME type and transfer encoding specified describe source accurately.

If there are no file-upload specifications in fields, the Content-Type is application/x-www-form-urlencoded, and furthermore all the fkey and fvalue are transformed by url-coding:encode (see url-coding) with the additional reserved characters #\& (ampersand) and #\= (equal sign).

Otherwise, the Content-Type is multipart/form-data, with each field in fields formatted as a MIME sub-part.

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