Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Documentation export in place.

  • Loading branch information...
commit c0b593f60214426588a1d200f16d2471e7348964 1 parent 687dfad
@neotyk authored
View
6 changelog.org
@@ -1,8 +1,7 @@
#+TITLE: Asynchronous HTTP Client - Clojure - Changelog
#+AUTHOR: Hubert Iwaniuk
#+EMAIL: neotyk@kungfoo.pl
-#+INFOJS_OPT: view:info toc:1
-#+OPTIONS: H:4
+#+SETUPFILE: setup.org
* Release 0.3.0
** Upgrade async-http-client to v1.6.3
@@ -35,6 +34,9 @@
;; client usage
(let [resp (GET client url)]))
#+end_src
+** Clojure 1.2.1
+ Fixed cyclic dependency that was preventing http.async.client from
+ been used in Clojure 1.2.1.
* Release 0.2.2
** get-encoding helper works w/o Content-Type header
** Upgrade async-http-client to v.1.5.0
View
1,557 docs.org
@@ -1,805 +1,800 @@
#+TITLE: Asynchronous HTTP Client - Clojure - Documentation
#+AUTHOR: Hubert Iwaniuk
#+EMAIL: neotyk@kungfoo.pl
-#+INFOJS_OPT: view:info toc:1
-#+OPTIONS: H:4
+#+SETUPFILE: setup.org
-* User Documentation
- How to use Asynchronous HTTP Client for Clojure
- a.k.a. *http.async.client*.
-** Quick start
- If you just want to use it already.
-*** Dependency
- Declare dependency in your project.clj:
- #+BEGIN_SRC clojure
- (defproject your-project "1.0.0-SNAPSHOT"
- :description "Your project description"
- :dependencies [[org.clojure/clojure "1.2.1"]
- [org.clojure/clojure-contrib "1.2.0"]
- [http.async.client "0.3-0-SNAPSHOT"]])
- #+END_SRC
- Make sure that your project depends on at least 1.2.0 Clojure as
- *http.async.client* will not run in earlier versions.
-*** Require
- Require it from your code:
- #+BEGIN_SRC clojure
- (ns your.ns (:require [http.async.client :as client]))
- #+END_SRC
-*** GETting
- To get HTTP resource:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- ;; request http resource
- (let [response (client/GET client "http://github.com/neotyk/http.async.client/")]
- ;; wait for response to be received
- (client/await response)
- ;; read body of response as string
- (client/string response)))
- #+END_SRC
-** Detailed start
-*** Work modes
-**** Asynchronous operations
- When you do:
- #+BEGIN_SRC clojure
- (client/GET <client> url)
- #+END_SRC
- Result will be a map of [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.util/promise][*http.async.client.util/promise*]]s, and
- represents response.
- Do not fear, this is [[http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/promise][clojure.core/promise]] that was extended to be
- able to check if it was delivered.
+* Quick start
+ If you just want to use it already.
+** Dependency
+ Declare dependency in your project.clj:
+ #+BEGIN_SRC clojure
+ (defproject your-project "1.0.0-SNAPSHOT"
+ :description "Your project description"
+ :dependencies [[org.clojure/clojure "1.2.1"]
+ [org.clojure/clojure-contrib "1.2.0"]
+ [http.async.client "0.3-0-SNAPSHOT"]])
+ #+END_SRC
+ Make sure that your project depends on at least 1.2.0 Clojure as
+ *http.async.client* will not run in earlier versions.
+** Require
+ Require it from your code:
+ #+BEGIN_SRC clojure
+ (ns your.ns (:require [http.async.client :as client]))
+ #+END_SRC
+** GETting
+ To get HTTP resource:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ ;; request http resource
+ (let [response (client/GET client "http://github.com/neotyk/http.async.client/")]
+ ;; wait for response to be received
+ (client/await response)
+ ;; read body of response as string
+ (client/string response)))
+ #+END_SRC
+* Detailed start
+** Work modes
+*** Asynchronous operations
+ When you do:
+ #+BEGIN_SRC clojure
+ (client/GET <client> url)
+ #+END_SRC
+ Result will be a map of [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.util/promise][*http.async.client.util/promise*]]s, and
+ represents response.
+ Do not fear, this is [[http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/promise][clojure.core/promise]] that was extended to be
+ able to check if it was delivered.
- Following HTTP methods have been covered so far:
- - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/GET][GET]]
- - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/POST][POST]]
- - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/PUT][PUT]]
- - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/DELETE][DELETE]]
- - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/HEAD][HEAD]]
- - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/OPTIONS][OPTIONS]]
- For detailed description see [[*HTTP%20methods][HTTP methods]].
+ Following HTTP methods have been covered so far:
+ - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/GET][GET]]
+ - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/POST][POST]]
+ - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/PUT][PUT]]
+ - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/DELETE][DELETE]]
+ - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/HEAD][HEAD]]
+ - [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/OPTIONS][OPTIONS]]
+ For detailed description see [[*HTTP%20methods][HTTP methods]].
- You can submit options to HTTP methods as keyworded arguments,
- like this:
- #+BEGIN_SRC clojure
- (client/GET <client> url :query {:key "value"})
- #+END_SRC
- Following options are supported:
- - *:query* :: query parameters
- - *:headers* :: custom headers to be sent out
- - *:body* :: body to be sent, allowed only with [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/PUT][PUT]]/[[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/POST][POST]]
- - *:cookies* :: cookies to be sent
- - *:proxy* :: proxy to be used
- For detailed usage of options see [[*Request%20options][Request options]].
+ You can submit options to HTTP methods as keyworded arguments,
+ like this:
+ #+BEGIN_SRC clojure
+ (client/GET <client> url :query {:key "value"})
+ #+END_SRC
+ Following options are supported:
+ - *:query* :: query parameters
+ - *:headers* :: custom headers to be sent out
+ - *:body* :: body to be sent, allowed only with [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/PUT][PUT]]/[[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/POST][POST]]
+ - *:cookies* :: cookies to be sent
+ - *:proxy* :: proxy to be used
+ For detailed usage of options see [[*Request%20options][Request options]].
- Response map contains following keys:
- - *:status* :: promise of lazy map of status fields
- - *:code* :: response code
- - *:msg* :: response message
- - *:protocol* :: protocol with version
- - *:major* :: major version of protocol
- - *:minor* :: minor version of protocol
- - *:headers* :: promise of lazy map of headers where header names are
- keyworded, like *:server* for example
- - *:body* :: promise of response body, this is ByteArrayOutputStream, but you
- have convenience functions to convert it for example to string:
- #+BEGIN_SRC clojure
- (client/string (client/GET <client> <url>))
- #+END_SRC
- - *:done* :: promise that is delivered once response receiving
- is done
- - *:error* :: promise, if there was an error you will find Throwable here
-**** Streaming
- For consuming HTTP streams use:
- #+BEGIN_SRC clojure
- (client/stream-seq <client> :get url)
- #+END_SRC
- Response here is same as in [[*%20Asynchronous%20operations][Asynchronous operations]] but *:body*
- will be lazy sequence of ByteArrayOutputStreams.
+ Response map contains following keys:
+ - *:status* :: promise of lazy map of status fields
+ - *:code* :: response code
+ - *:msg* :: response message
+ - *:protocol* :: protocol with version
+ - *:major* :: major version of protocol
+ - *:minor* :: minor version of protocol
+ - *:headers* :: promise of lazy map of headers where header names are
+ keyworded, like *:server* for example
+ - *:body* :: promise of response body, this is ByteArrayOutputStream, but you
+ have convenience functions to convert it for example to string:
+ #+BEGIN_SRC clojure
+ (client/string (client/GET <client> <url>))
+ #+END_SRC
+ - *:done* :: promise that is delivered once response receiving
+ is done
+ - *:error* :: promise, if there was an error you will find Throwable here
+*** Streaming
+ For consuming HTTP streams use:
+ #+BEGIN_SRC clojure
+ (client/stream-seq <client> :get url)
+ #+END_SRC
+ Response here is same as in [[*%20Asynchronous%20operations][Asynchronous operations]] but *:body*
+ will be lazy sequence of ByteArrayOutputStreams.
- You can still use convenience functions like *client/string* for body,
- but remember that you are dealing now with *seq*.
+ You can still use convenience functions like *client/string* for body,
+ but remember that you are dealing now with *seq*.
- For more details please see [[*Lazy%20sequence][Lazy sequence]].
-**** Raw mode
- This allows you to provide callbacks that will get triggered on HTTP
- response events like:
- - received status line,
- - received headers,
- - received body part,
- - completed request,
- - handle error.
- All callbacks are expected to return tuple with first element
- been a value to be delivered for given response processing phase,
- second element is controlling execution and if you make it
- *:abort* than processing response is going to be terminated.
+ For more details please see [[*Lazy%20sequence][Lazy sequence]].
+*** Raw mode
+ This allows you to provide callbacks that will get triggered on HTTP
+ response events like:
+ - received status line,
+ - received headers,
+ - received body part,
+ - completed request,
+ - handle error.
+ All callbacks are expected to return tuple with first element
+ been a value to be delivered for given response processing phase,
+ second element is controlling execution and if you make it
+ *:abort* than processing response is going to be terminated.
- For detailed information on how to use this mode please see [[*Low%20level][Low
- level]].
-*** HTTP methods
- HTTP methods and convenience functions to request them.
-**** GET
- Most basic invocation of [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/GET][*http.async.client/GET*]] is only with
- *url* you want to get.
- Extended invocation includes options that can be any options
- accepted by [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/prepare-request][*http.async.client.request/prepare-request*]]
- [:headers :query ..].
+ For detailed information on how to use this mode please see [[*Low%20level][Low
+ level]].
+** HTTP methods
+ HTTP methods and convenience functions to request them.
+*** GET
+ Most basic invocation of [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/GET][*http.async.client/GET*]] is only with
+ *url* you want to get.
+ Extended invocation includes options that can be any options
+ accepted by [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/prepare-request][*http.async.client.request/prepare-request*]]
+ [:headers :query ..].
- Simple invocation:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client "<your url>")
- status (client/status resp)
- headers (client/headers resp)]
- (println (:code status))
- (client/await resp)
- (println (client/string resp))))
- #+END_SRC
+ Simple invocation:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client "<your url>")
+ status (client/status resp)
+ headers (client/headers resp)]
+ (println (:code status))
+ (client/await resp)
+ (println (client/string resp))))
+ #+END_SRC
- Invocation with query parameters:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client "<your url>" :query {:param-name "some-value"})
- status (client/status resp)
- headers (client/headers resp)]
- (println (:code status))
- (client/await resp)
- (println (client/string resp))))
- #+END_SRC
+ Invocation with query parameters:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client "<your url>" :query {:param-name "some-value"})
+ status (client/status resp)
+ headers (client/headers resp)]
+ (println (:code status))
+ (client/await resp)
+ (println (client/string resp))))
+ #+END_SRC
- Invocation with proxy:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client "<your url>"
- :query {:param-name "some-value"}
- :proxy {:host host :port port})
- status (client/status resp)]
- (println (:code status))
- (client/await resp)
- (println (client/string resp))))
- #+END_SRC
+ Invocation with proxy:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client "<your url>"
+ :query {:param-name "some-value"}
+ :proxy {:host host :port port})
+ status (client/status resp)]
+ (println (:code status))
+ (client/await resp)
+ (println (client/string resp))))
+ #+END_SRC
- Invocation with cookies:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client "http://localhost:8123/cookie"
- ;; Send cookie
- :cookies #{{:domain "http://localhost:8123/"
- :name "sample-name"
- :value "sample-value"
- :path "/cookie"
- :max-age 10
- :secure false}})]
- (doseq [cookie (client/cookies resp)] ;; Read cookies from server response
- (println "name:" (:name cookie) ", value:" (:value cookie)))))
- #+END_SRC
- Notice [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/cookies][*http.async.client/cookies*]] function extracts cookies from
- response headers, so to start processing it you don't need to wait
- for whole response to arrive.
-**** PUT/POST
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/PUT][*http.async.client/PUT*]]/[[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/POST][*http.async.client/POST*]] work the same
- way as [[*%20http%20neotyk%20github%20com%20http%20async%20client%20autodoc%20http%20async%20client%20api%20html%20http%20async%20client%20GET%20GET][*GET*]] but they also accept *:body* argument.
+ Invocation with cookies:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client "http://localhost:8123/cookie"
+ ;; Send cookie
+ :cookies #{{:domain "http://localhost:8123/"
+ :name "sample-name"
+ :value "sample-value"
+ :path "/cookie"
+ :max-age 10
+ :secure false}})]
+ (doseq [cookie (client/cookies resp)] ;; Read cookies from server response
+ (println "name:" (:name cookie) ", value:" (:value cookie)))))
+ #+END_SRC
+ Notice [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/cookies][*http.async.client/cookies*]] function extracts cookies from
+ response headers, so to start processing it you don't need to wait
+ for whole response to arrive.
+*** PUT/POST
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/PUT][*http.async.client/PUT*]]/[[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/POST][*http.async.client/POST*]] work the same
+ way as [[*%20http%20neotyk%20github%20com%20http%20async%20client%20autodoc%20http%20async%20client%20api%20html%20http%20async%20client%20GET%20GET][*GET*]] but they also accept *:body* argument.
- *:body* can be:
- - String
- - map, for easy form data submissions
- - InputStream for any content
- - File for zero byte copy
-***** Submitting body as String
- You can send String as body with PUT/POST:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/POST client "<your url>" :body "SampleBody")]
- ; do something with resp
- ))
- #+END_SRC
-***** Submitting form parameters
- Submitting parameters via body map:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/POST client "<your url>" :body {:u "user" :p "s3cr3t"})]
- ; do something with resp
- ))
- #+END_SRC
-***** Submitting body as InputStream
- Another method to provide body is via InputStream:
- #+BEGIN_SRC clojure
- (use '[clojure.java.io :only [input-stream]])
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/PUT client "<your url>" :body (input-stream (.getBytes "SampleContent" "UTF-8")))]
- ; do something with resp
- ))
- #+END_SRC
-***** Submitting body as File, a.k.a. zero byte copy
- To use zero byte copy future, provide a File as :body
- #+begin_src clojure
- (import '(java.io File))
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/PUT "<your url>" :body (File. "<path to file>"))]
- ;; do something with resp
- ))
- #+end_src
-**** DELETE
- To call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/DELETE][*http.async.client/DELETE*]] on a resource:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/DELETE "<your url>")]
- ; do something with resp
- ))
- #+END_SRC
-**** HEAD
- To call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/HEAD][*http.async.client/HEAD*]] on a resource:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/HEAD "<your url>")]
- ; do something with resp
- ))
- #+END_SRC
-**** OPTIONS
- To call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/OPTIONS][*http.async.client/OPTIONS*]] on a resource:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/OPTIONS "<your url>")]
- ; do something with resp
- ))
- #+END_SRC
-*** Request options
- Following options can be provided to requests and are defined by
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/prepare-request][*http.async.client.request/prepare-request*]]:
- - [[*%20query][:query]] :: query parameters
- - [[*%20headers][:headers]] :: custom headers to be sent out
- - [[*%20body][:body]] :: body to be sent, allowed only with PUT/POST
- - [[*%20cookies][:cookies]] :: cookies to be sent
- - [[*%20proxy][:proxy]] :: proxy to be used
- - [[*%20auth][:auth]] :: authentication map
- - [[*:timeout][:timeout]] :: timeout configuration
-**** :query
- Query parameters is a map of keywords and their values. You use
- it like so:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url :query {:key1 "value1" :key2 "value2"})]
- (client/await resp)
- (client/string resp)))
- #+END_SRC
-**** :headers
- Custom headers can be submitted same way as [[*%20query][:query]]:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url :headers {:header-name1 "value1"
- :header-name2 "value2"})]
- (client/await resp)
- (client/string resp)))
- #+END_SRC
-**** :body
- Body can be provided with a message only with [[*PUT%20POST][PUT/POST]], it
- doesn't make sense to have body with other [[*HTTP%20methods][HTTP methods]].
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/PUT client url :body "sample body")]
- (client/await resp)
- (client/string resp)))
- #+END_SRC
- *:body* can be String, form parameters (that is map), input stream or
- java.io.File, please see [[*PUT%20POST][PUT/POST]] for more documentation.
-**** :cookies
- Cookies can be provided to request as follows:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client "http://localhost:8123/cookie"
- :cookies #{{:domain "http://localhost:8123/"
- :name "sample-name"
- :value "sample-value"
- :path "/cookie"
- :max-age 10
- :secure false}})]
- (client/await resp)
- (client/string resp)))
- #+END_SRC
- *:cookies* option takes sequence of cookie maps, in this example
- a hash set.
- Cookie map consist of:
- - *:domain* :: Domain that cookie has been installed
- - *:name* :: Cookie name
- - *:value* :: Cookie value, note that there is no additional
- processing so you should encode it yourself if
- needed.
- - *:path* :: Path on with cookie has been installed
- - *:max-age* :: Max age that cookie was configured to live
- - *:secure* :: If cookie is secure cookie
+ *:body* can be:
+ - String
+ - map, for easy form data submissions
+ - InputStream for any content
+ - File for zero byte copy
+**** Submitting body as String
+ You can send String as body with PUT/POST:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/POST client "<your url>" :body "SampleBody")]
+ ; do something with resp
+ ))
+ #+END_SRC
+**** Submitting form parameters
+ Submitting parameters via body map:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/POST client "<your url>" :body {:u "user" :p "s3cr3t"})]
+ ; do something with resp
+ ))
+ #+END_SRC
+**** Submitting body as InputStream
+ Another method to provide body is via InputStream:
+ #+BEGIN_SRC clojure
+ (use '[clojure.java.io :only [input-stream]])
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/PUT client "<your url>" :body (input-stream (.getBytes "SampleContent" "UTF-8")))]
+ ; do something with resp
+ ))
+ #+END_SRC
+**** Submitting body as File, a.k.a. zero byte copy
+ To use zero byte copy future, provide a File as :body
+ #+begin_src clojure
+ (import '(java.io File))
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/PUT "<your url>" :body (File. "<path to file>"))]
+ ;; do something with resp
+ ))
+ #+end_src
+*** DELETE
+ To call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/DELETE][*http.async.client/DELETE*]] on a resource:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/DELETE "<your url>")]
+ ; do something with resp
+ ))
+ #+END_SRC
+*** HEAD
+ To call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/HEAD][*http.async.client/HEAD*]] on a resource:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/HEAD "<your url>")]
+ ; do something with resp
+ ))
+ #+END_SRC
+*** OPTIONS
+ To call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/OPTIONS][*http.async.client/OPTIONS*]] on a resource:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/OPTIONS "<your url>")]
+ ; do something with resp
+ ))
+ #+END_SRC
+** Request options
+ Following options can be provided to requests and are defined by
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/prepare-request][*http.async.client.request/prepare-request*]]:
+ - [[*%20query][:query]] :: query parameters
+ - [[*%20headers][:headers]] :: custom headers to be sent out
+ - [[*%20body][:body]] :: body to be sent, allowed only with PUT/POST
+ - [[*%20cookies][:cookies]] :: cookies to be sent
+ - [[*%20proxy][:proxy]] :: proxy to be used
+ - [[*%20auth][:auth]] :: authentication map
+ - [[*:timeout][:timeout]] :: timeout configuration
+*** :query
+ Query parameters is a map of keywords and their values. You use
+ it like so:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url :query {:key1 "value1" :key2 "value2"})]
+ (client/await resp)
+ (client/string resp)))
+ #+END_SRC
+*** :headers
+ Custom headers can be submitted same way as [[*%20query][:query]]:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url :headers {:header-name1 "value1"
+ :header-name2 "value2"})]
+ (client/await resp)
+ (client/string resp)))
+ #+END_SRC
+*** :body
+ Body can be provided with a message only with [[*PUT%20POST][PUT/POST]], it
+ doesn't make sense to have body with other [[*HTTP%20methods][HTTP methods]].
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/PUT client url :body "sample body")]
+ (client/await resp)
+ (client/string resp)))
+ #+END_SRC
+ *:body* can be String, form parameters (that is map), input stream or
+ java.io.File, please see [[*PUT%20POST][PUT/POST]] for more documentation.
+*** :cookies
+ Cookies can be provided to request as follows:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client "http://localhost:8123/cookie"
+ :cookies #{{:domain "http://localhost:8123/"
+ :name "sample-name"
+ :value "sample-value"
+ :path "/cookie"
+ :max-age 10
+ :secure false}})]
+ (client/await resp)
+ (client/string resp)))
+ #+END_SRC
+ *:cookies* option takes sequence of cookie maps, in this example
+ a hash set.
+ Cookie map consist of:
+ - *:domain* :: Domain that cookie has been installed
+ - *:name* :: Cookie name
+ - *:value* :: Cookie value, note that there is no additional
+ processing so you should encode it yourself if
+ needed.
+ - *:path* :: Path on with cookie has been installed
+ - *:max-age* :: Max age that cookie was configured to live
+ - *:secure* :: If cookie is secure cookie
- Cookie reading is described in [[*Reading%20cookies][Reading cookies]].
-**** :proxy
- Proxy can be configured per request basis as follows:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url :proxy {:host h :port p})]
- (client/await resp)
- (client/string resp)))
- #+END_SRC
- Proxy expects a map with following keys:
- - *:host* :: proxy host
- - *:port* :: proxy port
- - *:protocol* :: /optional/ protocol to communicate with proxy.
- Can be *:http* (default) or *:https*.
- - *:user* :: /optional/ user name to use for proxy authentication.
- Must be provided with :password.
- - *:password* :: /optional/ password to use for proxy
- authentication.
- Must be provided with :user.
-**** :auth
- Authentication can be configured per request basis.
- For now BASIC and DIGEST methods are supported.
+ Cookie reading is described in [[*Reading%20cookies][Reading cookies]].
+*** :proxy
+ Proxy can be configured per request basis as follows:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url :proxy {:host h :port p})]
+ (client/await resp)
+ (client/string resp)))
+ #+END_SRC
+ Proxy expects a map with following keys:
+ - *:host* :: proxy host
+ - *:port* :: proxy port
+ - *:protocol* :: /optional/ protocol to communicate with proxy.
+ Can be *:http* (default) or *:https*.
+ - *:user* :: /optional/ user name to use for proxy authentication.
+ Must be provided with :password.
+ - *:password* :: /optional/ password to use for proxy
+ authentication.
+ Must be provided with :user.
+*** :auth
+ Authentication can be configured per request basis.
+ For now BASIC and DIGEST methods are supported.
- Basic method is default, so you don't have to specify it:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url :auth {:user u :password p})]
- ;; Check if response is not 401 or so and process response
- ))
- #+END_SRC
- Though you can:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url :auth {:type :basic :user u :password p})]
- ;; Check if response is not 401 or so and process response
- ))
- #+END_SRC
- And for digest method you will need realm as well:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url
- :auth {:type :digest :user u :password p :realm r})]
- ;; Check if response is not 401 or so and process response
- ))
- #+END_SRC
-**** :timeout
- Response timeout can be configured per request as well.
- Timeout value is time in milliseconds in which response has to be
- received.
- There is special value *-1* that indicates infinite timeout.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url :timeout -1)]
- (client/await resp)
- ;; process response
- ))
- #+END_SRC
- Sample above will wait until response is fully received, as long
- as it takes (-1 timeout).
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url :timeout 100)]
- (client/await resp)
- (if (client/failed? resp)
- ;; did not get response in configured timeout
- ;; process response
- )))
- #+END_SRC
- Example above configures timeout to 100ms, so *await* will only
- wait for 100ms, after that response is done.
- Which doesn't necessarily mean that it was delivered to client
- successfully, because it was restricted by timeout, that is why
- example contains check if response has failed.
-*** Streaming
- HTTP Stream is response with chunked content encoding.
- Those streams might not be meant to ever finish, see twitter.com
- streams, so collecting those responses as a whole is impossible,
- they should be processed by response parts (chunks) as they are
- been received.
+ Basic method is default, so you don't have to specify it:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url :auth {:user u :password p})]
+ ;; Check if response is not 401 or so and process response
+ ))
+ #+END_SRC
+ Though you can:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url :auth {:type :basic :user u :password p})]
+ ;; Check if response is not 401 or so and process response
+ ))
+ #+END_SRC
+ And for digest method you will need realm as well:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url
+ :auth {:type :digest :user u :password p :realm r})]
+ ;; Check if response is not 401 or so and process response
+ ))
+ #+END_SRC
+*** :timeout
+ Response timeout can be configured per request as well.
+ Timeout value is time in milliseconds in which response has to be
+ received.
+ There is special value *-1* that indicates infinite timeout.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url :timeout -1)]
+ (client/await resp)
+ ;; process response
+ ))
+ #+END_SRC
+ Sample above will wait until response is fully received, as long
+ as it takes (-1 timeout).
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url :timeout 100)]
+ (client/await resp)
+ (if (client/failed? resp)
+ ;; did not get response in configured timeout
+ ;; process response
+ )))
+ #+END_SRC
+ Example above configures timeout to 100ms, so *await* will only
+ wait for 100ms, after that response is done.
+ Which doesn't necessarily mean that it was delivered to client
+ successfully, because it was restricted by timeout, that is why
+ example contains check if response has failed.
+** Streaming
+ HTTP Stream is response with chunked content encoding.
+ Those streams might not be meant to ever finish, see twitter.com
+ streams, so collecting those responses as a whole is impossible,
+ they should be processed by response parts (chunks) as they are
+ been received.
- Two ways of consuming a HTTP Stream are supported:
- - [[*Lazy%20sequence][Lazy sequence]]
- - [[*Call%20back][Call-back]]
-**** Lazy sequence
- You can get HTTP Stream as lazy sequence of it's body.
- This is very convenient method as *seq* is native type of Clojure
- so you can apply all mapping, filtering and any other standard
- function that you like to it.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/stream-seq client :get url)]
- (doseq [s (s/string resp)]
- (println s))))
- #+END_SRC
- *stream-seq* arguments:
- - http method :: any of supported methods can be used, though it
- makes sense only to use *:get*, *:put* and
- *:post*
- - url :: URL of HTTP resource
- - options :: same as normal [[*Request%20options][Request options]].
+ Two ways of consuming a HTTP Stream are supported:
+ - [[*Lazy%20sequence][Lazy sequence]]
+ - [[*Call%20back][Call-back]]
+*** Lazy sequence
+ You can get HTTP Stream as lazy sequence of it's body.
+ This is very convenient method as *seq* is native type of Clojure
+ so you can apply all mapping, filtering and any other standard
+ function that you like to it.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/stream-seq client :get url)]
+ (doseq [s (s/string resp)]
+ (println s))))
+ #+END_SRC
+ *stream-seq* arguments:
+ - http method :: any of supported methods can be used, though it
+ makes sense only to use *:get*, *:put* and
+ *:post*
+ - url :: URL of HTTP resource
+ - options :: same as normal [[*Request%20options][Request options]].
- It is important to understand that seqs returned by *body* or
- *string* (which in turn calls body) are backed by queue.
- One of consequences of it is that once you consumed some body
- parts they will not be available anymore.
- Let's see code speak for itself.
- #+BEGIN_SRC clojure
- (let [resp (client/stream-seq :get url)]
- (println "1: " (first (client/string resp)))
- (println "2: " (first (client/string resp))))
- #+END_SRC
- This code will print following:
- : 1: part1
- : 2: part2
- Assuming that part1 is first chunk and part2 is second.
+ It is important to understand that seqs returned by *body* or
+ *string* (which in turn calls body) are backed by queue.
+ One of consequences of it is that once you consumed some body
+ parts they will not be available anymore.
+ Let's see code speak for itself.
+ #+BEGIN_SRC clojure
+ (let [resp (client/stream-seq :get url)]
+ (println "1: " (first (client/string resp)))
+ (println "2: " (first (client/string resp))))
+ #+END_SRC
+ This code will print following:
+ : 1: part1
+ : 2: part2
+ Assuming that part1 is first chunk and part2 is second.
- Second consequence of been directly backed by queue is that you
- can have multiple consumers of same response and non of them will
- get same body part.
+ Second consequence of been directly backed by queue is that you
+ can have multiple consumers of same response and non of them will
+ get same body part.
- And finally this implementation is not holding to it's head.
-**** Call-back
- Consuming HTTP Stream with call-back is quite straight forward with
- *http.async.client*. You will need to know what HTTP Method you will call,
- what URL and provide a call back function to handle body parts been
- received.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [parts (ref #{})
- resp (client/request-stream client :get url
- (fn [state body]
- (dosync (alter parts conj (string body)))
- [body :continue]))]
- ;; do something to @parts
- ))
- #+END_SRC
+ And finally this implementation is not holding to it's head.
+*** Call-back
+ Consuming HTTP Stream with call-back is quite straight forward with
+ *http.async.client*. You will need to know what HTTP Method you will call,
+ what URL and provide a call back function to handle body parts been
+ received.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [parts (ref #{})
+ resp (client/request-stream client :get url
+ (fn [state body]
+ (dosync (alter parts conj (string body)))
+ [body :continue]))]
+ ;; do something to @parts
+ ))
+ #+END_SRC
- Few notes on implementing body part callback:
- - state is a *map* with *:status* and *:headers* as promises, at
- stage when you get called for body part, both of them should be in
- place already, though it is advised to use convenience methods to
- read them, see [[*Reading%20status%20line][Reading status line]] and [[*Reading%20headers][Reading headers]],
- - call-back has to follow guidelines described in [[*Body%20part][Body part]],
- - some streams are not meant to be finish, in that case don't
- collect body parts, as for sure you will run out of available
- resources,
- - try not to do any heavy lifting in this callback, better send it
- to agent.
-*** Response handling
- *http.async.client* exposes some convenience functions for
- response handling.
-**** Awaiting response
- If you call any of [[*Asynchronous%20operations][Asynchronous operations]], [[*Streaming][Streaming]] or [[*Raw%20mode][Raw mode]]
- you actually asynchronously execute HTTP request.
- Some times you might need to wait for response processing to be
- done before proceeding, in order to do so you call
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/await][*http.async.client/await*]].
- It takes only one argument, that is response and returns once
- receiving has finished.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)]
- (client/await resp)))
- #+END_SRC
- Sample above will behave like synchronous HTTP operation.
- For convenience it returns same response so you can use it
- further, for example like that:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)]
- (client/string (client/await resp))))
- #+END_SRC
-**** Reading status line
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/status][*http.async.client/status*]] returns status lazy map of response.
- It will wait until HTTP Status has been received.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)
- status (client/status resp)]
- (:code status)))
- #+END_SRC
- Sample above will return HTTP response status code, notice that
- after this returns headers and body, might not been delivered
- yet.
-**** Reading headers
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/headers][*http.async.client/headers*]] returns headers lazy map of response.
- It will wait until HTTP Headers are received.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)
- headers (client/headers resp)]
- (:server headers)))
- #+END_SRC
- Again, like in case of status, body might not have been delivered
- yet after this returns.
-**** Reading cookies
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/cookies][*http.async.client/cookies*]] returns seq of maps representing
- cookies.
- It will wait until HTTP Headers are received.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)
- cookies (client/cookies resp)]
- (map :name cookies)))
- #+END_SRC
- Sample above will return sequence of cookie names that server has
- set.
-**** Reading body
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/body][*http.async.client/body*]] returns either ByteArrayOutputStream or
- seq of it, depending if you used [[*Asynchronous%20operations][Asynchronous operations]] or
- [[*Streaming][Streaming]] respectively.
- It will *not* wait for response to be finished, it will return as
- soon as first chunk of HTTP response body is received.
-**** Reading body as string
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/string][*http.async.client/string*]] returns either string or seq of
- strings, again depending if you used [[*Asynchronous%20operations][Asynchronous operations]] or
- [[*Streaming][Streaming]] respectively.
- It will *not* wait for response to be finished, it will return as
- soon as first chunk of HTTP response body is received.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)]
- (client/string (client/await resp))))
- #+END_SRC
- Sample above will return string of response body.
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/string][*http.async.client/string*]] is lazy so you can use it in case of
- streams as well.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/stream-seq client :get url)
- strings (client/string resp)]
- (doseq [part strings]
- (println part))))
- #+END_SRC
- Sample above will print parts as they are received, and will
- return once response receiving is finished.
-**** Reading error
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/error][*http.async.client/error*]] will return Throwable that was cause of
- request failure iff request failed, else *nil*.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)]
- (client/await resp)
- (when-let [err (client/error resp)]
- (println "failed processing request: " err))))
- #+END_SRC
-**** Canceling request
- At any given time of processing HTTP Response you can *cancel* it
- by calling [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/cancel][*http.async.client/cancel*]].
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)]
- (client/cancel resp)))
- #+END_SRC
- Please see *canceling-request* test.
-**** Response predicates
- You can also check status of request.
-***** done?
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/done?][*http.async.client/done?*]] will tell you if response processing
- has finished:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)] ;; Create client
- (let [resp (client/GET client url)]
- (when-not (client/done? resp)
- (client/await resp)
- (client/done? resp))))
- #+END_SRC
- Sample above will check if response was finished, if not - will
- wait for it and return true as a result of call to done?.
-***** failed?
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/failed?][*http.async.client/failed?*]] will return true iff request has
- failed. If this return true you can [[*Reading%20error][read error]].
-***** canceled?
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/canceled?][*http.async.client/canceled?*]] will return true iff request has
- been [[*Canceling%20request][canceled]], else false is return.
-*** Managing *http.async.client*
-**** Branding
- *http.async.client* can be configured with User-Agent. To do so
- you can use [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/create-client][*http.async.client/create-client*]] and remember to
- close created client yourself, best is to use it within macro
- like with-open, though make sure that body of it will wait for
- whore response to finish.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client {:user-agent "Your User Agent/1.0"})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+END_SRC
-**** Enabling HTTP compression
- *http.async.client* can be configured to allow, or not, HTTP
- compression.
- #+begin_src clojure
- (with-open [client (client/create-client {:compression-enabled true})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+end_src
-**** Follow redirects
- Enabling HTTP redirects following.
- #+begin_src clojure
- (with-open [client (client/create-client {:follow-redirects true})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+end_src
-**** Keep alive
- Keep Alive is enabled by default. This implies using pool for
- connections.
- #+begin_src clojure
- (with-open [client (client/create-client {:keep-alive true})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+end_src
-**** Max connections per host
- Maximum number of connections to be cached per host.
- Above this number connections will still be created but will not
- be kept alive.
- #+begin_src clojure
- (with-open [client (client/create-client {:max-conns-per-host 10})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+end_src
-**** Max connections total count
- Maximum number of total connections opened, submitting new
- request while all allowed connections are active, will result in
- rejection.
- #+begin_src clojure
- (with-open [client (client/create-client {:max-conns-total 100})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+end_src
-**** Max redirects to follow
- Maximum number of redirects to follow.
- #+begin_src clojure
- (with-open [client (client/create-client {:max-redirects 3})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+end_src
-**** Timeouts
- With *http.async.client* apart from per connection [[*:timeout][:timeout]] you
- can globally configure *connection*, *request* and *idle*
- timeouts. All timeout values are in milliseconds and magic value
- *-1* is interpreted as infinite wait.
- *idle* connection in pool timeout works only on connections in
- pool, connections idle, for configured time, in pool will be
- closed.
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client {:connection-timeout 10
- :request-timeout 1000
- :idle-in-pool-timeout 100})]
- (let [resp (client/client client/GET url)]
- ;; request processing
- ))
- #+END_SRC
- Example above will timeout connection if it was not established
- in 10ms, request if it was not received in 1sec, or connection
- when it was idling in pool for more than 100ms.
-**** Proxy
- Client can be also configured with global HTTP Proxy settings.
- #+begin_src clojure
- (with-open [client (client/create-client {:proxy {:host h :port p}})]
- (let [resp (client/GET client url)]
- ;; do stuff with resp
- ))
- #+end_src
- Proxy expects a map with following keys:
- - *:host* :: proxy host
- - *:port* :: proxy port
- - *:protocol* :: /optional/ protocol to communicate with proxy.
- Can be *:http* (default) or *:https*.
- - *:user* :: /optional/ user name to use for proxy authentication.
- Must be provided with :password.
- - *:password* :: /optional/ password to use for proxy
- authentication.
- Must be provided with :user.
-**** Authentication
- Default authentication realm to be used globally can be
- configured.
- For now BASIC and DIGEST methods are supported.
+ Few notes on implementing body part callback:
+ - state is a *map* with *:status* and *:headers* as promises, at
+ stage when you get called for body part, both of them should be in
+ place already, though it is advised to use convenience methods to
+ read them, see [[*Reading%20status%20line][Reading status line]] and [[*Reading%20headers][Reading headers]],
+ - call-back has to follow guidelines described in [[*Body%20part][Body part]],
+ - some streams are not meant to be finish, in that case don't
+ collect body parts, as for sure you will run out of available
+ resources,
+ - try not to do any heavy lifting in this callback, better send it
+ to agent.
+** Response handling
+ *http.async.client* exposes some convenience functions for
+ response handling.
+*** Awaiting response
+ If you call any of [[*Asynchronous%20operations][Asynchronous operations]], [[*Streaming][Streaming]] or [[*Raw%20mode][Raw mode]]
+ you actually asynchronously execute HTTP request.
+ Some times you might need to wait for response processing to be
+ done before proceeding, in order to do so you call
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/await][*http.async.client/await*]].
+ It takes only one argument, that is response and returns once
+ receiving has finished.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)]
+ (client/await resp)))
+ #+END_SRC
+ Sample above will behave like synchronous HTTP operation.
+ For convenience it returns same response so you can use it
+ further, for example like that:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)]
+ (client/string (client/await resp))))
+ #+END_SRC
+*** Reading status line
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/status][*http.async.client/status*]] returns status lazy map of response.
+ It will wait until HTTP Status has been received.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)
+ status (client/status resp)]
+ (:code status)))
+ #+END_SRC
+ Sample above will return HTTP response status code, notice that
+ after this returns headers and body, might not been delivered
+ yet.
+*** Reading headers
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/headers][*http.async.client/headers*]] returns headers lazy map of response.
+ It will wait until HTTP Headers are received.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)
+ headers (client/headers resp)]
+ (:server headers)))
+ #+END_SRC
+ Again, like in case of status, body might not have been delivered
+ yet after this returns.
+*** Reading cookies
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/cookies][*http.async.client/cookies*]] returns seq of maps representing
+ cookies.
+ It will wait until HTTP Headers are received.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)
+ cookies (client/cookies resp)]
+ (map :name cookies)))
+ #+END_SRC
+ Sample above will return sequence of cookie names that server has
+ set.
+*** Reading body
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/body][*http.async.client/body*]] returns either ByteArrayOutputStream or
+ seq of it, depending if you used [[*Asynchronous%20operations][Asynchronous operations]] or
+ [[*Streaming][Streaming]] respectively.
+ It will *not* wait for response to be finished, it will return as
+ soon as first chunk of HTTP response body is received.
+*** Reading body as string
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/string][*http.async.client/string*]] returns either string or seq of
+ strings, again depending if you used [[*Asynchronous%20operations][Asynchronous operations]] or
+ [[*Streaming][Streaming]] respectively.
+ It will *not* wait for response to be finished, it will return as
+ soon as first chunk of HTTP response body is received.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)]
+ (client/string (client/await resp))))
+ #+END_SRC
+ Sample above will return string of response body.
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/string][*http.async.client/string*]] is lazy so you can use it in case of
+ streams as well.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/stream-seq client :get url)
+ strings (client/string resp)]
+ (doseq [part strings]
+ (println part))))
+ #+END_SRC
+ Sample above will print parts as they are received, and will
+ return once response receiving is finished.
+*** Reading error
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/error][*http.async.client/error*]] will return Throwable that was cause of
+ request failure iff request failed, else *nil*.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)]
+ (client/await resp)
+ (when-let [err (client/error resp)]
+ (println "failed processing request: " err))))
+ #+END_SRC
+*** Canceling request
+ At any given time of processing HTTP Response you can *cancel* it
+ by calling [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/cancel][*http.async.client/cancel*]].
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)]
+ (client/cancel resp)))
+ #+END_SRC
+ Please see *canceling-request* test.
+*** Response predicates
+ You can also check status of request.
+**** done?
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/done?][*http.async.client/done?*]] will tell you if response processing
+ has finished:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)] ;; Create client
+ (let [resp (client/GET client url)]
+ (when-not (client/done? resp)
+ (client/await resp)
+ (client/done? resp))))
+ #+END_SRC
+ Sample above will check if response was finished, if not - will
+ wait for it and return true as a result of call to done?.
+**** failed?
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/failed?][*http.async.client/failed?*]] will return true iff request has
+ failed. If this return true you can [[*Reading%20error][read error]].
+**** canceled?
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/canceled?][*http.async.client/canceled?*]] will return true iff request has
+ been [[*Canceling%20request][canceled]], else false is return.
+** Managing client
+*** Branding
+ *http.async.client* can be configured with User-Agent. To do so
+ you can use [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/create-client][*http.async.client/create-client*]] and remember to
+ close created client yourself, best is to use it within macro
+ like with-open, though make sure that body of it will wait for
+ whore response to finish.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client {:user-agent "Your User Agent/1.0"})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+END_SRC
+*** Enabling HTTP compression
+ *http.async.client* can be configured to allow, or not, HTTP
+ compression.
+ #+begin_src clojure
+ (with-open [client (client/create-client {:compression-enabled true})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+end_src
+*** Follow redirects
+ Enabling HTTP redirects following.
+ #+begin_src clojure
+ (with-open [client (client/create-client {:follow-redirects true})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+end_src
+*** Keep alive
+ Keep Alive is enabled by default. This implies using pool for
+ connections.
+ #+begin_src clojure
+ (with-open [client (client/create-client {:keep-alive true})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+end_src
+*** Max connections per host
+ Maximum number of connections to be cached per host.
+ Above this number connections will still be created but will not
+ be kept alive.
+ #+begin_src clojure
+ (with-open [client (client/create-client {:max-conns-per-host 10})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+end_src
+*** Max connections total count
+ Maximum number of total connections opened, submitting new
+ request while all allowed connections are active, will result in
+ rejection.
+ #+begin_src clojure
+ (with-open [client (client/create-client {:max-conns-total 100})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+end_src
+*** Max redirects to follow
+ Maximum number of redirects to follow.
+ #+begin_src clojure
+ (with-open [client (client/create-client {:max-redirects 3})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+end_src
+*** Timeouts
+ With *http.async.client* apart from per connection [[*:timeout][:timeout]] you
+ can globally configure *connection*, *request* and *idle*
+ timeouts. All timeout values are in milliseconds and magic value
+ *-1* is interpreted as infinite wait.
+ *idle* connection in pool timeout works only on connections in
+ pool, connections idle, for configured time, in pool will be
+ closed.
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client {:connection-timeout 10
+ :request-timeout 1000
+ :idle-in-pool-timeout 100})]
+ (let [resp (client/client client/GET url)]
+ ;; request processing
+ ))
+ #+END_SRC
+ Example above will timeout connection if it was not established
+ in 10ms, request if it was not received in 1sec, or connection
+ when it was idling in pool for more than 100ms.
+*** Proxy
+ Client can be also configured with global HTTP Proxy settings.
+ #+begin_src clojure
+ (with-open [client (client/create-client {:proxy {:host h :port p}})]
+ (let [resp (client/GET client url)]
+ ;; do stuff with resp
+ ))
+ #+end_src
+ Proxy expects a map with following keys:
+ - *:host* :: proxy host
+ - *:port* :: proxy port
+ - *:protocol* :: /optional/ protocol to communicate with proxy.
+ Can be *:http* (default) or *:https*.
+ - *:user* :: /optional/ user name to use for proxy authentication.
+ Must be provided with :password.
+ - *:password* :: /optional/ password to use for proxy
+ authentication.
+ Must be provided with :user.
+*** Authentication
+ Default authentication realm to be used globally can be
+ configured.
+ For now BASIC and DIGEST methods are supported.
- Basic method is default, so you don't have to specify it:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client {:auth {:user u :password p}})]
- (let [resp (client/GET client url)]
- ;; Check if response is not 401 or so and process response
- ))
- #+END_SRC
- Though you can:
- #+BEGIN_SRC clojure
- (client/with-client {:auth {:type :basic :user u :password p}}
- (let [resp (client/GET client url)]
- ;; Check if response is not 401 or so and process response
- ))
- #+END_SRC
- And for digest method you will need realm as well:
- #+BEGIN_SRC clojure
- (client/with-client {:auth {:type :digest :user u :password p :realm r}}
- (let [resp (client/GET client url)]
- ;; Check if response is not 401 or so and process response
- ))
- #+END_SRC
-**** Closing *http.async.client*
- Whenever you've created *http.async.client* via
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/create-client][*http.async.client/create-client*]] you will need to close it.
- To do so you call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/close][*http.async.client/close*]], *http.async.client*
- relies on client been bound to **client**.
- #+BEGIN_SRC clojure
- (let [client (client/create-client)]
- (try
- (let [resp (client/GET client url)]
- ;; process response
- )
- (finally
- (client/close *client*))))
- #+END_SRC
-** Low level
-*** Requesting
- This is lowest level access to *http.async.client*.
- Mechanics here is based on asynchronous call-backs.
- It provides default set of callbacks and functions to create and
- execute requests.
-**** Preparing request
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/prepare-request][*http.async.client.request/prepare-request*]] is responsible for
- request preparation, like name suggests.
- It takes following arguments:
- - HTTP Method like *:get* *:head*
- - *url* that you want to call
- - and *options*, a keyworded map described already in [[*Request%20options][Request options]].
- Sample:
- #+BEGIN_SRC clojure
- (with-open [client (client/create-client)]
- (let [req (prepare-request client
- :get "http://google.com"
- :headers {:my-header "value"})]
- ;; now you have request, next thing to do would be to execute it
- ))
- #+END_SRC
-**** Executing request
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/execute-request][*http.async.client/execute-request*]] returns same map of promises
- as [[*Asynchronous%20operations][Asynchronous operations]].
- Its arguments are: request to be executed (result of [[*Preparing%20request][Preparing
- request]]) and *options* as keyworded map consisting of call-backs.
- Following *options* are recognized:
- - *:status* [[*Status%20line][Status line]]
- - *:headers* [[*Headers][Headers]]
- - *:part* [[*Body%20part][Body part]]
- - *:completed* [[*Body%20completed][Body completed]]
- - *:error* [[*Error][Error]]
- All callbacks take response map as first argument and callback
- specific argument if any.
- Callbacks are expected to return tuple of *result* and *action*:
- - *result* :: will be delivered to respective promise in response
- map
- - *action* :: if its value is *:abort* than response processing
- will be aborted, anything else here will result in
- continuation.
-***** Status line
- Status line callback gets called after status line has been
- received with arguments:
- - response map
- - Status map has following keys:
- - *:code* status code (200, 404, ..)
- - *:msg* status message ("OK", ..)
- - *:protocol* protocol with version ("HTTP/1.1")
- - *:major* major protocol version (1)
- - *:minor* minor protocol version (0, 1)
-***** Headers
- Headers callback gets called after headers have been received
- with arguments:
- - response map
- - lazy map of headers. Keys in that map are *(keyword
- (.toLowerCase <header name>))*, so "Server" headers is
- *:server* and so on.
-***** Body part
- Body part callback gets called after each part of body has been
- received with arguments:
- - response map
- - ByteArrayOutputStream that contains body part received.
-***** Body completed
- This callback gets called when receiving of response body has
- finished with only one argument, i.e. response map.
-***** Error
- Error callback gets called when error while processing has been
- encountered with arguments
- - response map
- - *Throwable* that was a cause of failure
-**** Default set of callbacks
- [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/*default-callbacks*][*http.async.client.request/*default-callbacks**]] is a map of
- default callbacks. This fill allow you to easy change only few
- callbacks and reuse default for the rest.
+ Basic method is default, so you don't have to specify it:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client {:auth {:user u :password p}})]
+ (let [resp (client/GET client url)]
+ ;; Check if response is not 401 or so and process response
+ ))
+ #+END_SRC
+ Though you can:
+ #+BEGIN_SRC clojure
+ (client/with-client {:auth {:type :basic :user u :password p}}
+ (let [resp (client/GET client url)]
+ ;; Check if response is not 401 or so and process response
+ ))
+ #+END_SRC
+ And for digest method you will need realm as well:
+ #+BEGIN_SRC clojure
+ (client/with-client {:auth {:type :digest :user u :password p :realm r}}
+ (let [resp (client/GET client url)]
+ ;; Check if response is not 401 or so and process response
+ ))
+ #+END_SRC
+*** Closing *http.async.client*
+ Whenever you've created *http.async.client* via
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/create-client][*http.async.client/create-client*]] you will need to close it.
+ To do so you call [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/close][*http.async.client/close*]], *http.async.client*
+ relies on client been bound to **client**.
+ #+BEGIN_SRC clojure
+ (let [client (client/create-client)]
+ (try
+ (let [resp (client/GET client url)]
+ ;; process response
+ )
+ (finally
+ (client/close *client*))))
+ #+END_SRC
+* Low level
+ This is lowest level access to *http.async.client*.
+ Mechanics here is based on asynchronous call-backs.
+ It provides default set of callbacks and functions to create and
+ execute requests.
+** Preparing request
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/prepare-request][*http.async.client.request/prepare-request*]] is responsible for
+ request preparation, like name suggests.
+ It takes following arguments:
+ - HTTP Method like *:get* *:head*
+ - *url* that you want to call
+ - and *options*, a keyworded map described already in [[*Request%20options][Request options]].
+ Sample:
+ #+BEGIN_SRC clojure
+ (with-open [client (client/create-client)]
+ (let [req (prepare-request client
+ :get "http://google.com"
+ :headers {:my-header "value"})]
+ ;; now you have request, next thing to do would be to execute it
+ ))
+ #+END_SRC
+** Executing request
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/execute-request][*http.async.client/execute-request*]] returns same map of promises
+ as [[*Asynchronous%20operations][Asynchronous operations]].
+ Its arguments are: request to be executed (result of [[*Preparing%20request][Preparing
+ request]]) and *options* as keyworded map consisting of call-backs.
+ Following *options* are recognized:
+ - *:status* [[*Status%20line][Status line]]
+ - *:headers* [[*Headers][Headers]]
+ - *:part* [[*Body%20part][Body part]]
+ - *:completed* [[*Body%20completed][Body completed]]
+ - *:error* [[*Error][Error]]
+ All callbacks take response map as first argument and callback
+ specific argument if any.
+ Callbacks are expected to return tuple of *result* and *action*:
+ - *result* :: will be delivered to respective promise in response
+ map
+ - *action* :: if its value is *:abort* than response processing
+ will be aborted, anything else here will result in
+ continuation.
+*** Status line
+ Status line callback gets called after status line has been
+ received with arguments:
+ - response map
+ - Status map has following keys:
+ - *:code* status code (200, 404, ..)
+ - *:msg* status message ("OK", ..)
+ - *:protocol* protocol with version ("HTTP/1.1")
+ - *:major* major protocol version (1)
+ - *:minor* minor protocol version (0, 1)
+*** Headers
+ Headers callback gets called after headers have been received
+ with arguments:
+ - response map
+ - lazy map of headers. Keys in that map are *(keyword
+ (.toLowerCase <header name>))*, so "Server" headers is
+ *:server* and so on.
+*** Body part
+ Body part callback gets called after each part of body has been
+ received with arguments:
+ - response map
+ - ByteArrayOutputStream that contains body part received.
+*** Body completed
+ This callback gets called when receiving of response body has
+ finished with only one argument, i.e. response map.
+*** Error
+ Error callback gets called when error while processing has been
+ encountered with arguments
+ - response map
+ - *Throwable* that was a cause of failure
+** Default callbacks
+ [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client.request/*default-callbacks*][*http.async.client.request/*default-callbacks**]] is a map of
+ default callbacks. This fill allow you to easy change only few
+ callbacks and reuse default for the rest.
- Please look at source of [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/stream-seq][*http.async.client/stream-seq*]] to see
- how to do it.
+ Please look at source of [[http://neotyk.github.com/http.async.client/autodoc/http.async.client-api.html#http.async.client/stream-seq][*http.async.client/stream-seq*]] to see
+ how to do it.
View
6 index.org
@@ -1,11 +1,11 @@
#+TITLE: http.async.client - Asynchronous HTTP Client - Clojure
#+AUTHOR: Hubert Iwaniuk
#+EMAIL: neotyk@kungfoo.pl
-#+INFOJS_OPT: view:info toc:1
+#+SETUPFILE: setup.org
*http.async.client* is Asynchronous HTTP Client for Clojure.
-* *tl;dr*
+* tl;dr
Declare dependency:
#+BEGIN_SRC clojure
@@ -29,7 +29,7 @@
(c/string response)))
#+END_SRC
-* Information over *http.async.client*
+* More info
[[http://github.com/neotyk/http.async.client][*http.async.client*]] is based on [[http://github.com/AsyncHttpClient/async-http-client][Asynchronous Http Client for Java]]
which runs on top of [[http://jboss.org/netty][Netty Project]].
View
6 setup.org
@@ -0,0 +1,6 @@
+#+INFOJS_OPT: path:org-info.js
+#+INFOJS_OPT: view:info toc:nil ftoc:t ltoc:above tdepth:2 sdepth:4 mouse:underline buttons:nil
+#+INFOJS_OPT: up:http://neotyk.github.com/http.async.client/
+#+INFOJS_OPT: home:http://neotyk.github.com
+#+STYLE: <link rel="stylesheet" type="text/css" href="stylesheet.css" />
+#+OPTIONS: H:4
View
452 stylesheet.css
@@ -0,0 +1,452 @@
+body
+{
+ margin: 10px 6% 10px 30%;
+ font-family: Verdana, Helvetica, sans-serif;
+ font-size: 11pt;
+ text-align: left;
+ line-height: 1.2em;
+}
+
+h1,h2
+{
+ font-family:Verdana,Arial,sans-serif;
+ font-weight:bold;
+ color:#104d8c;
+ text-align:left;
+}
+
+h3,h4,h5,h6
+{
+ font-family:Verdana,Arial,sans-serif;
+ font-weight:bold;
+ color:#104d8c;
+ text-align:left;
+}
+
+div
+{
+ text-align:left;
+}
+
+a
+{
+ text-decoration:none;
+ cursor:pointer;
+ color:#0000AA;
+ font-style:italic;
+}
+
+a:hover
+{
+ text-decoration:underline;
+ cursor:pointer;
+ color:#0000AA;
+}
+
+a:visited
+{
+ text-decoration:none;
+ cursor:pointer;
+ color:#0000AA;
+}
+
+img, a img
+{
+ text-decoration:none;
+ border-style:none;
+}
+
+
+#title
+{
+ text-align: center;
+ margin-bottom:2em;
+ line-height:1.2em;
+}
+
+#table-of-contents{
+ position: fixed;
+ display: block;
+ left: 1ex;
+ top: 20px;
+ width: 25%;
+ min-height: 60px;
+ max-height: 90%;
+ overflow: auto;
+ font-size: 85%;
+ line-height: 1.4em;
+}
+
+#table-of-contents > h2 {
+ font-size: 1em;
+}
+
+#text-table-of-contents > ul {
+ list-style-type: none;
+ margin-left: 1ex;
+}
+
+#text-table-of-contents > ul ul {
+ list-style-type: none;
+ margin-left: 1ex;
+}
+
+.outline-1{margin-bottom:2.5em;}
+.outline-2{margin-bottom:2em;margin-left:0.5em}
+.outline-3{margin-bottom:1.5em;margin-left:1em}
+.outline-4{margin-bottom:1.5em;margin-left:1.5em}
+
+ul
+{
+ padding-left:0px;
+ margin-left:2em;
+}
+
+li
+{
+ margin-right:5ex;
+ text-align:justify;
+}
+
+dt
+{
+ font-weight:bold;
+}
+
+dd
+{
+ margin-left:3em;
+}
+
+p
+{
+ text-align:justify;
+}
+
+.todo
+{
+ color: red;
+}
+
+.done
+{
+ color: green;
+}
+
+.timestamp
+{
+ color: grey;
+}
+
+.timestamp-kwd
+{
+ color: CadetBlue;
+}
+
+.tag
+{
+ font-size:9pt;
+ font-weight:normal;
+ font-style:italic;
+ color:orange;
+}
+
+table
+{
+ border-collapse: collapse;
+ border-bottom:1px solid black;
+}
+
+th
+{
+ white-space:nowrap;
+}
+
+td, th
+{
+ vertical-align: top;
+}
+
+pre, code.pre
+{
+ /* width:80%; */
+ margin-left:2%;
+ margin-right:2%;
+ margin-top:1em;
+ margin-bottom:1em;
+ padding:0.3em;
+ display:block;
+ background-color:#eeeeee;
+ border:1px solid #cccccc;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+}
+
+code
+{
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+
+li pre, li code.pre
+{
+ /* width:90%; */
+ margin-left:0em;
+ margin-top:1em;
+ margin-bottom:1em;
+ padding:0.3em;
+ display:block;
+ background-color:#eeeeee;
+ border:1px solid #cccccc;
+}
+
+
+p pre
+{
+ margin:0px;
+ padding:0px;
+}
+
+div.backlinks
+{
+ clear:both;
+ text-align:right;
+ margin-top:1em;
+}
+.backlinks a
+{
+ padding-top:0.1em;
+ padding-bottom:0.1em;
+ padding-left:0.3em;
+ padding-right:0.3em;
+ text-align:right;
+ background-color:#DDDDFF;
+ color:#6666CC;
+ font-family:sans-serif;
+ text-decoration:none;
+ cursor:pointer;
+}
+
+div.zitat
+{
+ width:80%;
+ margin-left:3em;
+ margin-top:1em;
+ margin-bottom:1em;
+ padding:1em;
+ background-color:#ffeeee;
+ border:1px solid #cccccc;
+}
+
+div.leftColumn
+{
+ width:48%;
+ float:left;
+}
+
+div.rightColumn
+{
+ width:48%;
+ float:right;
+}
+
+
+li
+{
+}
+
+
+/* footer */
+
+div#postamble
+{
+ clear:both;
+ padding-top:0.6em;
+ padding-bottom:1em;
+ margin-top:3em;
+ border-top:1px solid #333333;
+}
+
+#postamble p
+{
+ width:100%;
+ text-align:center;
+ font-size:0.8em;
+ color:#666666;
+}
+
+#postamble p.date
+{
+ width:40%;
+ padding-left:2ex;
+ float:left;
+ text-align:left;
+ font-size:0.8em;
+ color:#999999;
+}
+#postamble p.author
+{
+ clear:both;
+ width:40%;
+ padding-right:2ex;
+ float:right;
+ font-size:0.8em;
+ color:#999999;
+ text-align:right;
+ white-space:nowrap;
+}
+
+
+/* Styles for htmlize.el */
+
+.comment {
+ /* font-lock-comment-face */
+ color: #b22222;
+ font-style: italic;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.comment-delimiter {
+ /* font-lock-comment-delimiter-face */
+ color: #b22222;
+ font-style: italic;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.constant {
+ /* font-lock-constant-face */
+ color: #ff4500;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.default {
+ /* default */
+ color: #000000;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.function-name {
+ color:#0000ff;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.builtin {
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+ color: #0000ff;
+}
+.html-tag {
+ /* html-tag-face */
+ color: #0000ff;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.keyword {
+ /* font-lock-keyword-face */
+ color: #a52a2a;
+ font-weight: bold;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.string {
+ /* font-lock-string-face */
+ color: #006400;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.type {
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.variable-name {
+ /* font-lock-variable-name-face */
+ color: #4d4d4d;
+ font-weight:bold;
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+}
+.org-meta-line {
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+ color: #990000;
+}
+.css-selector {
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+ color: #0000ff;
+}
+.css-property {
+ font-family:"Bitstream Vera Sans mono",Courier,monospace;
+ font-size:10pt;
+ line-height:1.6em;
+ color: #000000;
+ font-weight:bold;
+}
+/* END htmlize.el */
+
+
+
+
+/* Styles for org-info.js */
+
+.org-info-js_info-navigation
+{
+ border-style:none;
+ font-size: 80%;
+}
+
+#org-info-js_console
+{
+ color:#333333;
+ margin:0px;
+ background-color:#ffffff;
+}
+
+#org-info-js_console-input
+{
+ background-color:#ffffff;
+ border-style:none;
+ color:#333333;
+ padding-left:10px;
+ vertical-align:middle;
+}
+
+#org-info-js_console-label
+{
+ font-size:11px;
+ font-weight:bold;
+ padding-left:10px;
+ font-family:Verdana,Arial,sans-serif;
+ vertical-align:middle;
+}
+
+.org-info-js_console-label-warning
+{
+ color:#cc0000;
+}
+
+#org-info-js_console-container
+{
+ border:1px solid #cccccc;
+}
+
+.org-info-js_search-highlight
+{
+ background-color:#adefef; /* emacs default */
+ color:#000000;
+ font-weight:bold;
+}
View
2  todo.org
@@ -1,7 +1,7 @@
#+TITLE: Asynchronous HTTP Client - Clojure - To Do
#+AUTHOR: Hubert Iwaniuk
#+EMAIL: neotyk@kungfoo.pl
-#+INFOJS_OPT: view:info toc:1
+#+SETUPFILE: setup.org
* Receive [6/6] :code:rel1:
** DONE Status Line :rel1:
Please sign in to comment.
Something went wrong with that request. Please try again.