Skip to content

Commit 6bd4a32

Browse files
committed
Revert "Rewritten multipart library to use ServletFileUpload courtesy of Adam"
This reverts commit dd36e21.
1 parent 1361dc3 commit 6bd4a32

1 file changed

Lines changed: 58 additions & 18 deletions

File tree

src/compojure/http/multipart.clj

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,78 @@
55
;; using this software in any fashion, you are agreeing to be bound by the
66
;; terms of this license. You must not remove this notice, or any other, from
77
;; this software.
8-
;; Modified by Adam Blinkinsop <blinks@acm.org> in August 2009.
98

109
(ns compojure.http.multipart
1110
"Add multipart form handling to Compojure. Relies on the Apache Commons
1211
FileUpload library."
1312
(:use clojure.contrib.def)
1413
(:use compojure.map-utils)
15-
(:import [org.apache.commons.fileupload.servlet ServletFileUpload]))
14+
(:import org.apache.commons.fileupload.FileUpload)
15+
(:import org.apache.commons.fileupload.RequestContext)
16+
(:import org.apache.commons.fileupload.disk.DiskFileItemFactory)
17+
(:import org.apache.commons.fileupload.disk.DiskFileItem))
1618

17-
(defn multipart?
18-
"Does this request contain multipart content?"
19+
(defn multipart-form?
20+
"Does a request have a multipart form?"
1921
[request]
20-
(ServletFileUpload/isMultipartContent request))
22+
(if-let [content-type (:content-type request)]
23+
(.startsWith content-type "multipart/form-data")))
2124

22-
(defvar- upload (ServletFileUpload.))
25+
(defvar- file-upload
26+
(FileUpload.
27+
(doto (DiskFileItemFactory.)
28+
(.setSizeThreshold -1)
29+
(.setFileCleaningTracker nil)))
30+
"Uploader class to save multipart form values to temporary files.")
2331

24-
(defn field-seq
25-
"Map field names to values, which will either be a simple string or map.
32+
(defn- request-context
33+
"Create a RequestContext object from a request map."
34+
[request]
35+
(proxy [RequestContext] []
36+
(getContentType [] (:content-type request))
37+
(getContentLength [] (:content-length request))
38+
(getCharacterEncoding [] (:character-encoding request))
39+
(getInputStream [] (:body request))))
40+
41+
(defn- file-map
42+
"Create a file map from a DiskFileItem."
43+
[#^DiskFileItem item]
44+
{:disk-file-item item
45+
:filename (.getName item)
46+
:size (.getSize item)
47+
:content-type (.getContentType item)
48+
:tempfile (.getStoreLocation item)})
49+
50+
(defn parse-multipart-params
51+
"Parse a map of multipart parameters from the request."
52+
[request]
53+
(reduce
54+
(fn [param-map, #^DiskFileItem item]
55+
(assoc-vec param-map
56+
(keyword (.getFieldName item))
57+
(if (.isFormField item)
58+
(if (zero? (.getSize item))
59+
""
60+
(.getString item))
61+
(file-map item))))
62+
{}
63+
(.parseRequest
64+
file-upload
65+
(request-context request))))
2666

27-
Multipart values will be maps with content-type, name (original filename),
28-
and stream (an open input stream object)."
67+
(defn get-multipart-params
68+
"Retrieve multipart params from the request."
2969
[request]
30-
(map (fn [i] {(keyword (.getFieldName i))
31-
(if (.isFormField i)
32-
(.getParameter request (.getFieldName i))
33-
{:content-type (.getContentType i)
34-
:name (.getName i)
35-
:stream (.openStream i)})})
36-
(.getItemIterator upload request)))
70+
(if (multipart-form? request)
71+
(parse-multipart-params request)
72+
{}))
3773

3874
(defn with-multipart
75+
"Decorate a Ring handler with multipart parameters."
3976
[handler]
4077
(fn [request]
41-
(let [req (merge request {:params (merge (field-seq request))})]
78+
(let [params (get-multipart-params request)
79+
request (-> request
80+
(assoc :multipart-params params)
81+
(assoc :params (merge (request :params) params)))]
4282
(handler request))))

0 commit comments

Comments
 (0)