Skip to content

Commit

Permalink
Add :max-file-size option to multipart middleware
Browse files Browse the repository at this point in the history
  • Loading branch information
weavejester committed Feb 24, 2023
1 parent a1da756 commit 1f5d1a0
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 33 deletions.
2 changes: 1 addition & 1 deletion ring-core/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
:dependencies [[org.clojure/clojure "1.7.0"]
[ring/ring-codec "1.2.0"]
[commons-io "2.11.0"]
[commons-fileupload "1.4"]
[commons-fileupload "1.5"]
[crypto-random "1.2.1"]
[crypto-equality "1.0.1"]]
:aliases {"test-all" ["with-profile" "default:+1.8:+1.9:+1.10" "test"]}
Expand Down
61 changes: 29 additions & 32 deletions ring-core/src/ring/middleware/multipart_params.clj
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,8 @@
(if (.hasNext it)
(cons (.next it) (file-item-iterator-seq it)))))

(defn- file-item-seq
"Create a seq of FileItem instances from a request context."
[request progress-fn context]
(let [upload (if progress-fn
(doto (FileUpload.)
(.setProgressListener (progress-listener request progress-fn)))
(FileUpload.))]
(file-item-iterator-seq
(.getItemIterator ^FileUpload upload context))))
(defn- file-item-seq [^FileUpload upload context]
(file-item-iterator-seq (.getItemIterator upload context)))

(defn- parse-content-type-charset [^FileItemStream item]
(some->> (.getContentType item) parsing/find-content-type-charset))
Expand Down Expand Up @@ -86,14 +79,12 @@
:stream (.openStream item)}))
(.isFormField item)])

(defn- parse-multipart-params
"Parse a map of multipart parameters from the request."
[request fallback-encoding forced-encoding store progress-fn]
(->> (request-context request fallback-encoding)
(file-item-seq request progress-fn)
(map #(parse-file-item % store))
(decode-string-values fallback-encoding forced-encoding)
(reduce (fn [m [k v]] (assoc-conj m k v)) {})))
(defn- make-file-upload [request {:keys [progress-fn max-file-size]}]
(let [upload (FileUpload.)]
(.setFileSizeMax upload (or max-file-size -1))
(when progress-fn
(.setProgressListener upload (progress-listener request progress-fn)))
upload))

(defn- load-var
"Returns the var named by the supplied symbol, or nil if not found. Attempts
Expand All @@ -108,27 +99,30 @@
func (load-var store)]
(func))))

(defn- parse-multipart-params
"Parse a map of multipart parameters from the request."
[request {:keys [encoding fallback-encoding store] :as options}]
(let [store (or store @default-store)
fallback-encoding (or encoding
fallback-encoding
(req/character-encoding request)
"UTF-8")]
(->> (request-context request fallback-encoding)
(file-item-seq (make-file-upload request options))
(map #(parse-file-item % store))
(decode-string-values fallback-encoding encoding)
(reduce (fn [m [k v]] (assoc-conj m k v)) {}))))

(defn multipart-params-request
"Adds :multipart-params and :params keys to request.
See: wrap-multipart-params."
{:added "1.2"}
([request]
(multipart-params-request request {}))
([request options]
(let [store (or (:store options) @default-store)
forced-encoding (:encoding options)
req-encoding (or forced-encoding
(:fallback-encoding options)
(req/character-encoding request)
"UTF-8")
progress (:progress-fn options)
params (if (multipart-form? request)
(parse-multipart-params request
req-encoding
forced-encoding
store
progress)
{})]
(let [params (if (multipart-form? request)
(parse-multipart-params request options)
{})]
(merge-with merge request
{:multipart-params params}
{:params params}))))
Expand Down Expand Up @@ -162,7 +156,10 @@
:progress-fn - a function that gets called during uploads. The
function should expect four parameters: request,
bytes-read, content-length, and item-count."
bytes-read, content-length, and item-count.
:max-file-size - the maximum size allowed size of a file in bytes. If
nil or omitted, there is no limit."
([handler]
(wrap-multipart-params handler {}))
([handler options]
Expand Down
13 changes: 13 additions & 0 deletions ring-core/test/ring/middleware/test/multipart_params.clj
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,16 @@
:body (string-input-stream form-body "ISO-8859-15")}
request* (multipart-params-request request {:fallback-encoding "ISO-8859-15"})]
(is (= (get-in request* [:multipart-params "foo"]) "äÄÖöÅå€"))))

(deftest test-enforced-limits
(let [form-body (str "--XXXX\r\n"
"Content-Disposition: form-data;"
"name=\"upload\"; filename=\"test1.txt\"\r\n"
"Content-Type: text/plain\r\n\r\n"
"foobarbaz\r\n"
"--XXXX--")
request {:headers {"content-type"
(str "multipart/form-data; boundary=XXXX")}
:body (string-input-stream form-body)}]
(is (thrown? org.apache.commons.fileupload.FileUploadBase$FileUploadIOException
(multipart-params-request request {:max-file-size 6})))))

0 comments on commit 1f5d1a0

Please sign in to comment.