|
| 1 | +# nginx-upload-module |
| 2 | + |
| 3 | +A module for [nginx](https://www.nginx.com/) for handling file uploads using |
| 4 | +multipart/form-data encoding ([RFC 1867](http://www.ietf.org/rfc/rfc1867.txt)) |
| 5 | +and resumable uploads according to [this](#upload-protocol) protocol |
| 6 | + |
| 7 | +## Description |
| 8 | + |
| 9 | +The module parses request body storing all files being uploaded to a |
| 10 | +directory specified by [`upload_store`](#upload_store) directive. The |
| 11 | +files are then being stripped from body and altered request is then |
| 12 | +passed to a location specified by [`upload_pass`](#upload_pass) |
| 13 | +directive, thus allowing arbitrary handling of uploaded files. Each of |
| 14 | +file fields are being replaced by a set of fields specified by |
| 15 | +[`upload_set_form_field`](#upload_set_form_field) directive. The |
| 16 | +content of each uploaded file then could be read from a file specified |
| 17 | +by $upload_tmp_path variable or the file could be simply moved to |
| 18 | +ultimate destination. Removal of output files is controlled by directive |
| 19 | +[`upload_cleanup`](#upload_cleanup). If a request has a method other than |
| 20 | +POST, the module returns error 405 (Method not allowed). Requests with |
| 21 | +such methods could be processed in alternative location via |
| 22 | +[`error_page`](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page) |
| 23 | +directive. |
| 24 | + |
| 25 | +## Directives |
| 26 | + |
| 27 | +### upload_pass |
| 28 | + |
| 29 | +**Syntax:** <code><b>upload_pass</b> <i>location</i></code><br> |
| 30 | +**Default:** —<br> |
| 31 | +**Context:** `server,location` |
| 32 | + |
| 33 | +Specifies location to pass request body to. File fields will be stripped |
| 34 | +and replaced by fields, containing necessary information to handle |
| 35 | +uploaded files. |
| 36 | + |
| 37 | +### upload_resumable |
| 38 | + |
| 39 | +**Syntax:** <code><b>upload_resumable</b> on | off</code><br> |
| 40 | +**Default:** `upload_resumable off`<br> |
| 41 | +**Context:** `main,server,location` |
| 42 | + |
| 43 | +Enables resumable uploads. |
| 44 | + |
| 45 | +### upload_store |
| 46 | + |
| 47 | +**Syntax:** <code><b>upload_store</b> <i>directory</i> [<i>level1</i> [<i>level2</i>]] ...</code><br> |
| 48 | +**Default:** —<br> |
| 49 | +**Context:** `server,location` |
| 50 | + |
| 51 | +Specifies a directory to which output files will be saved to. The |
| 52 | +directory could be hashed. In this case all subdirectories should exist |
| 53 | +before starting nginx. |
| 54 | + |
| 55 | +### upload_state_store |
| 56 | + |
| 57 | +**Syntax:** <code><b>upload_state_store</b> <i>directory</i> [<i>level1</i> [<i>level2</i>]] ...</code><br> |
| 58 | +**Default:** —<br> |
| 59 | +**Context:** `server,location` |
| 60 | + |
| 61 | +Specifies a directory that will contain state files for resumable |
| 62 | +uploads. The directory could be hashed. In this case all subdirectories |
| 63 | +should exist before starting nginx. |
| 64 | + |
| 65 | +### upload_store_access |
| 66 | + |
| 67 | +**Syntax:** <code><b>upload_store_access</b> <i>mode</i></code><br> |
| 68 | +**Default:** `upload_store_access user:rw`<br> |
| 69 | +**Context:** `server,location` |
| 70 | + |
| 71 | +Specifies access mode which will be used to create output files. |
| 72 | + |
| 73 | +### upload_set_form_field |
| 74 | + |
| 75 | +**Syntax:** <code><b>upload_set_form_field</b> <i>name</i> <i>value</i></code><br> |
| 76 | +**Default:** —<br> |
| 77 | +**Context:** `server,location` |
| 78 | + |
| 79 | +Specifies a form field(s) to generate for each uploaded file in request |
| 80 | +body passed to backend. Both `name` and `value` could contain following |
| 81 | +special variables: |
| 82 | + |
| 83 | + - `$upload_field_name`: the name of original file field |
| 84 | + - `$upload_content_type`: the content type of file uploaded |
| 85 | + - `$upload_file_name`: the original name of the file being uploaded |
| 86 | + with leading path elements in DOS and UNIX notation stripped. I.e. |
| 87 | + "D:\\Documents And Settings\\My Dcouments\\My Pictures\\Picture.jpg" |
| 88 | + will be converted to "Picture.jpg" and "/etc/passwd" will be |
| 89 | + converted to "passwd". |
| 90 | + - `$upload_tmp_path`: the path where the content of original file is |
| 91 | + being stored to. The output file name consists 10 digits and |
| 92 | + generated with the same algorithm as in `proxy_temp_path` |
| 93 | + directive. |
| 94 | + |
| 95 | +These variables are valid only during processing of one part of original |
| 96 | +request body. |
| 97 | + |
| 98 | +Usage example: |
| 99 | + |
| 100 | +```nginx |
| 101 | +upload_set_form_field $upload_field_name.name "$upload_file_name"; |
| 102 | +upload_set_form_field $upload_field_name.content_type "$upload_content_type"; |
| 103 | +upload_set_form_field $upload_field_name.path "$upload_tmp_path"; |
| 104 | +``` |
| 105 | + |
| 106 | +### upload_aggregate_form_field |
| 107 | + |
| 108 | +**Syntax:** <code><b>upload_aggregate_form_field</b> <i>name</i> <i>value</i></code><br> |
| 109 | +**Default:** —<br> |
| 110 | +**Context:** `server,location` |
| 111 | + |
| 112 | +Specifies a form field(s) containing aggregate attributes to generate |
| 113 | +for each uploaded file in request body passed to backend. Both name and |
| 114 | +value could contain standard nginx variables, variables from |
| 115 | +[upload_set_form_field](#upload_set_form_field) directive and |
| 116 | +following additional special variables: |
| 117 | + |
| 118 | + - `$upload_file_md5`: MD5 checksum of the file |
| 119 | + - `$upload_file_md5_uc`: MD5 checksum of the file in uppercase letters |
| 120 | + - `$upload_file_sha1`: SHA1 checksum of the file |
| 121 | + - `$upload_file_sha1_uc`: SHA1 checksum of the file in uppercase letters |
| 122 | + - `$upload_file_crc32`: hexdecimal value of CRC32 of the file |
| 123 | + - `$upload_file_size`: size of the file in bytes |
| 124 | + - `$upload_file_number`: ordinal number of file in request body |
| 125 | + |
| 126 | +The value of a field specified by this directive is evaluated after |
| 127 | +successful upload of the file, thus these variables are valid only at |
| 128 | +the end of processing of one part of original request body. |
| 129 | + |
| 130 | +**Warning:**: variables `$upload_file_md5`, `$upload_file_md5_uc`, |
| 131 | +`$upload_file_sha1`, and `$upload_file_sha1_uc` use additional |
| 132 | +resources to calculate MD5 and SHA1 checksums. |
| 133 | + |
| 134 | +Usage example: |
| 135 | + |
| 136 | +```nginx |
| 137 | +upload_aggregate_form_field $upload_field_name.md5 "$upload_file_md5"; |
| 138 | +upload_aggregate_form_field $upload_field_name.size "$upload_file_size"; |
| 139 | +
|
| 140 | +``` |
| 141 | + |
| 142 | +### upload_pass_form_field |
| 143 | + |
| 144 | +**Syntax:** <code><b>upload_pass_form_field</b> <i>regex</i></code><br> |
| 145 | +**Default:** —<br> |
| 146 | +**Context:** `server,location` |
| 147 | + |
| 148 | +Specifies a regex pattern for names of fields which will be passed to |
| 149 | +backend from original request body. This directive could be specified |
| 150 | +multiple times per location. Field will be passed to backend as soon as |
| 151 | +first pattern matches. For PCRE-unaware enviroments this directive |
| 152 | +specifies exact name of a field to pass to backend. If directive is |
| 153 | +omitted, no fields will be passed to backend from client. |
| 154 | + |
| 155 | +Usage example: |
| 156 | + |
| 157 | +```nginx |
| 158 | +upload_pass_form_field "^submit$|^description$"; |
| 159 | +``` |
| 160 | + |
| 161 | +For PCRE-unaware environments: |
| 162 | + |
| 163 | +```nginx |
| 164 | +upload_pass_form_field "submit"; |
| 165 | +upload_pass_form_field "description"; |
| 166 | +
|
| 167 | +``` |
| 168 | + |
| 169 | +### upload_cleanup |
| 170 | + |
| 171 | +**Syntax:** <code><b>upload_cleanup</b> <i>status/range</i> ...</code><br> |
| 172 | +**Default:** —<br> |
| 173 | +**Context:** `server,location` |
| 174 | + |
| 175 | +Specifies HTTP statuses after generation of which all file successfuly |
| 176 | +uploaded in current request will be removed. Used for cleanup after |
| 177 | +backend or server failure. Backend may also explicitly signal errornous |
| 178 | +status if it doesn't need uploaded files for some reason. HTTP status |
| 179 | +must be a numerical value in range 400-599, no leading zeroes are |
| 180 | +allowed. Ranges of statuses could be specified with a dash. |
| 181 | + |
| 182 | +Usage example: |
| 183 | + |
| 184 | +```nginx |
| 185 | +upload_cleanup 400 404 499 500-505; |
| 186 | +``` |
| 187 | + |
| 188 | +### upload_buffer_size |
| 189 | + |
| 190 | +**Syntax:** <code><b>upload_buffer_size</b> <i>size</i></code><br> |
| 191 | +**Default:** size of memory page in bytes<br> |
| 192 | +**Context:** `server,location` |
| 193 | + |
| 194 | +Size in bytes of write buffer which will be used to accumulate file data |
| 195 | +and write it to disk. This directive is intended to be used to |
| 196 | +compromise memory usage vs. syscall rate. |
| 197 | + |
| 198 | +### upload_max_part_header_len |
| 199 | + |
| 200 | +**Syntax:** <code><b>upload_max_part_header_len</b> <i>size</i></code><br> |
| 201 | +**Default:** `512`<br> |
| 202 | +**Context:** `server,location` |
| 203 | + |
| 204 | +Specifies maximal length of part header in bytes. Determines the size of |
| 205 | +the buffer which will be used to accumulate part headers. |
| 206 | + |
| 207 | +### upload_max_file_size |
| 208 | + |
| 209 | +**Syntax:** <code><b>upload_max_file_size</b> <i>size</i></code><br> |
| 210 | +**Default:** `0`<br> |
| 211 | +**Context:** `main,server,location` |
| 212 | + |
| 213 | +Specifies maximal size of the file. Files longer than the value of this |
| 214 | +directive will be omitted. This directive specifies "soft" limit, in the |
| 215 | +sense, that after encountering file longer than specified limit, nginx |
| 216 | +will continue to process request body, trying to receive remaining |
| 217 | +files. For "hard" limit `client_max_body_size` directive must be |
| 218 | +used. The value of zero for this directive specifies that no |
| 219 | +restrictions on file size should be applied. |
| 220 | + |
| 221 | +### upload_limit_rate |
| 222 | + |
| 223 | +**Syntax:** <code><b>upload_limit_rate</b> <i>rate</i></code><br> |
| 224 | +**Default:** `0`<br> |
| 225 | +**Context:** `main,server,location` |
| 226 | + |
| 227 | +Specifies upload rate limit in bytes per second. Zero means rate is |
| 228 | +unlimited. |
| 229 | + |
| 230 | +### upload_max_output_body_len |
| 231 | + |
| 232 | +**Syntax:** <code><b>upload_max_output_body_len</b> <i>size</i></code><br> |
| 233 | +**Default:** `100k`<br> |
| 234 | +**Context:** `main,server,location` |
| 235 | + |
| 236 | +Specifies maximal length of the output body. This prevents piling up of |
| 237 | +non-file form fields in memory. Whenever output body overcomes specified |
| 238 | +limit error 413 (Request entity too large) will be generated. The value |
| 239 | +of zero for this directive specifies that no restrictions on output body |
| 240 | +length should be applied. |
| 241 | + |
| 242 | +### upload_tame_arrays |
| 243 | + |
| 244 | +**Syntax:** <code><b>upload_tame_arrays</b> on | off</code><br> |
| 245 | +**Default:** `off`<br> |
| 246 | +**Context:** `main,server,location` |
| 247 | + |
| 248 | +Specifies whether square brackets in file field names must be dropped |
| 249 | +(required for PHP arrays). |
| 250 | + |
| 251 | +### upload_pass_args |
| 252 | + |
| 253 | +**Syntax:** <code><b>upload_pass_args</b> on | off</code><br> |
| 254 | +**Default:** `off`<br> |
| 255 | +**Context:** `main,server,location` |
| 256 | + |
| 257 | +Enables forwarding of query arguments to location, specified by |
| 258 | +[upload_pass](#upload_pass). Ineffective with named locations. Example: |
| 259 | + |
| 260 | +```html |
| 261 | +<form action="/upload/?id=5"> |
| 262 | +<!-- ... --> |
| 263 | +``` |
| 264 | + |
| 265 | +```nginx |
| 266 | +location /upload/ { |
| 267 | + upload_pass /internal_upload/; |
| 268 | + upload_pass_args on; |
| 269 | +} |
| 270 | +
|
| 271 | +# ... |
| 272 | +
|
| 273 | +location /internal_upload/ { |
| 274 | + # ... |
| 275 | + proxy_pass http://backend; |
| 276 | +} |
| 277 | +``` |
| 278 | + |
| 279 | +In this example backend gets request URI "/upload?id=5". In case of |
| 280 | +`upload_pass_args off` backend gets "/upload". |
| 281 | + |
| 282 | +## Example configuration |
| 283 | + |
| 284 | +```nginx |
| 285 | +server { |
| 286 | + client_max_body_size 100m; |
| 287 | + listen 80; |
| 288 | +
|
| 289 | + # Upload form should be submitted to this location |
| 290 | + location /upload/ { |
| 291 | + # Pass altered request body to this location |
| 292 | + upload_pass @test; |
| 293 | +
|
| 294 | + # Store files to this directory |
| 295 | + # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist |
| 296 | + upload_store /tmp 1; |
| 297 | +
|
| 298 | + # Allow uploaded files to be read only by user |
| 299 | + upload_store_access user:r; |
| 300 | +
|
| 301 | + # Set specified fields in request body |
| 302 | + upload_set_form_field $upload_field_name.name "$upload_file_name"; |
| 303 | + upload_set_form_field $upload_field_name.content_type "$upload_content_type"; |
| 304 | + upload_set_form_field $upload_field_name.path "$upload_tmp_path"; |
| 305 | +
|
| 306 | + # Inform backend about hash and size of a file |
| 307 | + upload_aggregate_form_field "$upload_field_name.md5" "$upload_file_md5"; |
| 308 | + upload_aggregate_form_field "$upload_field_name.size" "$upload_file_size"; |
| 309 | +
|
| 310 | + upload_pass_form_field "^submit$|^description$"; |
| 311 | +
|
| 312 | + upload_cleanup 400 404 499 500-505; |
| 313 | + } |
| 314 | +
|
| 315 | + # Pass altered request body to a backend |
| 316 | + location @test { |
| 317 | + proxy_pass http://localhost:8080; |
| 318 | + } |
| 319 | +} |
| 320 | +``` |
| 321 | + |
| 322 | +```html |
| 323 | +<form name="upload" method="POST" enctype="multipart/form-data" action="/upload/"> |
| 324 | +<input type="file" name="file1"> |
| 325 | +<input type="file" name="file2"> |
| 326 | +<input type="hidden" name="test" value="value"> |
| 327 | +<input type="submit" name="submit" value="Upload"> |
| 328 | +</form> |
| 329 | +``` |
| 330 | + |
| 331 | +## License |
| 332 | + |
| 333 | +The above-described module is an addition to |
| 334 | +[nginx](https://www.nginx.com/) web-server, nevertheless they are |
| 335 | +independent products. The license of above-described module is |
| 336 | +[BSD](http://en.wikipedia.org/wiki/BSD_license) You should have received |
| 337 | +a copy of license along with the source code. By using the materials |
| 338 | +from this site you automatically agree to the terms and conditions of |
| 339 | +this license. If you don't agree to the terms and conditions of this |
| 340 | +license, you must immediately remove from your computer all materials |
| 341 | +downloaded from this site. |
0 commit comments