An asynchronous port of the Drakma HTTP client.
This library is now API-compatible with drakma 1.3.4.
drakma-async:http-request takes the same arguments as drakma:http-request,
and does its absolute best to have the exact same behavior, except instead of
returning the values of the HTTP request made, it returns a cl-async future
that is finished with the values of the HTTP request.
Here's a simple usage example (using the blackbird promise implementation):
(defun my-http-request () (catcher (multiple-promise-bind (body status headers) (das:http-request "https://www.google.com/") (format t "Status: ~a~%" status) (format t "Headers: ~s~%" headers) (format t "Body: ~a~%" (if (stringp body) body (babel:octets-to-string body)))) (das:http-eof () (format t "Server hung up unexpectedly =[~%")) (error (e) (format t "Error: ~a~%" e)))) (as:start-event-loop #'my-http-request)
drakma-async comes with a test suite:
(ql:quickload :drakma-async-test) (drakma-async-test:run-tests)
drakma-async works well, but for an HTTP client that supports streaming (both upload and download) more natively, check out carrier. Carrier is built specifically to be used in an asynchronous setting, and may eventually deprecate drakma-async.
This library makes use of the
cl-async-ssl package, which is an add-on package
cl-async to provide SSL functionality.
drakma-async will use SSL by
:drakma-no-ssl is present in
*features* during load/compile
Same goes for the test suite: if
:drakma-no-ssl is present in
when the tests are loaded, no SSL tests are performed.
drakma-async provides a function in the
drakma package called
drakma:http-request, except for that the final value returned is
a closure instead of the finished request values. This closure is to be called
when all content in the response has been returned. This is handled by the
which is able to tell when a response has been completely downloaded. Once the
closure is called, it reads all the data from the http-stream the request was
sent on, and parses it via drakma's normal capabilities.
Obviously the downside to this is that the entire response has to be held in memory. For this reason, this library would be best used for smaller requests and sending large amounts of data as opposed to downloading large amounts of data. Note that there is an issue outlining this problem and a potential fix, but it hasn't been worked on YET.
drakma:http-request-async is now completely
automated through the use of the
rewrite-http-request macro (along with some
tree search/replace functions in util.lisp).
This makes upgrading
drakma-async to use the latest version of drakma as
simple as copying the
http-request function from drakma's request.lisp and
pasting it inside the
(rewrite-http-request ...) macro in drakma-aync's
hijack.lisp. This saves me a lot of time doing manual porting, and makes it
easy to use another version of drakma if that's required.