|
9 | 9 | ring.middleware.multipart-params.temp-file/temp-file-store"
|
10 | 10 | (:require [ring.util.codec :refer [assoc-conj]]
|
11 | 11 | [ring.util.request :as req]
|
| 12 | + [ring.util.response :as response] |
12 | 13 | [ring.util.parsing :refer [re-charset]])
|
13 | 14 | (:import [org.apache.commons.fileupload UploadContext
|
14 | 15 | FileItemIterator
|
15 | 16 | FileItemStream
|
16 | 17 | FileUpload
|
| 18 | + InvalidFileNameException |
17 | 19 | ProgressListener]
|
18 | 20 | [org.apache.commons.io IOUtils]))
|
19 | 21 | (defn- progress-listener
|
|
135 | 137 | {:multipart-params params}
|
136 | 138 | {:params params}))))
|
137 | 139 |
|
| 140 | +(defn default-invalid-filename-handler |
| 141 | + ([request] |
| 142 | + (response/bad-request |
| 143 | + (str "Invalid filename in multipart upload: " |
| 144 | + (::invalid-filename request)))) |
| 145 | + ([request respond raise] |
| 146 | + (respond (default-invalid-filename-handler request)))) |
| 147 | + |
| 148 | +(defn- add-invalid-filename-to-req |
| 149 | + [request ^InvalidFileNameException invalid-filename-exception] |
| 150 | + (assoc request ::invalid-filename (.getName invalid-filename-exception))) |
| 151 | + |
138 | 152 | (defn wrap-multipart-params
|
139 |
| - "Middleware to parse multipart parameters from a request. Adds the |
140 |
| - following keys to the request map: |
| 153 | + "Middleware to parse multipart parameters from a request. Adds the following |
| 154 | + keys to the request map: |
141 | 155 |
|
142 | 156 | :multipart-params - a map of multipart parameters
|
143 | 157 | :params - a merged map of all types of parameter
|
144 | 158 |
|
145 |
| - The following options are accepted |
146 |
| -
|
147 |
| - :encoding - character encoding to use for multipart parsing. |
148 |
| - Overrides the encoding specified in the request. If not |
149 |
| - specified, uses the encoding specified in a part named |
150 |
| - \"_charset_\", or the content type for each part, or |
151 |
| - request character encoding if the part has no encoding, |
152 |
| - or \"UTF-8\" if no request character encoding is set. |
153 |
| -
|
154 |
| - :fallback-encoding - specifies the character encoding used in parsing if a |
155 |
| - part of the request does not specify encoding in its |
156 |
| - content type or no part named \"_charset_\" is present. |
157 |
| - Has no effect if :encoding is also set. |
158 |
| -
|
159 |
| - :store - a function that stores a file upload. The function |
160 |
| - should expect a map with :filename, :content-type and |
161 |
| - :stream keys, and its return value will be used as the |
162 |
| - value for the parameter in the multipart parameter map. |
163 |
| - The default storage function is the temp-file-store. |
164 |
| -
|
165 |
| - :progress-fn - a function that gets called during uploads. The |
166 |
| - function should expect four parameters: request, |
167 |
| - bytes-read, content-length, and item-count." |
| 159 | + The following options are accepted: |
| 160 | +
|
| 161 | + :encoding |
| 162 | + - Character encoding to use for multipart parsing. Overrides the encoding |
| 163 | + specified in the request. If not specified,uses the encoding specified in a |
| 164 | + part named \"_charset_\", or the content type for each part, or request |
| 165 | + character encoding if the part has no encoding, or \"UTF-8\" if no request |
| 166 | + character encoding is set. |
| 167 | +
|
| 168 | + :fallback-encoding |
| 169 | + - Specifies the character encoding used in parsing if a part of the request |
| 170 | + does not specify encoding in its content type or no part named \"_charset_\" |
| 171 | + is present. Has no effect if :encoding is also set. |
| 172 | +
|
| 173 | + :store |
| 174 | + - A function that stores a file upload. The function should expect a map with |
| 175 | + :filename, :content-type and :stream keys, and its return value will be used |
| 176 | + as the value for the parameter in the multipart parameter map. The default |
| 177 | + storage function is the temp-file-store. |
| 178 | +
|
| 179 | + :progress-fn |
| 180 | + - A function that gets called during uploads. The function should expect four |
| 181 | + parameters: request, bytes-read, content-length, and item-count. |
| 182 | +
|
| 183 | + :invalid-filename-handler |
| 184 | + - A handler that gets called when the file being uploaded has an invalid name. |
| 185 | + When this handler receives the request it can expect one additional key, |
| 186 | + ::invalid-filename, which contains the name of the invalid file." |
168 | 187 | ([handler]
|
169 | 188 | (wrap-multipart-params handler {}))
|
170 | 189 | ([handler options]
|
171 |
| - (fn |
172 |
| - ([request] |
173 |
| - (handler (multipart-params-request request options))) |
174 |
| - ([request respond raise] |
175 |
| - (handler (multipart-params-request request options) respond raise))))) |
| 190 | + (let [invalid-filename-handler |
| 191 | + (:invalid-filename-handler options default-invalid-filename-handler)] |
| 192 | + (fn ([request] |
| 193 | + (let [req-or-ex (try |
| 194 | + (multipart-params-request request options) |
| 195 | + (catch InvalidFileNameException ex ex))] |
| 196 | + (if (instance? InvalidFileNameException req-or-ex) |
| 197 | + (-> request |
| 198 | + (add-invalid-filename-to-req req-or-ex) |
| 199 | + invalid-filename-handler) |
| 200 | + (handler req-or-ex)))) |
| 201 | + ([request respond raise] |
| 202 | + (let [req-or-ex (try |
| 203 | + (multipart-params-request request options) |
| 204 | + (catch InvalidFileNameException ex ex))] |
| 205 | + (if (instance? InvalidFileNameException req-or-ex) |
| 206 | + (-> request |
| 207 | + (add-invalid-filename-to-req req-or-ex) |
| 208 | + (invalid-filename-handler respond raise)) |
| 209 | + (handler req-or-ex respond raise)))))))) |
0 commit comments