1 Introduction to http123
This library’s http-client<%> objects support two styles of usage: a high-level handler-based interface and a low-level response-based interface.
1.1 Using the Handler API
This section introduces the high-level, handlers-based client API.
> (define client (http-client #:add-header `([x-racket-version ,(version)]) #:add-content-handlers `([application/json ,read-json])))
> (send client handle time-req)
'#hasheq((date . "07-21-2021")
(milliseconds_since_epoch . 1626909431013)
(time . "11:17:11 PM"))
> (send client handle (request 'GET "https://tools.ietf.org/rfc/rfc7540.txt")) handle: no content handler matched
code: 'unhandled-content
response: 200 response with text/plain body
received: 'yes
> (define client2 (send client fork #:add-content-handlers `([text/plain ,(lambda (in) (read-string 40 in))] [*/* ,(lambda (in) (format "something called ~s, I guess" (send (current-response) get-content-type)))]))) > (send client2 handle (request 'GET "https://tools.ietf.org/rfc/rfc7540.txt")) "\n\n\n\n\n\nInternet Engineering Task Force (I"
> (send client2 handle (request 'GET "https://www.google.com/")) "something called text/html, I guess"
> (send client2 handle (request 'GET "https://mirror.racket-lang.org/no-such-file.html")) handle: no response handler matched
code: 'unhandled-response
response: 404 response with text/html body
received: 'yes
> (define client3 (send client2 fork #:add-response-handlers `([404 ,(lambda (client resp) 'not-found)] [client-error ,(lambda (client resp) 'failed)]))) > (send client3 handle (request 'GET "https://racket-lang.org/secret-plans.scrbl")) 'failed
> (send client3 handle (request 'GET "https://mirror.racket-lang.org/no-such-file.html")) 'not-found
> (define client4 (send client3 fork #:add-response-handlers `([404 ,(lambda (client resp) (list 'not-found (send client handle-response-content resp)))]))) > (send client4 handle (request 'GET "https://mirror.racket-lang.org/no-such-file.html")) '(not-found "something called text/html, I guess")
1.2 Using the Response API
This section introduces a lower-level client API that users can use to simply retrieve response objects.
> (define client (http-client))
> (define header '("Accept-Encoding: gzip, deflate" (accept-language #"en") (#"User-Agent" #"racket-http123/0.1"))) > (define req (request 'GET "https://www.google.com/" header #f))
> (define resp (send client sync-request req)) > ; ... prune away some header fields ... > resp
(new http2-response%
(status-code 200)
(request
(request
'GET
(url "https" #f "www.google.com" #f #t (list (path/param "" '())) '() #f)
'((#"accept-encoding" #"gzip, deflate")
(#"accept-language" #"en")
(#"user-agent" #"racket-http123/0.1"))
#f))
(header-fields
'((#"date" #"Wed, 21 Jul 2021 23:17:18 GMT")
(#"expires" #"-1")
(#"cache-control" #"private, max-age=0")
(#"content-type" #"text/html; charset=ISO-8859-1")
(#"p3p"
#"CP=\"This is not a P3P policy! See g.co/p3phelp for more info.\"")
(#"content-encoding" #"gzip")
(#"server" #"gws")
(#"content-length" #"6151")
(#"x-xss-protection" #"0")
(#"x-frame-options" #"SAMEORIGIN")))
...)
> (send resp get-status-code) 200
> (read-string 15 (send resp get-content-in)) "<!doctype html>"
> (read-string 5 (send resp get-content-in)) "<html"
Using async-request it is possible to submit send requests and receive responses as they arrive. In particular, with an HTTP/2 connection, responses may arrive in an order different from the order the requests were sent. Of course, responses using different connections are always unordered.
> (define ietf-evt (send client async-request (request 'GET "https://tools.ietf.org/rfc/rfc7540.txt")))
> (define google-evt (send client async-request (request 'GET "https://www.google.com/"))) > ((sync ietf-evt google-evt))
(new http2-response%
(status-code 200)
(request
(request
'GET
(url "https" #f "www.google.com" #f #t (list (path/param "" '())) '() #f)
'((#"accept-encoding" #"gzip, deflate")
(#"user-agent" #"racket-http123/0.1"))
#f))
(header-fields
'((#"date" #"Wed, 21 Jul 2021 23:17:19 GMT")
(#"expires" #"-1")
(#"cache-control" #"private, max-age=0")
(#"content-type" #"text/html; charset=ISO-8859-1")
(#"p3p"
#"CP=\"This is not a P3P policy! See g.co/p3phelp for more info.\"")
(#"content-encoding" #"gzip")
(#"server" #"gws")
(#"content-length" #"5903")
(#"x-xss-protection" #"0")
(#"x-frame-options" #"SAMEORIGIN")))
...)