- Scheme 77.2%
- C 21.9%
- Shell 0.9%
| docs | ||
| tests | ||
| .gitignore | ||
| build-http-curl | ||
| curl_helpers.c | ||
| http-curl.egg | ||
| http-curl.release-info | ||
| http-curl.scm | ||
| LICENSE | ||
| README.md | ||
http-curl
HTTP client egg for CHICKEN Scheme based on libcurl. Provides robust HTTPS/TLS support out of the box with an API compatible with http-client.
Requirements
- CHICKEN 5 or 6
- libcurl (with development headers)
On macOS: brew install curl
On Debian/Ubuntu: apt install libcurl4-openssl-dev
Installation
From the egg directory:
chicken-install
Testing
The default test suite runs offline:
csi -s tests/run.scm
Network-backed tests are opt-in:
TEST_NETWORK=1 csi -s tests/run.scm
A separate stress/leak check is available for manual runs:
TEST_NETWORK=1 LEAK_ITERATIONS=25 leaks --atExit -- csi -s tests/leak-check.scm
Usage
(import http-curl (chicken io))
;; Simple GET
(with-input-from-request "https://example.com" #f read-string)
;; POST with JSON body
(import intarweb uri-common)
(let* ((uri (uri-reference "https://httpbin.org/post"))
(h (headers '((content-type #(application/json ())))))
(req (make-request uri: uri method: 'POST headers: h)))
(with-input-from-request req "{\"key\":\"value\"}" read-string))
;; Form-encoded POST
(with-input-from-request "https://httpbin.org/post"
'((foo . "bar") (baz . "quux"))
read-string)
;; Access response object
(call-with-input-request*
"https://httpbin.org/get" #f
(lambda (port response)
(printf "Status: ~A~%" (response-code response))
(read-string #f port)))
;; Error handling
(import (chicken condition))
(condition-case
(with-input-from-request "https://httpbin.org/status/404" #f read-string)
((http client-error) (print "got a 4xx error"))
((http server-error) (print "got a 5xx error")))
Binary response bodies on CHICKEN 6
On CHICKEN 6, strings are UTF-8 and response body ports are textual, so reading a binary body with read-string is lossy: byte sequences that are not valid UTF-8 get replaced during decoding. Read binary payloads with read-bytevector from (scheme base) instead:
(import (scheme base))
(call-with-input-request
"https://httpbin.org/image/png" #f
(lambda (port) (read-bytevector 1000000 port)))
On CHICKEN 5, strings are raw bytes, so read-string also works for binary data there. Text bodies (including non-ASCII UTF-8) work with read-string on both versions.
API
Procedures
(with-input-from-request uri-or-request writer reader)
The most convenient form. reader is a thunk that reads from current-input-port. writer can be #f (GET), a string (direct body), an alist (form-encoded POST), or a thunk that writes to current-output-port.
Returns three values: reader-result, uri, response.
(call-with-input-request uri-or-request writer reader)
Like with-input-from-request, but reader receives the port as its argument: (lambda (port) ...).
(call-with-input-request* uri-or-request writer reader)
Like call-with-input-request, but reader receives both port and response: (lambda (port response) ...).
(call-with-response request writer reader)
Low-level interface. request is an intarweb request object. writer is (lambda (output-port) ...). reader is (lambda (response) ...).
Parameters
| Parameter | Default | Description |
|---|---|---|
max-redirect-depth |
5 | Maximum number of redirects to follow |
max-retry-attempts |
1 | Maximum retry attempts on failure |
client-software |
"http-curl/0.1" |
User-Agent string |
prepare-request |
identity | Request transform hook |
determine-proxy |
env-based | Proxy resolution (http_proxy/https_proxy) |
Error conditions
HTTP errors are raised as composite conditions matching http-client's format:
(http client-error)— 4xx responses(http server-error)— 5xx responses(http unexpected-server-response)— other non-2xx responses
Each condition has response and body properties accessible via condition-property-accessor.
Architecture
Response bodies stream through an OS pipe. libcurl runs in a pthread; the Scheme reader reads from the pipe fd in real-time. The body is never fully buffered in memory.
History
v0.1.3
- Add CHICKEN 6 support: the egg now builds and runs on both CHICKEN 5 and CHICKEN 6 from the same source
- Fix request body length for non-ASCII bodies on CHICKEN 6 (Content-Length is now byte-accurate)
- Document reading binary response bodies on CHICKEN 6 (use
read-bytevectorinstead ofread-string) - Add offline and network tests covering non-ASCII request bodies
License
BSD-3-Clause. See LICENSE.