(rfc http) - HTTP client

Library (rfc http)

This library provides simple HTTP client defined in RFC 2616.

The library only talks to HTTP 1.1 and provides part of the specified features. We may implement complete specification in future.

Following is the simple example to send GET method to a HTTP server.

(import (rfc http))

(define url "http://example.com/path")

(let-values (((server path) (url-server&path url)))
  (http-get server path))
;; -> return 3 values
;; status
;; header
;; body
Condition &http-error

HTTP error condition.

Function http-error? obj

Return #t if given obj is HTTP condition, otherwise #f.

Request APIs

Sends HTTP request to given path on server. The using methods are GET, HEAD, POST, PUT, and DELETE, respectively.

The body argument of http-post and http-put can be UTF-8 string, bytevector or list of body parameters. The parameters are used for sending multipart form data. The detail parameter form is described in the http-compose-form-data.

The keyword :value and file should not be represented simultaneously, if both keywords are found then :file is used.

Optional arguments options are passed to underling procedure http-request.

_ :key (no-redirect #f) _ _ (auth-handler #f) _ _ (auth-user #f) _ _ _ _ (auth-password #f) _ _ _ _ (user-agent (http-user-agent)) _ _ _ _ (secure #f) _ _ _ _ (receiver (http-string-receiver)) _ _ _ _ (sender #f) _ _ :allow-other-keys opts

Sends HTTP request to request-uri on server with method.

The keyword argument receiver is used to receive the response data. The value must be a procedure which takes four arguments, status code, headers, size of content, and thunk to retrieve remote binary port and its size.

The keyword argument sender is used for POST and PUTHTTP method to send data. If it's specified then it must be a procedure which takes three arguments, headers, encoding and header-sink.

NOTE: Users can define own receiver and sender however the API may change in the future. So if the predefined ones are sufficient, it is safe to use them.

The keyword arguments start with auth- handle authentication. If the server respond status code 401 then those values are used. auth-handler must be a procedure and takes five arguments alist of connection-info, auth-user, auth-password, response headers and response body. If the handler returns list of "authorization" value then http-request sends it as the authentication data. For example, if the server requires BASIC authentication then the procedure should return something like following value;

(("authorization" "Basic dXNlcjpwYXNz"))

Following is the complete example of auth-handler;

(define (basic-auth-handler info user pass headers body)
  (let ((m (format "~a:~a" user pass)))
    `(("authorization" ,(format "Basic ~a" (base64-encode-string m))))))

http-request supports BASIC authentication and Digest authentication by default. If you know that the server requires one of each then specifying auth-user and auth-password is sufficient.

If keyword argument secure is true value then TLS socket is used for physical connection.

The rest arguments opts is converted to request header.

This parameter value is used for user-agent header.

Senders and receivers

Creates a sender which sends nothing.

Creates a sender which content is str.

The string will be converted to bytevector according to the encoding argument when the sender is called.

blob must be a string or bytevector.

Creates a sender which content is blob. If the blob is string, it will be converted to bytevector with string->utf8.

Creates a sender which send multipart/form-data with content of param.

The content will be created by http-compose-form-data procedure passing param.

Creates a receiver which returning content is string, bytevecotor and unspecified value, respectively.

(http-get "google.com" "/" :receiver (http-string-receiver))
status headers and string representation of received content

(http-get "google.com" "/" :receiver (http-binary-receiver))
status headers and bytevector representation of received content

(http-get "google.com" "/" :receiver (http-null-receiver))
status headers and unspecified value

The sink must be a binary output port, flusher must be a procedure takes two arguments, sink and headers.

Creates a receiver which stores the content of response to sink and returns the result of flusher.

(http-get "google.com" "/"
          :receiver (let-values (((port extract) 
                                  (open-bytevector-output-port)))
                      (http-oport-receiver port 
                                           (lambda (port size) (extract)))))
status headers and bytevector representation of received content

filename must be a string.

Creates a receiver which stores the content to a file. The receiver returns the file name.

If keyword arguments temporary? specified with true value, then the returning file name is temporary file.

If there is no response or content-length header contains non number value, then the file will be cleaned.

(http-get "google.com" "/" :receiver (http-file-receiver "google.html"))
status headers and "google.html"

receiver must be an HTTP receiver.

Creates a receiver which handles gzip encoded response. If HTTP response contains Content-Encoding header with value gzip, then the receiver decodes the response and propagates to given receiver. Otherwise, it simply forwards the response to receiver.

The following describes how to use it:

(http-get "google.com" "/"
          :accept-encoding "gzip"
          :receiver (http-gzip-receiver (http-string-receiver)))

Utilities

Composes query string.

If given path is #f then only composed query string is returned, otherwise this returns _path_?_composed query_ form.

params must be a list of name & value list or null list.

Composes multipart form data.

If port is #f then it returns composed string. if it's a port then the result is stored in the given port.

The params must be following form;

 <params> : (<params> ...)
 <param>  : (<name> <value>)
          | (<name> <key> <value> <key2> <value2> ...)
 <key>    : :value | :file | :content-type | :content-transfer-encoding
          | other keyword (used as a header name)

<value> is the content of <name> parameter. It can be any of Scheme object however it is converted to string representation except bytevector.

If :file keyword is used then it read the content of <value>.

Decompose the given url and returns auth part of URL and path + query + fragment.