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