{"id":13788582,"url":"https://github.com/fdintino/nginx-upload-module","last_synced_at":"2025-05-15T20:07:30.374Z","repository":{"id":470468,"uuid":"95414","full_name":"fdintino/nginx-upload-module","owner":"fdintino","description":"A module for nginx web server for handling file uploads using multipart/form-data encoding (RFC 1867).","archived":false,"fork":false,"pushed_at":"2024-07-17T20:13:04.000Z","size":315,"stargazers_count":989,"open_issues_count":52,"forks_count":388,"subscribers_count":73,"default_branch":"master","last_synced_at":"2025-04-08T01:39:32.792Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.grid.net.ru/nginx/upload.en.html","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fdintino.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2008-12-22T19:05:33.000Z","updated_at":"2025-03-26T02:27:33.000Z","dependencies_parsed_at":"2024-08-03T21:12:35.270Z","dependency_job_id":null,"html_url":"https://github.com/fdintino/nginx-upload-module","commit_stats":{"total_commits":148,"total_committers":21,"mean_commits":"7.0476190476190474","dds":0.7162162162162162,"last_synced_commit":"96e64603dc5a588a2d1ae59a62b0019d6b41070c"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fdintino%2Fnginx-upload-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fdintino%2Fnginx-upload-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fdintino%2Fnginx-upload-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fdintino%2Fnginx-upload-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fdintino","download_url":"https://codeload.github.com/fdintino/nginx-upload-module/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254414499,"owners_count":22067272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T21:00:50.530Z","updated_at":"2025-05-15T20:07:25.327Z","avatar_url":"https://github.com/fdintino.png","language":"C","funding_links":[],"categories":["Third Party Modules","Upstreams, rate limiting and access control"],"sub_categories":["C Modules"],"readme":"# nginx-upload-module\n\n[![Build Status](https://travis-ci.org/fdintino/nginx-upload-module.svg?branch=master)](https://travis-ci.org/fdintino/nginx-upload-module)\n[![codecov](https://codecov.io/gh/fdintino/nginx-upload-module/branch/master/graph/badge.svg)](https://codecov.io/gh/fdintino/nginx-upload-module)\n\nA module for [nginx](https://www.nginx.com/) for handling file uploads using\nmultipart/form-data encoding ([RFC 1867](http://www.ietf.org/rfc/rfc1867.txt))\nand resumable uploads according to\n[this](https://github.com/fdintino/nginx-upload-module/blob/master/upload-protocol.md)\nprotocol.\n\n* [Description](#description)\n* [Directives](#directives)\n    * [upload_pass](#upload_pass)\n    * [upload_resumable](#upload_resumable)\n    * [upload_store](#upload_store)\n    * [upload_state_store](#upload_state_store)\n    * [upload_store_access](#upload_store_access)\n    * [upload_set_form_field](#upload_set_form_field)\n    * [upload_aggregate_form_field](#upload_aggregate_form_field)\n    * [upload_pass_form_field](#upload_pass_form_field)\n    * [upload_cleanup](#upload_cleanup)\n    * [upload_buffer_size](#upload_buffer_size)\n    * [upload_max_part_header_len](#upload_max_part_header_len)\n    * [upload_max_file_size](#upload_max_file_size)\n    * [upload_limit_rate](#upload_limit_rate)\n    * [upload_max_output_body_len](#upload_max_output_body_len)\n    * [upload_tame_arrays](#upload_tame_arrays)\n    * [upload_pass_args](#upload_pass_args)\n* [Example configuration](#example-configuration)\n* [License](#license)\n\n## Description\n\nThe module parses request body storing all files being uploaded to a\ndirectory specified by [`upload_store`](#upload_store) directive. The\nfiles are then being stripped from body and altered request is then\npassed to a location specified by [`upload_pass`](#upload_pass)\ndirective, thus allowing arbitrary handling of uploaded files. Each of\nfile fields are being replaced by a set of fields specified by\n[`upload_set_form_field`](#upload_set_form_field) directive. The\ncontent of each uploaded file then could be read from a file specified\nby $upload_tmp_path variable or the file could be simply moved to\nultimate destination. Removal of output files is controlled by directive\n[`upload_cleanup`](#upload_cleanup). If a request has a method other than\nPOST, the module returns error 405 (Method not allowed). Requests with\nsuch methods could be processed in alternative location via\n[`error_page`](http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page)\ndirective.\n\n## Directives\n\n### upload_pass\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_pass\u003c/b\u003e \u003ci\u003elocation\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** —\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies location to pass request body to. File fields will be stripped\nand replaced by fields, containing necessary information to handle\nuploaded files.\n\n### upload_resumable\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_resumable\u003c/b\u003e on | off\u003c/code\u003e\u003cbr\u003e\n**Default:** `upload_resumable off`\u003cbr\u003e\n**Context:** `main,server,location`\n\nEnables resumable uploads.\n\n### upload_store\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_store\u003c/b\u003e \u003ci\u003edirectory\u003c/i\u003e [\u003ci\u003elevel1\u003c/i\u003e [\u003ci\u003elevel2\u003c/i\u003e]] ...\u003c/code\u003e\u003cbr\u003e\n**Default:** —\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies a directory to which output files will be saved to. The\ndirectory could be hashed. In this case all subdirectories should exist\nbefore starting nginx.\n\n### upload_state_store\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_state_store\u003c/b\u003e \u003ci\u003edirectory\u003c/i\u003e [\u003ci\u003elevel1\u003c/i\u003e [\u003ci\u003elevel2\u003c/i\u003e]] ...\u003c/code\u003e\u003cbr\u003e\n**Default:** —\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies a directory that will contain state files for resumable\nuploads. The directory could be hashed. In this case all subdirectories\nshould exist before starting nginx.\n\n### upload_store_access\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_store_access\u003c/b\u003e \u003ci\u003emode\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** `upload_store_access user:rw`\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies access mode which will be used to create output files.\n\n### upload_set_form_field\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_set_form_field\u003c/b\u003e \u003ci\u003ename\u003c/i\u003e \u003ci\u003evalue\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** —\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies a form field(s) to generate for each uploaded file in request\nbody passed to backend. Both `name` and `value` could contain following\nspecial variables:\n\n  - `$upload_field_name`: the name of original file field\n  - `$upload_content_type`: the content type of file uploaded\n  - `$upload_file_name`: the original name of the file being uploaded\n    with leading path elements in DOS and UNIX notation stripped. I.e.\n    \"D:\\\\Documents And Settings\\\\My Dcouments\\\\My Pictures\\\\Picture.jpg\"\n    will be converted to \"Picture.jpg\" and \"/etc/passwd\" will be\n    converted to \"passwd\".\n  - `$upload_tmp_path`: the path where the content of original file is\n    being stored to. The output file name consists 10 digits and\n    generated with the same algorithm as in `proxy_temp_path`\n    directive.\n\nThese variables are valid only during processing of one part of original\nrequest body.\n\nUsage example:\n\n```nginx\nupload_set_form_field $upload_field_name.name \"$upload_file_name\";\nupload_set_form_field $upload_field_name.content_type \"$upload_content_type\";\nupload_set_form_field $upload_field_name.path \"$upload_tmp_path\";\n```\n\n### upload_aggregate_form_field\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_aggregate_form_field\u003c/b\u003e \u003ci\u003ename\u003c/i\u003e \u003ci\u003evalue\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** —\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies a form field(s) containing aggregate attributes to generate\nfor each uploaded file in request body passed to backend. Both name and\nvalue could contain standard nginx variables, variables from\n[upload_set_form_field](#upload_set_form_field) directive and\nfollowing additional special variables:\n\n  - `$upload_file_md5`: MD5 checksum of the file\n  - `$upload_file_md5_uc`: MD5 checksum of the file in uppercase letters\n  - `$upload_file_sha1`: SHA1 checksum of the file\n  - `$upload_file_sha1_uc`: SHA1 checksum of the file in uppercase letters\n  - `$upload_file_sha256`: SHA256 checksum of the file\n  - `$upload_file_sha256_uc`: SHA256 checksum of the file in uppercase letters\n  - `$upload_file_sha512`: SHA512 checksum of the file\n  - `$upload_file_sha512_uc`: SHA512 checksum of the file in uppercase letters\n  - `$upload_file_crc32`: hexdecimal value of CRC32 of the file\n  - `$upload_file_size`: size of the file in bytes\n  - `$upload_file_number`: ordinal number of file in request body\n\nThe value of a field specified by this directive is evaluated after\nsuccessful upload of the file, thus these variables are valid only at\nthe end of processing of one part of original request body.\n\n**Warning:**: variables `$upload_file_md5`, `$upload_file_md5_uc`,\n`$upload_file_sha1`, and `$upload_file_sha1_uc` use additional\nresources to calculate MD5 and SHA1 checksums.\n\nUsage example:\n\n```nginx\nupload_aggregate_form_field $upload_field_name.md5 \"$upload_file_md5\";\nupload_aggregate_form_field $upload_field_name.size \"$upload_file_size\";\n\n```\n\n### upload_pass_form_field\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_pass_form_field\u003c/b\u003e \u003ci\u003eregex\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** —\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies a regex pattern for names of fields which will be passed to\nbackend from original request body. This directive could be specified\nmultiple times per location. Field will be passed to backend as soon as\nfirst pattern matches. For PCRE-unaware enviroments this directive\nspecifies exact name of a field to pass to backend. If directive is\nomitted, no fields will be passed to backend from client.\n\nUsage example:\n\n```nginx\nupload_pass_form_field \"^submit$|^description$\";\n```\n\nFor PCRE-unaware environments:\n\n```nginx\nupload_pass_form_field \"submit\";\nupload_pass_form_field \"description\";\n\n```\n\n### upload_cleanup\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_cleanup\u003c/b\u003e \u003ci\u003estatus/range\u003c/i\u003e ...\u003c/code\u003e\u003cbr\u003e\n**Default:** —\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies HTTP statuses after generation of which all file successfuly\nuploaded in current request will be removed. Used for cleanup after\nbackend or server failure. Backend may also explicitly signal errornous\nstatus if it doesn't need uploaded files for some reason. HTTP status\nmust be a numerical value in range 400-599, no leading zeroes are\nallowed. Ranges of statuses could be specified with a dash.\n\nUsage example:\n\n```nginx\nupload_cleanup 400 404 499 500-505;\n```\n\n### upload_buffer_size\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_buffer_size\u003c/b\u003e \u003ci\u003esize\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** size of memory page in bytes\u003cbr\u003e\n**Context:** `server,location`\n\nSize in bytes of write buffer which will be used to accumulate file data\nand write it to disk. This directive is intended to be used to\ncompromise memory usage vs. syscall rate.\n\n### upload_max_part_header_len\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_max_part_header_len\u003c/b\u003e \u003ci\u003esize\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** `512`\u003cbr\u003e\n**Context:** `server,location`\n\nSpecifies maximal length of part header in bytes. Determines the size of\nthe buffer which will be used to accumulate part headers.\n\n### upload_max_file_size\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_max_file_size\u003c/b\u003e \u003ci\u003esize\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** `0`\u003cbr\u003e\n**Context:** `main,server,location`\n\nSpecifies maximal size of the file. Files longer than the value of this\ndirective will be omitted. This directive specifies \"soft\" limit, in the\nsense, that after encountering file longer than specified limit, nginx\nwill continue to process request body, trying to receive remaining\nfiles. For \"hard\" limit `client_max_body_size` directive must be\nused. The value of zero for this directive specifies that no\nrestrictions on file size should be applied.\n\n### upload_limit_rate\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_limit_rate\u003c/b\u003e \u003ci\u003erate\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** `0`\u003cbr\u003e\n**Context:** `main,server,location`\n\nSpecifies upload rate limit in bytes per second. Zero means rate is\nunlimited.\n\n### upload_max_output_body_len\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_max_output_body_len\u003c/b\u003e \u003ci\u003esize\u003c/i\u003e\u003c/code\u003e\u003cbr\u003e\n**Default:** `100k`\u003cbr\u003e\n**Context:** `main,server,location`\n\nSpecifies maximal length of the output body. This prevents piling up of\nnon-file form fields in memory. Whenever output body overcomes specified\nlimit error 413 (Request entity too large) will be generated. The value\nof zero for this directive specifies that no restrictions on output body\nlength should be applied.\n\n### upload_tame_arrays\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_tame_arrays\u003c/b\u003e on | off\u003c/code\u003e\u003cbr\u003e\n**Default:** `off`\u003cbr\u003e\n**Context:** `main,server,location`\n\nSpecifies whether square brackets in file field names must be dropped\n(required for PHP arrays).\n\n### upload_pass_args\n\n**Syntax:** \u003ccode\u003e\u003cb\u003eupload_pass_args\u003c/b\u003e on | off\u003c/code\u003e\u003cbr\u003e\n**Default:** `off`\u003cbr\u003e\n**Context:** `main,server,location`\n\nEnables forwarding of query arguments to location, specified by\n[upload_pass](#upload_pass). Ineffective with named locations. Example:\n\n```html\n\u003cform action=\"/upload/?id=5\"\u003e\n\u003c!-- ... --\u003e\n```\n\n```nginx\nlocation /upload/ {\n    upload_pass /internal_upload/;\n    upload_pass_args on;\n}\n\n# ...\n\nlocation /internal_upload/ {\n    # ...\n    proxy_pass http://backend;\n}\n```\n\nIn this example backend gets request URI \"/upload?id=5\". In case of\n`upload_pass_args off` backend gets \"/upload\".\n\n## Example configuration\n\n```nginx\nserver {\n    client_max_body_size 100m;\n    listen 80;\n\n    # Upload form should be submitted to this location\n    location /upload/ {\n        # Pass altered request body to this location\n        upload_pass @test;\n\n        # Store files to this directory\n        # The directory is hashed, subdirectories 0 1 2 3 4 5 6 7 8 9 should exist\n        upload_store /tmp 1;\n\n        # Allow uploaded files to be read only by user\n        upload_store_access user:r;\n\n        # Set specified fields in request body\n        upload_set_form_field $upload_field_name.name \"$upload_file_name\";\n        upload_set_form_field $upload_field_name.content_type \"$upload_content_type\";\n        upload_set_form_field $upload_field_name.path \"$upload_tmp_path\";\n\n        # Inform backend about hash and size of a file\n        upload_aggregate_form_field \"$upload_field_name.md5\" \"$upload_file_md5\";\n        upload_aggregate_form_field \"$upload_field_name.size\" \"$upload_file_size\";\n\n        upload_pass_form_field \"^submit$|^description$\";\n\n        upload_cleanup 400 404 499 500-505;\n    }\n\n    # Pass altered request body to a backend\n    location @test {\n        proxy_pass http://localhost:8080;\n    }\n}\n```\n\n```html\n\u003cform name=\"upload\" method=\"POST\" enctype=\"multipart/form-data\" action=\"/upload/\"\u003e\n\u003cinput type=\"file\" name=\"file1\"\u003e\n\u003cinput type=\"file\" name=\"file2\"\u003e\n\u003cinput type=\"hidden\" name=\"test\" value=\"value\"\u003e\n\u003cinput type=\"submit\" name=\"submit\" value=\"Upload\"\u003e\n\u003c/form\u003e\n```\n\n## License\n\nThe above-described module is an addition to\n[nginx](https://www.nginx.com/) web-server, nevertheless they are\nindependent products. The license of above-described module is\n[BSD](http://en.wikipedia.org/wiki/BSD_license) You should have received\na copy of license along with the source code. By using the materials\nfrom this site you automatically agree to the terms and conditions of\nthis license. If you don't agree to the terms and conditions of this\nlicense, you must immediately remove from your computer all materials\ndownloaded from this site.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffdintino%2Fnginx-upload-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffdintino%2Fnginx-upload-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffdintino%2Fnginx-upload-module/lists"}