summaryrefslogtreecommitdiff
path: root/compojure-3.2/src/compojure/http/multipart.clj
diff options
context:
space:
mode:
Diffstat (limited to 'compojure-3.2/src/compojure/http/multipart.clj')
-rwxr-xr-xcompojure-3.2/src/compojure/http/multipart.clj80
1 files changed, 80 insertions, 0 deletions
diff --git a/compojure-3.2/src/compojure/http/multipart.clj b/compojure-3.2/src/compojure/http/multipart.clj
new file mode 100755
index 0000000..afd6737
--- /dev/null
+++ b/compojure-3.2/src/compojure/http/multipart.clj
@@ -0,0 +1,80 @@
+;; Copyright (c) James Reeves. All rights reserved.
+;; The use and distribution terms for this software are covered by the Eclipse
+;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which
+;; can be found in the file epl-v10.html at the root of this distribution. By
+;; using this software in any fashion, you are agreeing to be bound by the
+;; terms of this license. You must not remove this notice, or any other, from
+;; this software.
+
+(ns compojure.http.multipart
+ "Add multipart form handling to Compojure. Relies on the Apache Commons
+ FileUpload library."
+ (:use clojure.contrib.def
+ compojure.map-utils)
+ (:import [org.apache.commons.fileupload FileUpload RequestContext]
+ [org.apache.commons.fileupload.disk DiskFileItemFactory DiskFileItem]))
+
+(defn multipart-form?
+ "Does a request have a multipart form?"
+ [request]
+ (if-let [content-type (:content-type request)]
+ (.startsWith content-type "multipart/form-data")))
+
+(defvar- file-upload
+ (FileUpload.
+ (doto (DiskFileItemFactory.)
+ (.setSizeThreshold -1)
+ (.setFileCleaningTracker nil)))
+ "Uploader class to save multipart form values to temporary files.")
+
+(defn- request-context
+ "Create a RequestContext object from a request map."
+ [request]
+ (proxy [RequestContext] []
+ (getContentType [] (:content-type request))
+ (getContentLength [] (:content-length request))
+ (getCharacterEncoding [] (:character-encoding request))
+ (getInputStream [] (:body request))))
+
+(defn- file-map
+ "Create a file map from a DiskFileItem."
+ [#^DiskFileItem item]
+ {:disk-file-item item
+ :filename (.getName item)
+ :size (.getSize item)
+ :content-type (.getContentType item)
+ :tempfile (.getStoreLocation item)})
+
+(defn parse-multipart-params
+ "Parse a map of multipart parameters from the request."
+ [request]
+ (reduce
+ (fn [param-map, #^DiskFileItem item]
+ (assoc-vec param-map
+ (keyword (.getFieldName item))
+ (if (.isFormField item)
+ (if (zero? (.getSize item))
+ ""
+ (.getString item))
+ (file-map item))))
+ {}
+ (.parseRequest
+ file-upload
+ (request-context request))))
+
+(defn get-multipart-params
+ "Retrieve multipart params from the request."
+ [request]
+ (if (multipart-form? request)
+ (parse-multipart-params request)
+ {}))
+
+(defn with-multipart
+ "Decorate a Ring handler with multipart parameters."
+ [handler]
+ (fn [request]
+ (let [params (get-multipart-params request)
+ request (-> request
+ (assoc :multipart-params params)
+ (assoc :params (merge (request :params) params)))]
+ (handler request))))