This is a port of the wonderful drakma library to run on top of cl-async.
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
for cl-async
to provide SSL functionality. drakma-async
will use SSL by
default, unless :drakma-no-ssl
is present in *features*
during load/compile
time.
Same goes for the test suite: if :drakma-no-ssl
is present in *features*
when the tests are loaded, no SSL tests are performed.
drakma-async
provides a function in the drakma
package called http-request-async
which mirrors 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
http-stream implementation
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.
Porting of drakma:http-request
to 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.