Skip to content

Commit 76d6749

Browse files
committed
Add error handler to wrap-multipart-params
Instead of throwing an exception when upload limits are exceeded, use a customizable error handler (defaulting to a minimal 413 response).
1 parent 622c245 commit 76d6749

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

ring-core/src/ring/middleware/multipart_params.clj

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
[ring.util.parsing :as parsing])
1414
(:import [org.apache.commons.fileupload
1515
UploadContext
16-
FileItemIterator
1716
FileItemStream
1817
FileUpload
18+
FileUploadBase$FileUploadIOException
1919
ProgressListener]
2020
[org.apache.commons.io IOUtils]))
2121

@@ -119,6 +119,25 @@
119119
{:multipart-params params}
120120
{:params params}))))
121121

122+
(defn content-too-large-handler
123+
"A handler function that responds with a minimal 413 Content Too Large
124+
response."
125+
([_]
126+
{:status 413
127+
:headers {"Content-Type" "text/plain; charset=UTF-8"}
128+
:body "Uploaded content exceeded limits."})
129+
([request respond _]
130+
(respond (content-too-large-handler request))))
131+
132+
(defn- handle-request-and-errors [requestf handlef errorf]
133+
((try
134+
(let [request (requestf)]
135+
#(handlef request))
136+
(catch FileUploadBase$FileUploadIOException _
137+
errorf)
138+
(catch clojure.lang.ExceptionInfo _
139+
errorf))))
140+
122141
(defn wrap-multipart-params
123142
"Middleware to parse multipart parameters from a request. Adds the
124143
following keys to the request map:
@@ -154,12 +173,23 @@
154173
nil or omitted, there is no limit.
155174
156175
:max-file-count - the maximum number of files allowed in a single request.
157-
If nil or omitted, there is no limit."
176+
If nil or omitted, there is no limit.
177+
178+
:error-handler - a handler that is invoked when the :max-file-size or
179+
:max-file-count limits are exceeded. Defaults to
180+
using the content-too-large-handler function."
158181
([handler]
159182
(wrap-multipart-params handler {}))
160183
([handler options]
161-
(fn
162-
([request]
163-
(handler (multipart-params-request request options)))
164-
([request respond raise]
165-
(handler (multipart-params-request request options) respond raise)))))
184+
(let [error-handler (:error-handler options content-too-large-handler)]
185+
(fn
186+
([request]
187+
(handle-request-and-errors
188+
#(multipart-params-request request options)
189+
handler
190+
#(error-handler request)))
191+
([request respond raise]
192+
(handle-request-and-errors
193+
#(multipart-params-request request options)
194+
#(handler % respond raise)
195+
#(error-handler request respond raise)))))))

ring-core/test/ring/middleware/test/multipart_params.clj

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,25 @@
188188
"Content-Type: text/plain\r\n\r\n"
189189
"foobar\r\n"
190190
"--XXXX--")
191-
headers {"content-type" (str "multipart/form-data; boundary=XXXX")}]
191+
headers {"content-type" (str "multipart/form-data; boundary=XXXX")}
192+
handler (constantly {:status 200, :headers {}, :body "OK"})]
192193
(is (thrown? org.apache.commons.fileupload.FileUploadBase$FileUploadIOException
193194
(multipart-params-request
194195
{:headers headers, :body (string-input-stream form-body)}
195196
{:max-file-size 6})))
196197
(is (thrown? clojure.lang.ExceptionInfo
197198
(multipart-params-request
198199
{:headers headers, :body (string-input-stream form-body)}
199-
{:max-file-count 1})))))
200+
{:max-file-count 1})))
201+
(let [response ((wrap-multipart-params handler {:max-file-size 6})
202+
{:headers headers, :body (string-input-stream form-body)})]
203+
(is (= 413 (:status response))))
204+
(let [response ((wrap-multipart-params handler {:max-file-size 9})
205+
{:headers headers, :body (string-input-stream form-body)})]
206+
(is (= 200 (:status response))))
207+
(let [response ((wrap-multipart-params handler {:max-file-count 1})
208+
{:headers headers, :body (string-input-stream form-body)})]
209+
(is (= 413 (:status response))))
210+
(let [response ((wrap-multipart-params handler {:max-file-count 2})
211+
{:headers headers, :body (string-input-stream form-body)})]
212+
(is (= 200 (:status response))))))

0 commit comments

Comments
 (0)