Permalink
Please sign in to comment.
Showing
with
88 additions
and 8 deletions.
- +2 −0 project.clj
- +78 −0 src/ring/middleware/multipart.clj
- +8 −8 src/ring/middleware/params.clj
2
project.clj
78
src/ring/middleware/multipart.clj
| @@ -0,0 +1,78 @@ | ||
| +(ns ring.middleware.multipart | ||
| + (:use clojure.contrib.def | ||
| + [ring.middleware.params :only (assoc-param)]) | ||
| + (: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 encoding] | ||
| + (proxy [RequestContext] [] | ||
| + (getContentType [] (:content-type request)) | ||
| + (getContentLength [] (:content-length request)) | ||
| + (getCharacterEncoding [] encoding) | ||
| + (getInputStream [] (:body request)))) | ||
| + | ||
| +(defn- file-map | ||
| + "Create a file map from a DiskFileItem." | ||
| + [#^DiskFileItem item] | ||
| + (with-meta | ||
| + {:filename (.getName item) | ||
| + :size (.getSize item) | ||
| + :content-type (.getContentType item) | ||
| + :tempfile (.getStoreLocation item)} | ||
| + {:disk-file-item item})) | ||
| + | ||
| +(defn parse-multipart-params | ||
| + "Parse a map of multipart parameters from the request." | ||
| + [request encoding] | ||
| + (reduce | ||
| + (fn [param-map, #^DiskFileItem item] | ||
| + (assoc-param param-map | ||
| + (.getFieldName item) | ||
| + (if (.isFormField item) | ||
| + (.getString item) | ||
| + (file-map item)))) | ||
| + {} | ||
| + (.parseRequest | ||
| + file-upload | ||
| + (request-context request encoding)))) | ||
| + | ||
| +(defn wrap-multipart | ||
| + "Middleware to parse multipart parameters from a request. Adds the | ||
| + following keys to the request map: | ||
| + :multipart-params - a map of multipart parameters | ||
| + :params - a merged map of all types of parameter | ||
| + Takes an optional configuration map. Recognized keys are: | ||
| + :encoding - character encoding to use for multipart parsing. If not | ||
| + specified, uses the request character encoding, or \"UTF-8\" | ||
| + if no request character encoding is set." | ||
| + [handler & [opts]] | ||
| + (fn [request] | ||
| + (let [encoding (or (:encoding opts) | ||
| + (:character-encoding request) | ||
| + "UTF-8") | ||
| + params (if (multipart-form? request) | ||
| + (parse-multipart-params request encoding) | ||
| + {}) | ||
| + request (merge-with merge request | ||
| + {:multipart-params params} | ||
| + {:params params})] | ||
| + (handler request)))) |
16
src/ring/middleware/params.clj
0 comments on commit
2f4e5ae