On this page:
http-client
http-client<%>
fork
handle
adjust-request
handle-response
handle-response-content
handle-redirection
sync-request
async-request
current-response
response-handler/  c
content-handler/  c
8.12

2 Client API🔗ℹ

An HTTP client offers methods to perform requests and handle responses.

procedure

(http-client [#:ssl ssl 
  #:add-header header-fields 
  #:add-response-handlers response-handlers 
  #:add-content-handlers content-handlers 
  #:add-request-adjuster request-adjuster 
  #:add-response-listener response-listener 
  #:add-cookie-jar cookie-jar]) 
  (is-a?/c http-client<%>)
  ssl : (or/c 'secure 'auto ssl-client-context?) = 'secure
  header-fields : (listof header-field/c) = null
  response-handlers : 
(listof
 (list/c (or/c (integer-in 100-599) status-class/c)
         response-handler/c))
   = null
  content-handlers : (listof (list/c symbol? content-handler/c))
   = null
  request-adjuster : (or/c #f (-> request? request?)) = #f
  response-listener : (or/c #f (-> (is-a?/c response<%>) void?))
   = #f
  cookie-jar : (or/c #f (is-a?/c cookie-jar<%>)) = #f
Creates a new HTTP client that does not share connections with any existing clients.

The client automatically creates connections as necessary based on request URLs. For https requests, the client attempts to negotiate an HTTP/2 connection using ALPN; if the server does not agree to HTTP/2, the client falls back to HTTP/1.1. For http requests, only HTTP/1.1 is supported. The client remembers the value of (current-custodian) and uses that custodian when creating connections. Connections are automatically closed after a few seconds of inactivity.

The ssl argument determines the client context used by ssl-connect when making https connections. See fork for an explanation of the other arguments.

A client contains the following:
  • a connection manager that manages existing connections and creates new ones on demand

  • instructions for adjusting requests before they are executed (see adjust-request)—specifically, a base header and a list of adjuster functions

  • instructions for handling responses once they are received (see handle-response)—specifically, a list of listeners, a list of response handlers, and a list of content handlers (see handle-response-content)

method

(send a-http-client fork 
  [#:add-header header-fields 
  #:add-response-handlers response-handlers 
  #:add-content-handlers content-handlers 
  #:add-request-adjuster request-adjuster 
  #:add-response-listener response-listener 
  #:add-cookie-jar cookie-jar]) 
  (is-a?/c http-client<%>)
  header-fields : (listof header-field/c) = null
  response-handlers : 
(listof
 (list/c (or/c (integer-in 100-599) status-class/c)
         response-handler/c))
   = null
  content-handlers : (listof (list/c symbol? content-handler/c))
   = null
  request-adjuster : (or/c #f (-> request? request?)) = #f
  response-listener : (or/c #f (-> (is-a?/c response<%>) void?))
   = #f
  cookie-jar : (or/c #f (is-a?/c cookie-jar<%>)) = #f
Creates a new client object that shares the same connection manager and custodian as a-http-client, but adds the given header fields and handlers. The new header fields and handlers take precedence over the existing header fields and handlers. More precisely:
  • The header of the new client object consists of header-fields, plus the header fields of a-http-client except for any fields whose keys also occur in header-fields.

  • The response and content handlers of the new client consist of the response-handlers and content-handlers prepended to the existing response and content handlers, respectively.

  • The request adjusters of the new client consist of the new request-adjuster added to the existing request adjusters. That is, the new adjuster is run before the existing adjusters.

  • The response listeners of the new client consist of the old listeners with response-listener, if present, added to the end. That is, the new response listener is run after the existing listeners.

A cookie-jar argument is converted to a request adjuster and a response handler. The request adjuster adds Cookie fields to the request header; the response listener scans the response for Set-Cookie fields and adds them to cookie-jar. (Beware, the default list-cookie-jar% implementation is not thread-safe. Access to cookie-jar is synchronized for a-http-client and derived clients, but not for other clients that access cookie-jar.)

method

(send a-http-client handle req    
  [#:user-info user-info])  any
  req : request?
  user-info : (and/c hash? hash-eq? immutable?) = '#hasheq()
Adjusts req using the client’s default header fields and adjusters (see adjust-request), executes the request, notifies the response listeners, and handles the response according to the client’s response and content handlers (see handle-response and handle-response-content).

The user-info hash is included in the response. Symbols starting with an underscore (_) are reserved for use as keys by this library—for example, handle-redirection uses the '_redirected-from key.

The result is the result of the selected response handler.

Equivalent to
(let ([resp (send a-http-client sync-request req)])
  (send resp user-info user-info)
  (send a-http-client handle-response))

method

(send a-http-client adjust-request req)  request?

  req : request?
Returns a request like req except enriched with the client’s header fields and transformed by the client’s request adjusters.

A header field from the client is only included if req does not already have a header field of the same name. That is, req’s header fields take precedence over the client’s header fields.

method

(send a-http-client handle-response resp)  any

  resp : (is-a?/c response<%>)
Notifies the client’s response listeners (oldest first) and then handles the response by calling the first matching response handler, or if none match, by calling the default handler.

A handler entry matches resp according to the following rules:
  • An entry of the form (list status-code-integer handler) matches if status-code-integer is equal to (send resp get-status-code). Examples of status-code-integer include 200 and 404.

  • An entry of the form (list status-class-symbol handler) matches if status-class-symbol is equal to (send resp get-status-class). Examples of status-class-symbol include 'successful (2xx) and 'client-error (4xx).

  • An entry of the form (list 'else handler) always matches.

If a handler is selected, it is called with a-http-client and resp.

The default handler calls handle-response-content if resp has the status code 200 (Found); otherwise, it closes resp’s content input port and raises an exception. (Closing the content input port may cause an HTTP/2 connection to cancel the corresponding stream.)

method

(send a-http-client handle-response-content resp)  any

  resp : (is-a?/c response<%>)
Handles the response by calling the first matching content handler on resp’s content input port, or if none match, by calling the default content handler.

A content handler entry matches resp according to the following rules:
  • An entry of the form (list mime-type-symbol handler) matches if mime-type-symbol is equal to (send resp get-content-type). Examples of mime-type-symbol include 'text/html and 'application/json.

  • An entry of the form (list 'mime-type/* handler) matches if the main type of (send resp get-content-type) is mime-type. For example, 'image/* matches 'image/png.

  • An entry of the form (list '*/* handler) always matches.

If a handler is selected, it is called with (send resp get-content-in #t) in a context where current-response is set to resp.

The default content handler closes resp’s content input port and raises an exception.

method

(send a-http-client handle-redirection resp    
  [#:limit limit    
  #:fail fail])  any
  resp : (is-a?/c response<%>)
  limit : exact-nonnegative-integer? = 5
  fail : (-> any) = (lambda () (error ....))

The handle and handle-response methods do not automatically handle redirection responses; handle-redirection must be explicitly called by a response handler.

Handles a Redirection (3xx) response according to the following rules:
  • If resp does not have a Location header field, or if the location is not a valid URL, then the handler fails.

  • If there have already been limit or more redirections from the original request (as determined by the '_redirected-from key of (send resp user-info)), then the handler fails.

  • If resp’s status code is 301 or 302, then a new request is made for the redirection location. If the previous method was 'POST, then the new method is 'GET; otherwise, the new method is the same as the previous method.

  • If resp’s status code is 303, then a new request is made for the redirection location. If the previous method was 'HEAD, then the new method is 'HEAD; otherwise, the new method is 'GET.

  • If resp’s status code is 307 or 308, then a new request is made for the redirection location. The new method is the same as the previous method.

  • Otherwise, the handler fails.

On success, this method calls handle with the new request and the auxiliary info of resp adjusted by adding resp to the '_redirected-from list. The header of the new request is initially empty (that is, the previous request header is not carried over), but the new request is adjusted as usual by adjust-request. The data of the new request is the same as the data of the previous request is the method is the same; if the method is changed (for example, 'POST to 'GET), then the new request data is #f.

On failure, this method calls fail. The default fail value raises an exception.

method

(send a-http-client sync-request req)  (is-a?/c response<%>)

  req : request?
Sends a request and returns the response.

Equivalent to ((sync (send a-http-client async-request req))).

This method does not use the client’s response and content handlers.

method

(send a-http-client async-request req)

  (evt/c (-> (is-a?/c response<%>)))
  req : request?
Adjusts req according to adjust-request, executes the request, and returns a synchronizable event that is ready once one of the following occurs:
  • The beginning of a response has been received, including the status and header. The synchronization result is a constant function that returns an instance of response<%>; see get-content-in for notes on concurrent processing of the response message body.

  • The server closed the connection or sent an invalid response beginning. The synchronization result is a function that raises an exception with information about the failure.

See Synchronizable Event Results for the rationale of the procedure wrapper.

An exception may be raised immediately if a failure occurs while sending the request (for example, no connection could be made to the host).

This method does not use the client’s response and content handlers.

parameter

(current-response)  (or/c #f (is-a?/c response<%>))

(current-response resp)  void?
  resp : (or/c #f (is-a?/c response<%>))
The handle-response-content method sets this parameter to the response being handled for the duration of a call to a content handler.

Contract for response handlers. See handle-response.

Contract for content handlers. See handle-response-content.