Skip to content

Instantly share code, notes, and snippets.

@nathell
Created July 17, 2010 21:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathell/479867 to your computer and use it in GitHub Desktop.
Save nathell/479867 to your computer and use it in GitHub Desktop.
(ns http-client
(:import [org.mortbay.jetty.client HttpClient ContentExchange]
[java.io ByteArrayInputStream]))
(defn request
"Takes a request conforming to the Ring specification and sends it to
the server. Returns a Ring response."
[req]
(let [{:keys [scheme server-name server-port uri query-string content-type headers character-encoding request-method body]} req
client (HttpClient.)
url (str (name (or scheme :http)) "://" server-name ":" (or server-port 80) uri (if query-string (str "?" query-string) ""))
content-type-header (cond (and content-type character-encoding)
{"Content-Type" (str content-type "; charset=" character-encoding)},
content-type {"Content-Type" content-type},
true {})
headers (merge headers content-type-header)
response-headers (atom {})
exchange (proxy [ContentExchange] []
(onResponseHeader [name value]
(proxy-super onResponseHeader name value)
(swap! response-headers assoc (str name) (str value))))]
(.start client)
(.setConnectorType client HttpClient/CONNECTOR_SELECT_CHANNEL)
(.setURL exchange url)
(.setMethod exchange (.toUpperCase (name (or request-method :get))))
(doseq [[k v] headers]
(.setRequestHeader exchange k v))
(when body
(.setRequestContentSource exchange body))
(when-not (empty? content-type-header)
(.setRequestContentType exchange (content-type-header "Content-Type")))
(.send client exchange)
(.waitForDone exchange)
{:status (.getResponseStatus exchange)
:headers @response-headers
:body (ByteArrayInputStream. (.getResponseBytes exchange))}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment