Permalink
Browse files

Clean up some handler code and docs.

  • Loading branch information...
1 parent f3bead5 commit 35d6c1d171d11eca0a8ee1e6248034d83b849960 @mmcgrana committed Mar 7, 2010
Showing with 67 additions and 49 deletions.
  1. +57 −38 ring-httpcore-adapter/src/ring/adapter/httpcore.clj
  2. +10 −11 ring-jetty-adapter/src/ring/adapter/jetty.clj
View
95 ring-httpcore-adapter/src/ring/adapter/httpcore.clj
@@ -1,20 +1,29 @@
(ns ring.adapter.httpcore
- (:import (org.apache.http HttpRequest Header HttpEntityEnclosingRequest HttpResponse
+ (:import (org.apache.http
+ HttpRequest Header HttpEntityEnclosingRequest HttpResponse
ConnectionClosedException HttpException HttpServerConnection)
- (org.apache.http.entity AbstractHttpEntity StringEntity EntityTemplate InputStreamEntity
+ (org.apache.http.entity
+ AbstractHttpEntity StringEntity EntityTemplate InputStreamEntity
FileEntity ContentProducer)
- (org.apache.http.message BasicHeader BasicHeaderElement)
- (org.apache.http.params BasicHttpParams CoreConnectionPNames CoreProtocolPNames)
- (org.apache.http.protocol HttpRequestHandler BasicHttpContext HttpService BasicHttpProcessor
- ResponseDate ResponseServer ResponseContent ResponseConnControl HttpRequestHandlerRegistry
- HttpContext)
- (org.apache.http.impl DefaultConnectionReuseStrategy DefaultHttpResponseFactory
+ (org.apache.http.message
+ BasicHeader BasicHeaderElement)
+ (org.apache.http.params
+ BasicHttpParams CoreConnectionPNames CoreProtocolPNames)
+ (org.apache.http.protocol
+ HttpRequestHandler BasicHttpContext HttpService BasicHttpProcessor
+ ResponseDate ResponseServer ResponseContent ResponseConnControl
+ HttpRequestHandlerRegistry HttpContext)
+ (org.apache.http.impl
+ DefaultConnectionReuseStrategy DefaultHttpResponseFactory
DefaultHttpServerConnection)
- (java.io File FileInputStream InputStream OutputStream OutputStreamWriter IOException
- InterruptedIOException)
- (java.net URI ServerSocket)
- (java.util.concurrent Executors Executor ThreadFactory))
- (:use (clojure.contrib except)))
+ (java.io
+ File FileInputStream InputStream OutputStream OutputStreamWriter
+ IOException InterruptedIOException)
+ (java.net URI
+ ServerSocket)
+ (java.util.concurrent
+ Executors Executor ThreadFactory))
+ (:use [clojure.contrib.except :only (throwf)]))
(defmacro #^{:private true} -?>
([form] form)
@@ -25,14 +34,15 @@
`(when (instance? ~type ~x) (-> ~(vary-meta x assoc :tag type) ~@forms)))
(defn- charset [#^BasicHeader content-type-header]
- (-?> content-type-header .getElements #^BasicHeaderElement first (.getParameterByName "charset") .getValue))
+ (-?> content-type-header .getElements
+ #^BasicHeaderElement first (.getParameterByName "charset") .getValue))
(defn- lower-case [#^String s]
(.toLowerCase s java.util.Locale/ENGLISH))
(defn- build-req-map
"Augments the given request-prototype (a map) to represent the given HTTP
- request, to be passed as the Ring request to an app."
+ request, to be passed as the Ring request to a handler."
[#^HttpRequest request request-prototype]
(let [request-line (.getRequestLine request)
headers (reduce
@@ -42,7 +52,8 @@
(.getValue header)))
{} (seq (.getAllHeaders request)))
host (or (headers "host")
- (str (request-prototype :server-name) ":" (request-prototype :server-port 80)))
+ (str (request-prototype :server-name) ":"
+ (request-prototype :server-port 80)))
uri (URI. (str "http://" host (.getUri request-line)))]
(into (or request-prototype {})
{:server-port (.getPort uri)
@@ -54,8 +65,10 @@
:content-type (headers "content-type")
:content-length (when-let [len (instance?-> HttpEntityEnclosingRequest request .getEntity .getContentLength)]
(when (>= len 0) len))
- :character-encoding (instance?-> HttpEntityEnclosingRequest request .getEntity .getContentEncoding charset)
- :body (instance?-> HttpEntityEnclosingRequest request .getEntity .getContent)})))
+ :character-encoding (instance?-> HttpEntityEnclosingRequest
+ request .getEntity .getContentEncoding charset)
+ :body (instance?-> HttpEntityEnclosingRequest
+ request .getEntity .getContent)})))
(defn- apply-resp-map
"Apply the given response map to the servlet response, therby completing
@@ -72,7 +85,8 @@
; Apply the body - the method depends on the given body type.
(when body
(let [content-type (headers "Content-Type")
- charset (when content-type (charset (BasicHeader. "Content-Type" content-type)))
+ charset (when content-type
+ (charset (BasicHeader. "Content-Type" content-type)))
content-length (headers "Content-Length")
entity
(cond
@@ -82,12 +96,16 @@
(EntityTemplate.
(proxy [ContentProducer] []
(writeTo [#^OutputStream s]
- (let [w (if charset (OutputStreamWriter. s #^String charset) (OutputStreamWriter. s))]
+ (let [w (if charset
+ (OutputStreamWriter. s #^String charset)
+ (OutputStreamWriter. s))]
(doseq [#^String chunk body]
(.write w chunk))
(.flush w)))))
(instance? InputStream body)
- (InputStreamEntity. body (let [l (or content-length -1)] (if (>= Long/MAX_VALUE l) l -1)))
+ (InputStreamEntity. body
+ (let [l (or content-length -1)]
+ (if (>= Long/MAX_VALUE l) l -1)))
(instance? File body)
(FileEntity. body content-type)
:else
@@ -97,18 +115,16 @@
(.setEntity response entity))))
(defn- ring-handler
- "Returns an Handler implementation for the given app.
+ "Returns an Handler implementation for the given Ring handler.
The HttpContext must contains a map associated to \"ring.request-prototype\"."
- [app]
+ [handler]
(proxy [HttpRequestHandler] []
(handle [request response #^HttpContext context]
- (let [req (build-req-map request (.getAttribute context "ring.request-prototype"))
- resp (app req)]
+ (let [req (build-req-map request
+ (.getAttribute context "ring.request-prototype"))
+ resp (handler req)]
(apply-resp-map response resp)))))
-
-;; Simple HTTP Server
-
(defn- handle-request
"Handle the request, usually called from a worker thread."
[#^HttpService httpservice #^HttpServerConnection conn request-prototype]
@@ -125,16 +141,17 @@
(.shutdown conn)
(catch IOException _ nil))))))
-(defn- create-http-service [app]
+(defn- create-http-service [handler]
(let [params (doto (BasicHttpParams.)
- (.setParameter CoreProtocolPNames/ORIGIN_SERVER "HttpComponents/1.1"))
+ (.setParameter CoreProtocolPNames/ORIGIN_SERVER
+ "HttpComponents/1.1"))
httpproc (doto (BasicHttpProcessor.)
(.addInterceptor (ResponseDate.))
(.addInterceptor (ResponseServer.))
(.addInterceptor (ResponseContent.))
(.addInterceptor (ResponseConnControl.)))
registry (doto (HttpRequestHandlerRegistry.)
- (.register "*" (ring-handler app)))]
+ (.register "*" (ring-handler handler)))]
(doto (HttpService. httpproc
(DefaultConnectionReuseStrategy.)
(DefaultHttpResponseFactory.))
@@ -147,13 +164,15 @@
(.execute executor #(apply f args)))
(defn run-httpcore
- "Serve the given app according to the options.
+ "Serve the given handler according to the options.
Options:
- :port (Optional, Integer)
- :server-name (Optional, String) for old HTTP/1.0 clients
- :server-port (Optional, Integer) for old HTTP/1.0 clients, when public facing port is different from :port
- :execute, (Optional, IFn) function with signature [f & args] that applies f to args, usually in another thread"
- [app {:keys [port server-name server-port execute]}]
+ :port
+ :server-name - For old HTTP/1.0 clients
+ :server-port - For old HTTP/1.0 clients, when public facing port is different
+ from :port
+ :execute - Function with signature [f & args] that applies f to args,
+ usually in another thread"
+ [handler {:keys [port server-name server-port execute]}]
(let [execute (or execute (partial executor-execute
(Executors/newCachedThreadPool
(proxy [ThreadFactory] []
@@ -165,7 +184,7 @@
(.setIntParameter CoreConnectionPNames/SOCKET_BUFFER_SIZE (* 8 1024))
(.setBooleanParameter CoreConnectionPNames/STALE_CONNECTION_CHECK false)
(.setBooleanParameter CoreConnectionPNames/TCP_NODELAY true))
- httpservice (create-http-service app)
+ httpservice (create-http-service handler)
request-prototype {:scheme :http :server-port (or server-port port) :server-name server-name}]
(with-open [serversocket (ServerSocket. port)]
(while (not (.isInterrupted (Thread/currentThread)))
View
21 ring-jetty-adapter/src/ring/adapter/jetty.clj
@@ -48,24 +48,23 @@
(defn #^Server run-jetty
"Serve the given handler according to the options.
Options:
- :configurator (Optional, function; called with the Server instance.)
- :port (Optional, Integer)
- :host (Optional, String)
- :join? (Optional, true by default. If false, don't block.)
- :ssl-port, :keystore, :key-password, :truststore, :trust-password"
+ :configurator - A function called with the Server instance.
+ :port
+ :host
+ :join? - Block the caller: defaults to true.
+ :ssl - Use SSL.
+ :ssl-port - SSL port: defaults to 443, implies :ssl?
+ :keystore
+ :key-password
+ :truststore
+ :trust-password"
[handler options]
(let [#^Server s (create-server (dissoc options :configurator))]
(when-let [configurator (:configurator options)]
- ;; Optional additional configuration, such as
- ;; adding JMX.
(configurator s))
-
(doto s
(.setHandler (proxy-handler handler))
(.start))
-
(when (:join options true)
(.join s))
-
- ;; Finally, return the Server.
s))

0 comments on commit 35d6c1d

Please sign in to comment.