pax_global_header00006660000000000000000000000064150361007210014505gustar00rootroot0000000000000052 comment=41996f5ac73a867046d48512cab62e64fc846dad form-data-form-data-a661bf5/000077500000000000000000000000001503610072100156435ustar00rootroot00000000000000form-data-form-data-a661bf5/.editorconfig000066400000000000000000000002461503610072100203220ustar00rootroot00000000000000# editorconfig.org root = true [*] indent_style = space indent_size = 2 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true form-data-form-data-a661bf5/.eslintrc000066400000000000000000000020761503610072100174740ustar00rootroot00000000000000{ "root": true, "extends": "@ljharb", "rules": { "indent": [2, 2, {"SwitchCase": 2}], // "curly": [2, "multi-line"], "handle-callback-err": [2, "^err"], "valid-jsdoc": [2, { "requireReturn": false, "requireReturnDescription": false, "prefer": { "return": "returns" } }], "require-jsdoc": [2, { "require": { "FunctionDeclaration": true } }], "no-redeclare": [2, { "builtinGlobals": true }], "no-shadow": [2, { "builtinGlobals": false, "hoist": "all" }], "no-use-before-define": [2, "nofunc"], "no-shadow-restricted-names": 2, "no-extra-semi": 2, "no-unused-vars": 2, "no-undef": 2, "strict": 0, "dot-notation": 0, "no-new": 0, "eqeqeq": 0, "no-underscore-dangle": 0, "camelcase": 0, "func-style": 0, "max-lines": 0, "id-length": 1, "multiline-comment-style": 0, "no-plusplus": 1, "no-caller": 1, }, "env": { "node": true }, "ignorePatterns": [ "node_modules/*", "index.d.ts", "coverage", ], } form-data-form-data-a661bf5/.github/000077500000000000000000000000001503610072100172035ustar00rootroot00000000000000form-data-form-data-a661bf5/.github/workflows/000077500000000000000000000000001503610072100212405ustar00rootroot00000000000000form-data-form-data-a661bf5/.github/workflows/node-aught.yml000066400000000000000000000003631503610072100240200ustar00rootroot00000000000000name: 'Tests: node.js < 10' on: [pull_request, push] permissions: contents: read jobs: tests: uses: ljharb/actions/.github/workflows/node.yml@main with: range: '>= 6 < 10' type: minors command: npm run ci-test form-data-form-data-a661bf5/.github/workflows/node-pretest.yml000066400000000000000000000002451503610072100243750ustar00rootroot00000000000000name: 'Tests: pretest/posttest' on: [pull_request, push] permissions: contents: read jobs: tests: uses: ljharb/actions/.github/workflows/pretest.yml@main form-data-form-data-a661bf5/.github/workflows/node-tens.yml000066400000000000000000000003601503610072100236560ustar00rootroot00000000000000name: 'Tests: node.js >= 10' on: [pull_request, push] permissions: contents: read jobs: tests: uses: ljharb/actions/.github/workflows/node.yml@main with: range: '>= 10' type: minors command: npm run ci-test form-data-form-data-a661bf5/.github/workflows/rebase.yml000066400000000000000000000007001503610072100232210ustar00rootroot00000000000000name: Automatic Rebase on: [pull_request_target] permissions: contents: read jobs: _: permissions: contents: write # for ljharb/rebase to push code to rebase pull-requests: read # for ljharb/rebase to get info about PR name: "Automatic Rebase" runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: ljharb/rebase@master env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} form-data-form-data-a661bf5/.github/workflows/require-allow-edits.yml000066400000000000000000000005151503610072100256620ustar00rootroot00000000000000name: Require “Allow Edits” on: [pull_request_target] permissions: contents: read jobs: _: permissions: pull-requests: read # for ljharb/require-allow-edits to check 'allow edits' on PR name: "Require “Allow Edits”" runs-on: ubuntu-latest steps: - uses: ljharb/require-allow-edits@main form-data-form-data-a661bf5/.gitignore000066400000000000000000000003311503610072100176300ustar00rootroot00000000000000*.bak *.iml *.log *.sublime-* *.un~ .DS_Store .idea sftp-config.json yarn.lock package-lock.json coverage/ node_modules/ test/tmp/ # Only apps should have lockfiles npm-shrinkwrap.json package-lock.json yarn.lock form-data-form-data-a661bf5/.istanbul.yml000066400000000000000000000004571503610072100202730ustar00rootroot00000000000000verbose: false instrumentation: root: . extensions: - .js default-excludes: true reporting: print: summary reports: - json dir: ./coverage watermarks: statements: [90, 95] lines: [90, 95] functions: [90, 95] branches: [90, 95] form-data-form-data-a661bf5/.npmignore000066400000000000000000000001331503610072100176370ustar00rootroot00000000000000.* Makefile appveyor.yml sftp-config.json coverage/ node_modules/ test/ yarn.lock *.bak form-data-form-data-a661bf5/.npmrc000066400000000000000000000000671503610072100167660ustar00rootroot00000000000000package-lock=false allow-same-version=true message=v%s form-data-form-data-a661bf5/CHANGELOG.md000066400000000000000000001243371503610072100174660ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [v4.0.4](https://github.com/form-data/form-data/compare/v4.0.3...v4.0.4) - 2025-07-16 ### Commits - [meta] add `auto-changelog` [`811f682`](https://github.com/form-data/form-data/commit/811f68282fab0315209d0e2d1c44b6c32ea0d479) - [Tests] handle predict-v8-randomness failures in node < 17 and node > 23 [`1d11a76`](https://github.com/form-data/form-data/commit/1d11a76434d101f22fdb26b8aef8615f28b98402) - [Fix] Switch to using `crypto` random for boundary values [`3d17230`](https://github.com/form-data/form-data/commit/3d1723080e6577a66f17f163ecd345a21d8d0fd0) - [Tests] fix linting errors [`5e34080`](https://github.com/form-data/form-data/commit/5e340800b5f8914213e4e0378c084aae71cfd73a) - [meta] actually ensure the readme backup isn’t published [`316c82b`](https://github.com/form-data/form-data/commit/316c82ba93fd4985af757b771b9a1f26d3b709ef) - [Dev Deps] update `@ljharb/eslint-config` [`58c25d7`](https://github.com/form-data/form-data/commit/58c25d76406a5b0dfdf54045cf252563f2bbda8d) - [meta] fix readme capitalization [`2300ca1`](https://github.com/form-data/form-data/commit/2300ca19595b0ee96431e868fe2a40db79e41c61) ## [v4.0.3](https://github.com/form-data/form-data/compare/v4.0.2...v4.0.3) - 2025-06-05 ### Fixed - [Fix] `append`: avoid a crash on nullish values [`#577`](https://github.com/form-data/form-data/issues/577) ### Commits - [eslint] use a shared config [`426ba9a`](https://github.com/form-data/form-data/commit/426ba9ac440f95d1998dac9a5cd8d738043b048f) - [eslint] fix some spacing issues [`2094191`](https://github.com/form-data/form-data/commit/20941917f0e9487e68c564ebc3157e23609e2939) - [Refactor] use `hasown` [`81ab41b`](https://github.com/form-data/form-data/commit/81ab41b46fdf34f5d89d7ff30b513b0925febfaa) - [Fix] validate boundary type in `setBoundary()` method [`8d8e469`](https://github.com/form-data/form-data/commit/8d8e4693093519f7f18e3c597d1e8df8c493de9e) - [Tests] add tests to check the behavior of `getBoundary` with non-strings [`837b8a1`](https://github.com/form-data/form-data/commit/837b8a1f7562bfb8bda74f3fc538adb7a5858995) - [Dev Deps] remove unused deps [`870e4e6`](https://github.com/form-data/form-data/commit/870e4e665935e701bf983a051244ab928e62d58e) - [meta] remove local commit hooks [`e6e83cc`](https://github.com/form-data/form-data/commit/e6e83ccb545a5619ed6cd04f31d5c2f655eb633e) - [Dev Deps] update `eslint` [`4066fd6`](https://github.com/form-data/form-data/commit/4066fd6f65992b62fa324a6474a9292a4f88c916) - [meta] fix scripts to use prepublishOnly [`c4bbb13`](https://github.com/form-data/form-data/commit/c4bbb13c0ef669916657bc129341301b1d331d75) ## [v4.0.2](https://github.com/form-data/form-data/compare/v4.0.1...v4.0.2) - 2025-02-14 ### Merged - [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) - [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) - fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) - fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) ### Fixed - [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) - [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) - [Fix] set `Symbol.toStringTag` when available [`#396`](https://github.com/form-data/form-data/issues/396) ### Commits - Merge tags v2.5.3 and v3.0.3 [`92613b9`](https://github.com/form-data/form-data/commit/92613b9208556eb4ebc482fdf599fae111626fb6) - [Tests] migrate from travis to GHA [`806eda7`](https://github.com/form-data/form-data/commit/806eda77740e6e3c67c7815afb216f2e1f187ba5) - [Tests] migrate from travis to GHA [`8fdb3bc`](https://github.com/form-data/form-data/commit/8fdb3bc6b5d001f8909a9fca391d1d1d97ef1d79) - [Refactor] use `Object.prototype.hasOwnProperty.call` [`7fecefe`](https://github.com/form-data/form-data/commit/7fecefe4ba8f775634aff86a698776ad95ecffb5) - [Refactor] use `Object.prototype.hasOwnProperty.call` [`6e682d4`](https://github.com/form-data/form-data/commit/6e682d4bd41de7e80de41e3c4ee10f23fcc3dd00) - [Refactor] use `Object.prototype.hasOwnProperty.call` [`df3c1e6`](https://github.com/form-data/form-data/commit/df3c1e6f0937f47a782dc4573756a54987f31dde) - [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`8261fcb`](https://github.com/form-data/form-data/commit/8261fcb8bf5944d30ae3bd04b91b71d6a9932ef4) - [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`fb66cb7`](https://github.com/form-data/form-data/commit/fb66cb740e29fb170eee947d4be6fdf82d6659af) - [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `eslint`, `formidable`, `in-publish`, `phantomjs-prebuilt`, `pkgfiles`, `pre-commit`, `request`, `tape`, `typescript` [`819f6b7`](https://github.com/form-data/form-data/commit/819f6b7a543306a891fca37c3a06d0ff4a734422) - [eslint] clean up ignores [`3217b3d`](https://github.com/form-data/form-data/commit/3217b3ded8e382e51171d5c74c6038a21cc54440) - [eslint] clean up ignores [`3a9d480`](https://github.com/form-data/form-data/commit/3a9d480232dbcbc07260ad84c3da4975d9a3ae9e) - [Fix] `Buffer.from` and `Buffer.alloc` require node 4+ [`c499f76`](https://github.com/form-data/form-data/commit/c499f76f1faac1ddbf210c45217038e4c1e02337) - Only apps should have lockfiles [`b82f590`](https://github.com/form-data/form-data/commit/b82f59093cdbadb4b7ec0922d33ae7ab048b82ff) - Only apps should have lockfiles [`b170ee2`](https://github.com/form-data/form-data/commit/b170ee2b22b4c695c363b811c0c553d2fb1bbd79) - [Deps] update `combined-stream`, `mime-types` [`6b1ca1d`](https://github.com/form-data/form-data/commit/6b1ca1dc7362a1b1c3a99a885516cca4b7eb817f) - [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`e5df7f2`](https://github.com/form-data/form-data/commit/e5df7f24383342264bd73dee3274818a40d04065) - [Deps] update `mime-types` [`5a5bafe`](https://github.com/form-data/form-data/commit/5a5bafee894fead10da49e1fa2b084e17f2e1034) - Bumped version 2.5.3 [`9457283`](https://github.com/form-data/form-data/commit/9457283e1dce6122adc908fdd7442cfc54cabe7a) - [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`9dbe192`](https://github.com/form-data/form-data/commit/9dbe192be3db215eac4d9c0b980470a5c2c030c6) - Merge tags v2.5.2 and v3.0.2 [`d53265d`](https://github.com/form-data/form-data/commit/d53265d86c5153f535ec68eb107548b1b2883576) - Bumped version 2.5.2 [`7020dd4`](https://github.com/form-data/form-data/commit/7020dd4c1260370abc40e86e3dfe49c5d576fbda) - [Dev Deps] downgrade `cross-spawn` [`3fc1a9b`](https://github.com/form-data/form-data/commit/3fc1a9b62ddf1fe77a2bd6bd3476e4c0a9e01a88) - fix: move util.isArray to Array.isArray (#564) [`edb555a`](https://github.com/form-data/form-data/commit/edb555a811f6f7e4668db4831551cf41c1de1cac) - fix: move util.isArray to Array.isArray (#564) [`10418d1`](https://github.com/form-data/form-data/commit/10418d1fe4b0d65fe020eafe3911feb5ad5e2bd6) ## [v4.0.1](https://github.com/form-data/form-data/compare/v4.0.0...v4.0.1) - 2024-10-10 ### Commits - [Tests] migrate from travis to GHA [`757b4e3`](https://github.com/form-data/form-data/commit/757b4e32e95726aec9bdcc771fb5a3b564d88034) - [eslint] clean up ignores [`e8f0d80`](https://github.com/form-data/form-data/commit/e8f0d80cd7cd424d1488532621ec40a33218b30b) - fix (npmignore): ignore temporary build files [`335ad19`](https://github.com/form-data/form-data/commit/335ad19c6e17dc2d7298ffe0e9b37ba63600e94b) - fix: move util.isArray to Array.isArray [`440d3be`](https://github.com/form-data/form-data/commit/440d3bed752ac2f9213b4c2229dbccefe140e5fa) ## [v4.0.0](https://github.com/form-data/form-data/compare/v3.0.3...v4.0.0) - 2021-02-15 ### Merged - Handle custom stream [`#382`](https://github.com/form-data/form-data/pull/382) ### Commits - Fix typo [`e705c0a`](https://github.com/form-data/form-data/commit/e705c0a1fdaf90d21501f56460b93e43a18bd435) - Update README for custom stream behavior [`6dd8624`](https://github.com/form-data/form-data/commit/6dd8624b2999e32768d62752c9aae5845a803b0d) ## [v3.0.3](https://github.com/form-data/form-data/compare/v3.0.2...v3.0.3) - 2025-02-14 ### Merged - [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) ### Fixed - [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) ### Commits - [Refactor] use `Object.prototype.hasOwnProperty.call` [`7fecefe`](https://github.com/form-data/form-data/commit/7fecefe4ba8f775634aff86a698776ad95ecffb5) - [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `cross-spawn`, `eslint`, `formidable`, `in-publish`, `pkgfiles`, `pre-commit`, `puppeteer`, `request`, `tape`, `typescript` [`8261fcb`](https://github.com/form-data/form-data/commit/8261fcb8bf5944d30ae3bd04b91b71d6a9932ef4) - Only apps should have lockfiles [`b82f590`](https://github.com/form-data/form-data/commit/b82f59093cdbadb4b7ec0922d33ae7ab048b82ff) - [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`e5df7f2`](https://github.com/form-data/form-data/commit/e5df7f24383342264bd73dee3274818a40d04065) - [Deps] update `mime-types` [`5a5bafe`](https://github.com/form-data/form-data/commit/5a5bafee894fead10da49e1fa2b084e17f2e1034) ## [v3.0.2](https://github.com/form-data/form-data/compare/v3.0.1...v3.0.2) - 2024-10-10 ### Merged - fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) ### Commits - [Tests] migrate from travis to GHA [`8fdb3bc`](https://github.com/form-data/form-data/commit/8fdb3bc6b5d001f8909a9fca391d1d1d97ef1d79) - [eslint] clean up ignores [`3217b3d`](https://github.com/form-data/form-data/commit/3217b3ded8e382e51171d5c74c6038a21cc54440) - fix: move util.isArray to Array.isArray (#564) [`edb555a`](https://github.com/form-data/form-data/commit/edb555a811f6f7e4668db4831551cf41c1de1cac) ## [v3.0.1](https://github.com/form-data/form-data/compare/v3.0.0...v3.0.1) - 2021-02-15 ### Merged - Fix typo: ads -> adds [`#451`](https://github.com/form-data/form-data/pull/451) ### Commits - feat: add setBoundary method [`55d90ce`](https://github.com/form-data/form-data/commit/55d90ce4a4c22b0ea0647991d85cb946dfb7395b) ## [v3.0.0](https://github.com/form-data/form-data/compare/v2.5.3...v3.0.0) - 2019-11-05 ### Merged - Update Readme.md [`#449`](https://github.com/form-data/form-data/pull/449) - Update package.json [`#448`](https://github.com/form-data/form-data/pull/448) - fix memory leak [`#447`](https://github.com/form-data/form-data/pull/447) - form-data: Replaced PhantomJS Dependency [`#442`](https://github.com/form-data/form-data/pull/442) - Fix constructor options in Typescript definitions [`#446`](https://github.com/form-data/form-data/pull/446) - Fix the getHeaders method signatures [`#434`](https://github.com/form-data/form-data/pull/434) - Update combined-stream (fixes #422) [`#424`](https://github.com/form-data/form-data/pull/424) ### Fixed - Merge pull request #424 from botgram/update-combined-stream [`#422`](https://github.com/form-data/form-data/issues/422) - Update combined-stream (fixes #422) [`#422`](https://github.com/form-data/form-data/issues/422) ### Commits - Add readable stream options to constructor type [`80c8f74`](https://github.com/form-data/form-data/commit/80c8f746bcf4c0418ae35fbedde12fb8c01e2748) - Fixed: getHeaders method signatures [`f4ca7f8`](https://github.com/form-data/form-data/commit/f4ca7f8e31f7e07df22c1aeb8e0a32a7055a64ca) - Pass options to constructor if not used with new [`4bde68e`](https://github.com/form-data/form-data/commit/4bde68e12de1ba90fefad2e7e643f6375b902763) - Make userHeaders optional [`2b4e478`](https://github.com/form-data/form-data/commit/2b4e4787031490942f2d1ee55c56b85a250875a7) ## [v2.5.3](https://github.com/form-data/form-data/compare/v2.5.2...v2.5.3) - 2025-02-14 ### Merged - [Fix] set `Symbol.toStringTag` when available [`#573`](https://github.com/form-data/form-data/pull/573) ### Fixed - [Fix] set `Symbol.toStringTag` when available (#573) [`#396`](https://github.com/form-data/form-data/issues/396) ### Commits - [Refactor] use `Object.prototype.hasOwnProperty.call` [`6e682d4`](https://github.com/form-data/form-data/commit/6e682d4bd41de7e80de41e3c4ee10f23fcc3dd00) - [Dev Deps] update `@types/node`, `browserify`, `coveralls`, `eslint`, `formidable`, `in-publish`, `phantomjs-prebuilt`, `pkgfiles`, `pre-commit`, `request`, `tape`, `typescript` [`819f6b7`](https://github.com/form-data/form-data/commit/819f6b7a543306a891fca37c3a06d0ff4a734422) - Only apps should have lockfiles [`b170ee2`](https://github.com/form-data/form-data/commit/b170ee2b22b4c695c363b811c0c553d2fb1bbd79) - [Deps] update `combined-stream`, `mime-types` [`6b1ca1d`](https://github.com/form-data/form-data/commit/6b1ca1dc7362a1b1c3a99a885516cca4b7eb817f) - Bumped version 2.5.3 [`9457283`](https://github.com/form-data/form-data/commit/9457283e1dce6122adc908fdd7442cfc54cabe7a) - [Dev Deps] pin `request` which via `tough-cookie` ^2.4 depends on `psl` [`9dbe192`](https://github.com/form-data/form-data/commit/9dbe192be3db215eac4d9c0b980470a5c2c030c6) ## [v2.5.2](https://github.com/form-data/form-data/compare/v2.5.1...v2.5.2) - 2024-10-10 ### Merged - fix (npmignore): ignore temporary build files [`#532`](https://github.com/form-data/form-data/pull/532) ### Commits - [Tests] migrate from travis to GHA [`806eda7`](https://github.com/form-data/form-data/commit/806eda77740e6e3c67c7815afb216f2e1f187ba5) - [eslint] clean up ignores [`3a9d480`](https://github.com/form-data/form-data/commit/3a9d480232dbcbc07260ad84c3da4975d9a3ae9e) - [Fix] `Buffer.from` and `Buffer.alloc` require node 4+ [`c499f76`](https://github.com/form-data/form-data/commit/c499f76f1faac1ddbf210c45217038e4c1e02337) - Bumped version 2.5.2 [`7020dd4`](https://github.com/form-data/form-data/commit/7020dd4c1260370abc40e86e3dfe49c5d576fbda) - [Dev Deps] downgrade `cross-spawn` [`3fc1a9b`](https://github.com/form-data/form-data/commit/3fc1a9b62ddf1fe77a2bd6bd3476e4c0a9e01a88) - fix: move util.isArray to Array.isArray (#564) [`10418d1`](https://github.com/form-data/form-data/commit/10418d1fe4b0d65fe020eafe3911feb5ad5e2bd6) ## [v2.5.1](https://github.com/form-data/form-data/compare/v2.5.0...v2.5.1) - 2019-08-28 ### Merged - Fix error in callback signatures [`#435`](https://github.com/form-data/form-data/pull/435) - -Fixed: Eerror in the documentations as indicated in #439 [`#440`](https://github.com/form-data/form-data/pull/440) - Add constructor options to TypeScript defs [`#437`](https://github.com/form-data/form-data/pull/437) ### Commits - Add remaining combined-stream options to typedef [`4d41a32`](https://github.com/form-data/form-data/commit/4d41a32c0b3f85f8bbc9cf17df43befd2d5fc305) - Bumped version 2.5.1 [`8ce81f5`](https://github.com/form-data/form-data/commit/8ce81f56cccf5466363a5eff135ad394a929f59b) - Bump rimraf to 2.7.1 [`a6bc2d4`](https://github.com/form-data/form-data/commit/a6bc2d4296dbdee5d84cbab7c69bcd0eea7a12e2) ## [v2.5.0](https://github.com/form-data/form-data/compare/v2.4.0...v2.5.0) - 2019-07-03 ### Merged - - Added: public methods with information and examples to readme [`#429`](https://github.com/form-data/form-data/pull/429) - chore: move @types/node to devDep [`#431`](https://github.com/form-data/form-data/pull/431) - Switched windows tests from AppVeyor to Travis [`#430`](https://github.com/form-data/form-data/pull/430) - feat(typings): migrate TS typings #427 [`#428`](https://github.com/form-data/form-data/pull/428) - enhance the method of path.basename, handle undefined case [`#421`](https://github.com/form-data/form-data/pull/421) ### Commits - - Added: public methods with information and examples to the readme file. [`21323f3`](https://github.com/form-data/form-data/commit/21323f3b4043a167046a4a2554c5f2825356c423) - feat(typings): migrate TS typings [`a3c0142`](https://github.com/form-data/form-data/commit/a3c0142ed91b0c7dcaf89c4f618776708f1f70a9) - - Fixed: Typos [`37350fa`](https://github.com/form-data/form-data/commit/37350fa250782f156a998ec1fa9671866d40ac49) - Switched to Travis Windows from Appveyor [`fc61c73`](https://github.com/form-data/form-data/commit/fc61c7381fad12662df16dbc3e7621c91b886f03) - - Fixed: rendering of subheaders [`e93ed8d`](https://github.com/form-data/form-data/commit/e93ed8df9d7f22078bc3a2c24889e9dfa11e192d) - Updated deps and readme [`e3d8628`](https://github.com/form-data/form-data/commit/e3d8628728f6e4817ab97deeed92f0c822661b89) - Updated dependencies [`19add50`](https://github.com/form-data/form-data/commit/19add50afb7de66c70d189f422d16f1b886616e2) - Bumped version to 2.5.0 [`905f173`](https://github.com/form-data/form-data/commit/905f173a3f785e8d312998e765634ee451ca5f42) - - Fixed: filesize is not a valid option? knownLength should be used for streams [`d88f912`](https://github.com/form-data/form-data/commit/d88f912b75b666b47f8674467516eade69d2d5be) - Bump notion of modern node to node8 [`508b626`](https://github.com/form-data/form-data/commit/508b626bf1b460d3733d3420dc1cfd001617f6ac) - enhance the method of path.basename [`faaa68a`](https://github.com/form-data/form-data/commit/faaa68a297be7d4fca0ac4709d5b93afc1f78b5c) ## [v2.4.0](https://github.com/form-data/form-data/compare/v2.3.2...v2.4.0) - 2019-06-19 ### Merged - Added "getBuffer" method and updated certificates [`#419`](https://github.com/form-data/form-data/pull/419) - docs(readme): add axios integration document [`#425`](https://github.com/form-data/form-data/pull/425) - Allow newer versions of combined-stream [`#402`](https://github.com/form-data/form-data/pull/402) ### Commits - Updated: Certificate [`e90a76a`](https://github.com/form-data/form-data/commit/e90a76ab3dcaa63a6f3045f8255bfbb9c25a3e4e) - Updated build/test/badges [`8512eef`](https://github.com/form-data/form-data/commit/8512eef436e28372f5bc88de3ca76a9cb46e6847) - Bumped version 2.4.0 [`0f8da06`](https://github.com/form-data/form-data/commit/0f8da06c0b4c997bd2f6b09d78290d339616a950) - docs(readme): remove unnecessary bracket [`4e3954d`](https://github.com/form-data/form-data/commit/4e3954dde304d27e3b95371d8c78002f3af5d5b2) - Bumped version to 2.3.3 [`b16916a`](https://github.com/form-data/form-data/commit/b16916a568a0d06f3f8a16c31f9a8b89b7844094) ## [v2.3.2](https://github.com/form-data/form-data/compare/v2.3.1...v2.3.2) - 2018-02-13 ### Merged - Pulling in fixed combined-stream [`#379`](https://github.com/form-data/form-data/pull/379) ### Commits - All the dev dependencies are breaking in old versions of node :'( [`c7dba6a`](https://github.com/form-data/form-data/commit/c7dba6a139d872d173454845e25e1850ed6b72b4) - Updated badges [`19b6c7a`](https://github.com/form-data/form-data/commit/19b6c7a8a5c40f47f91c8a8da3e5e4dc3c449fa3) - Try tests in node@4 [`872a326`](https://github.com/form-data/form-data/commit/872a326ab13e2740b660ff589b75232c3a85fcc9) - Pull in final version [`9d44871`](https://github.com/form-data/form-data/commit/9d44871073d647995270b19dbc26f65671ce15c7) ## [v2.3.1](https://github.com/form-data/form-data/compare/v2.3.0...v2.3.1) - 2017-08-24 ### Commits - Updated readme with custom options example [`8e0a569`](https://github.com/form-data/form-data/commit/8e0a5697026016fe171e93bec43c2205279e23ca) - Added support (tests) for node 8 [`d1d6f4a`](https://github.com/form-data/form-data/commit/d1d6f4ad4670d8ba84cc85b28e522ca0e93eb362) ## [v2.3.0](https://github.com/form-data/form-data/compare/v2.2.0...v2.3.0) - 2017-08-24 ### Merged - Added custom `options` support [`#368`](https://github.com/form-data/form-data/pull/368) - Allow form.submit with url string param to use https [`#249`](https://github.com/form-data/form-data/pull/249) - Proper header production [`#357`](https://github.com/form-data/form-data/pull/357) - Fix wrong MIME type in example [`#285`](https://github.com/form-data/form-data/pull/285) ### Commits - allow form.submit with url string param to use https [`c0390dc`](https://github.com/form-data/form-data/commit/c0390dcc623e15215308fa2bb0225aa431d9381e) - update tests for url parsing [`eec0e80`](https://github.com/form-data/form-data/commit/eec0e807889d46697abd39a89ad9bf39996ba787) - Uses for in to assign properties instead of Object.assign [`f6854ed`](https://github.com/form-data/form-data/commit/f6854edd85c708191bb9c89615a09fd0a9afe518) - Adds test to check for option override [`61762f2`](https://github.com/form-data/form-data/commit/61762f2c5262e576d6a7f778b4ebab6546ef8582) - Removes the 2mb maxDataSize limitation [`dc171c3`](https://github.com/form-data/form-data/commit/dc171c3ba49ac9b8813636fd4159d139b812315b) - Ignore .DS_Store [`e8a05d3`](https://github.com/form-data/form-data/commit/e8a05d33361f7dca8927fe1d96433d049843de24) ## [v2.2.0](https://github.com/form-data/form-data/compare/v2.1.4...v2.2.0) - 2017-06-11 ### Merged - Filename can be a nested path [`#355`](https://github.com/form-data/form-data/pull/355) ### Commits - Bumped version number. [`d7398c3`](https://github.com/form-data/form-data/commit/d7398c3e7cd81ed12ecc0b84363721bae467db02) ## [v2.1.4](https://github.com/form-data/form-data/compare/2.1.3...v2.1.4) - 2017-04-08 ## [2.1.3](https://github.com/form-data/form-data/compare/v2.1.3...2.1.3) - 2017-04-08 ## [v2.1.3](https://github.com/form-data/form-data/compare/v2.1.2...v2.1.3) - 2017-04-08 ### Merged - toString should output '[object FormData]' [`#346`](https://github.com/form-data/form-data/pull/346) ## [v2.1.2](https://github.com/form-data/form-data/compare/v2.1.1...v2.1.2) - 2016-11-07 ### Merged - #271 Added check for self and window objects + tests [`#282`](https://github.com/form-data/form-data/pull/282) ### Commits - Added check for self and window objects + tests [`c99e4ec`](https://github.com/form-data/form-data/commit/c99e4ec32cd14d83776f2bdcc5a4e7384131c1b1) ## [v2.1.1](https://github.com/form-data/form-data/compare/v2.1.0...v2.1.1) - 2016-10-03 ### Merged - Bumped dependencies. [`#270`](https://github.com/form-data/form-data/pull/270) - Update browser.js shim to use self instead of window [`#267`](https://github.com/form-data/form-data/pull/267) - Boilerplate code rediction [`#265`](https://github.com/form-data/form-data/pull/265) - eslint@3.7.0 [`#266`](https://github.com/form-data/form-data/pull/266) ### Commits - code duplicates removed [`e9239fb`](https://github.com/form-data/form-data/commit/e9239fbe7d3c897b29fe3bde857d772469541c01) - Changed according to requests [`aa99246`](https://github.com/form-data/form-data/commit/aa9924626bd9168334d73fea568c0ad9d8fbaa96) - chore(package): update eslint to version 3.7.0 [`090a859`](https://github.com/form-data/form-data/commit/090a859835016cab0de49629140499e418db9c3a) ## [v2.1.0](https://github.com/form-data/form-data/compare/v2.0.0...v2.1.0) - 2016-09-25 ### Merged - Added `hasKnownLength` public method [`#263`](https://github.com/form-data/form-data/pull/263) ### Commits - Added hasKnownLength public method [`655b959`](https://github.com/form-data/form-data/commit/655b95988ef2ed3399f8796b29b2a8673c1df11c) ## [v2.0.0](https://github.com/form-data/form-data/compare/v1.0.0...v2.0.0) - 2016-09-16 ### Merged - Replaced async with asynckit [`#258`](https://github.com/form-data/form-data/pull/258) - Pre-release house cleaning [`#247`](https://github.com/form-data/form-data/pull/247) ### Commits - Replaced async with asynckit. Modernized [`1749b78`](https://github.com/form-data/form-data/commit/1749b78d50580fbd080e65c1eb9702ad4f4fc0c0) - Ignore .bak files [`c08190a`](https://github.com/form-data/form-data/commit/c08190a87d3e22a528b6e32b622193742a4c2672) - Trying to be more chatty. :) [`c79eabb`](https://github.com/form-data/form-data/commit/c79eabb24eaf761069255a44abf4f540cfd47d40) ## [v1.0.0](https://github.com/form-data/form-data/compare/v1.0.0-rc4...v1.0.0) - 2016-08-26 ### Merged - Allow custom header fields to be set as an object. [`#190`](https://github.com/form-data/form-data/pull/190) - v1.0.0-rc4 [`#182`](https://github.com/form-data/form-data/pull/182) - Avoid undefined variable reference in older browsers [`#176`](https://github.com/form-data/form-data/pull/176) - More housecleaning [`#164`](https://github.com/form-data/form-data/pull/164) - More cleanup [`#159`](https://github.com/form-data/form-data/pull/159) - Added windows testing. Some cleanup. [`#158`](https://github.com/form-data/form-data/pull/158) - Housecleaning. Added test coverage. [`#156`](https://github.com/form-data/form-data/pull/156) - Second iteration of cleanup. [`#145`](https://github.com/form-data/form-data/pull/145) ### Commits - Pre-release house cleaning [`440d72b`](https://github.com/form-data/form-data/commit/440d72b5fd44dd132f42598c3183d46e5f35ce71) - Updated deps, updated docs [`54b6114`](https://github.com/form-data/form-data/commit/54b61143e9ce66a656dd537a1e7b31319a4991be) - make docs up-to-date [`5e383d7`](https://github.com/form-data/form-data/commit/5e383d7f1466713f7fcef58a6817e0cb466c8ba7) - Added missing deps [`fe04862`](https://github.com/form-data/form-data/commit/fe04862000b2762245e2db69d5207696a08c1174) ## [v1.0.0-rc4](https://github.com/form-data/form-data/compare/v1.0.0-rc3...v1.0.0-rc4) - 2016-03-15 ### Merged - Housecleaning, preparing for the release [`#144`](https://github.com/form-data/form-data/pull/144) - lib: emit error when failing to get length [`#127`](https://github.com/form-data/form-data/pull/127) - Cleaning up for Codacity 2. [`#143`](https://github.com/form-data/form-data/pull/143) - Cleaned up codacity concerns. [`#142`](https://github.com/form-data/form-data/pull/142) - Should throw type error without new operator. [`#129`](https://github.com/form-data/form-data/pull/129) ### Commits - More cleanup [`94b6565`](https://github.com/form-data/form-data/commit/94b6565bb98a387335c72feff5ed5c10da0a7f6f) - Shuffling things around [`3c2f172`](https://github.com/form-data/form-data/commit/3c2f172eaddf0979b3eef5c73985d1a6fd3eee4a) - Second iteration of cleanup. [`347c88e`](https://github.com/form-data/form-data/commit/347c88ef9a99a66b9bcf4278497425db2f0182b2) - Housecleaning [`c335610`](https://github.com/form-data/form-data/commit/c3356100c054a4695e4dec8ed7072775cd745616) - More housecleaning [`f573321`](https://github.com/form-data/form-data/commit/f573321824aae37ba2052a92cc889d533d9f8fb8) - Trying to make far run on windows. + cleanup [`e426dfc`](https://github.com/form-data/form-data/commit/e426dfcefb07ee307d8a15dec04044cce62413e6) - Playing with appveyor [`c9458a7`](https://github.com/form-data/form-data/commit/c9458a7c328782b19859bc1745e7d6b2005ede86) - Updated dev dependencies. [`ceebe88`](https://github.com/form-data/form-data/commit/ceebe88872bb22da0a5a98daf384e3cc232928d3) - Replaced win-spawn with cross-spawn [`405a69e`](https://github.com/form-data/form-data/commit/405a69ee34e235ee6561b5ff0140b561be40d1cc) - Updated readme badges. [`12f282a`](https://github.com/form-data/form-data/commit/12f282a1310fcc2f70cc5669782283929c32a63d) - Making paths windows friendly. [`f4bddc5`](https://github.com/form-data/form-data/commit/f4bddc5955e2472f8e23c892c9b4d7a08fcb85a3) - [WIP] trying things for greater sanity [`8ad1f02`](https://github.com/form-data/form-data/commit/8ad1f02b0b3db4a0b00c5d6145ed69bcb7558213) - Bending under Codacy [`bfff3bb`](https://github.com/form-data/form-data/commit/bfff3bb36052dc83f429949b4e6f9b146a49d996) - Another attempt to make windows friendly [`f3eb628`](https://github.com/form-data/form-data/commit/f3eb628974ccb91ba0020f41df490207eeed77f6) - Updated dependencies. [`f73996e`](https://github.com/form-data/form-data/commit/f73996e0508ee2d4b2b376276adfac1de4188ac2) - Missed travis changes. [`67ee79f`](https://github.com/form-data/form-data/commit/67ee79f964fdabaf300bd41b0af0c1cfaca07687) - Restructured badges. [`48444a1`](https://github.com/form-data/form-data/commit/48444a1ff156ba2c2c3cfd11047c2f2fd92d4474) - Add similar type error as the browser for attempting to use form-data without new. [`5711320`](https://github.com/form-data/form-data/commit/5711320fb7c8cc620cfc79b24c7721526e23e539) - Took out codeclimate-test-reporter [`a7e0c65`](https://github.com/form-data/form-data/commit/a7e0c6522afe85ca9974b0b4e1fca9c77c3e52b1) - One more [`8e84cff`](https://github.com/form-data/form-data/commit/8e84cff3370526ecd3e175fd98e966242d81993c) ## [v1.0.0-rc3](https://github.com/form-data/form-data/compare/v1.0.0-rc2...v1.0.0-rc3) - 2015-07-29 ### Merged - House cleaning. Added `pre-commit`. [`#140`](https://github.com/form-data/form-data/pull/140) - Allow custom content-type without setting a filename. [`#138`](https://github.com/form-data/form-data/pull/138) - Add node-fetch to alternative submission methods. [`#132`](https://github.com/form-data/form-data/pull/132) - Update dependencies [`#130`](https://github.com/form-data/form-data/pull/130) - Switching to container based TravisCI [`#136`](https://github.com/form-data/form-data/pull/136) - Default content-type to 'application/octect-stream' [`#128`](https://github.com/form-data/form-data/pull/128) - Allow filename as third option of .append [`#125`](https://github.com/form-data/form-data/pull/125) ### Commits - Allow custom content-type without setting a filename [`c8a77cc`](https://github.com/form-data/form-data/commit/c8a77cc0cf16d15f1ebf25272beaab639ce89f76) - Fixed ranged test. [`a5ac58c`](https://github.com/form-data/form-data/commit/a5ac58cbafd0909f32fe8301998f689314fd4859) - Allow filename as third option of #append [`d081005`](https://github.com/form-data/form-data/commit/d0810058c84764b3c463a18b15ebb37864de9260) - Allow custom content-type without setting a filename [`8cb9709`](https://github.com/form-data/form-data/commit/8cb9709e5f1809cfde0cd707dbabf277138cd771) ## [v1.0.0-rc2](https://github.com/form-data/form-data/compare/v1.0.0-rc1...v1.0.0-rc2) - 2015-07-21 ### Merged - #109 Append proper line break [`#123`](https://github.com/form-data/form-data/pull/123) - Add shim for browser (browserify/webpack). [`#122`](https://github.com/form-data/form-data/pull/122) - Update license field [`#115`](https://github.com/form-data/form-data/pull/115) ### Commits - Add shim for browser. [`87c33f4`](https://github.com/form-data/form-data/commit/87c33f4269a2211938f80ab3e53835362b1afee8) - Bump version [`a3f5d88`](https://github.com/form-data/form-data/commit/a3f5d8872c810ce240c7d3838c69c3c9fcecc111) ## [v1.0.0-rc1](https://github.com/form-data/form-data/compare/0.2...v1.0.0-rc1) - 2015-06-13 ### Merged - v1.0.0-rc1 [`#114`](https://github.com/form-data/form-data/pull/114) - Updated test targets [`#102`](https://github.com/form-data/form-data/pull/102) - Remove duplicate plus sign [`#94`](https://github.com/form-data/form-data/pull/94) ### Commits - Made https test local. Updated deps. [`afe1959`](https://github.com/form-data/form-data/commit/afe1959ec711f23e57038ab5cb20fedd86271f29) - Proper self-signed ssl [`4d5ec50`](https://github.com/form-data/form-data/commit/4d5ec50e81109ad2addf3dbb56dc7c134df5ff87) - Update HTTPS handling for modern days [`2c11b01`](https://github.com/form-data/form-data/commit/2c11b01ce2c06e205c84d7154fa2f27b66c94f3b) - Made tests more local [`09633fa`](https://github.com/form-data/form-data/commit/09633fa249e7ce3ac581543aafe16ee9039a823b) - Auto create tmp folder for Formidable [`28714b7`](https://github.com/form-data/form-data/commit/28714b7f71ad556064cdff88fabe6b92bd407ddd) - remove duplicate plus sign [`36e09c6`](https://github.com/form-data/form-data/commit/36e09c695b0514d91a23f5cd64e6805404776fc7) ## [0.2](https://github.com/form-data/form-data/compare/0.1.4...0.2) - 2014-12-06 ### Merged - Bumped version [`#96`](https://github.com/form-data/form-data/pull/96) - Replace mime library. [`#95`](https://github.com/form-data/form-data/pull/95) - #71 Respect bytes range in a read stream. [`#73`](https://github.com/form-data/form-data/pull/73) ## [0.1.4](https://github.com/form-data/form-data/compare/0.1.3...0.1.4) - 2014-06-23 ### Merged - Updated version. [`#76`](https://github.com/form-data/form-data/pull/76) - #71 Respect bytes range in a read stream. [`#75`](https://github.com/form-data/form-data/pull/75) ## [0.1.3](https://github.com/form-data/form-data/compare/0.1.2...0.1.3) - 2014-06-17 ### Merged - Updated versions. [`#69`](https://github.com/form-data/form-data/pull/69) - Added custom headers support [`#60`](https://github.com/form-data/form-data/pull/60) - Added test for Request. Small fixes. [`#56`](https://github.com/form-data/form-data/pull/56) ### Commits - Added test for the custom header functionality [`bd50685`](https://github.com/form-data/form-data/commit/bd506855af62daf728ef1718cae88ed23bb732f3) - Documented custom headers option [`77a024a`](https://github.com/form-data/form-data/commit/77a024a9375f93c246c35513d80f37d5e11d35ff) - Removed 0.6 support. [`aee8dce`](https://github.com/form-data/form-data/commit/aee8dce604c595cfaacfc6efb12453d1691ac0d6) ## [0.1.2](https://github.com/form-data/form-data/compare/0.1.1...0.1.2) - 2013-10-02 ### Merged - Fixed default https port assignment, added tests. [`#52`](https://github.com/form-data/form-data/pull/52) - #45 Added tests for multi-submit. Updated readme. [`#49`](https://github.com/form-data/form-data/pull/49) - #47 return request from .submit() [`#48`](https://github.com/form-data/form-data/pull/48) ### Commits - Bumped version. [`2b761b2`](https://github.com/form-data/form-data/commit/2b761b256ae607fc2121621f12c2e1042be26baf) ## [0.1.1](https://github.com/form-data/form-data/compare/0.1.0...0.1.1) - 2013-08-21 ### Merged - Added license type and reference to package.json [`#46`](https://github.com/form-data/form-data/pull/46) ### Commits - #47 return request from .submit() [`1d61c2d`](https://github.com/form-data/form-data/commit/1d61c2da518bd5e136550faa3b5235bb540f1e06) - #47 Updated readme. [`e3dae15`](https://github.com/form-data/form-data/commit/e3dae1526bd3c3b9d7aff6075abdaac12c3cc60f) ## [0.1.0](https://github.com/form-data/form-data/compare/0.0.10...0.1.0) - 2013-07-08 ### Merged - Update master to 0.1.0 [`#44`](https://github.com/form-data/form-data/pull/44) - 0.1.0 - Added error handling. Streamlined edge cases behavior. [`#43`](https://github.com/form-data/form-data/pull/43) - Pointed badges back to mothership. [`#39`](https://github.com/form-data/form-data/pull/39) - Updated node-fake to support 0.11 tests. [`#37`](https://github.com/form-data/form-data/pull/37) - Updated tests to play nice with 0.10 [`#36`](https://github.com/form-data/form-data/pull/36) - #32 Added .npmignore [`#34`](https://github.com/form-data/form-data/pull/34) - Spring cleaning [`#30`](https://github.com/form-data/form-data/pull/30) ### Commits - Added error handling. Streamlined edge cases behavior. [`4da496e`](https://github.com/form-data/form-data/commit/4da496e577cb9bc0fd6c94cbf9333a0082ce353a) - Made tests more deterministic. [`7fc009b`](https://github.com/form-data/form-data/commit/7fc009b8a2cc9232514a44b2808b9f89ce68f7d2) - Fixed styling. [`d373b41`](https://github.com/form-data/form-data/commit/d373b417e779024bc3326073e176383cd08c0b18) - #40 Updated Readme.md regarding getLengthSync() [`efb373f`](https://github.com/form-data/form-data/commit/efb373fd63814d977960e0299d23c92cd876cfef) - Updated readme. [`527e3a6`](https://github.com/form-data/form-data/commit/527e3a63b032cb6f576f597ad7ff2ebcf8a0b9b4) ## [0.0.10](https://github.com/form-data/form-data/compare/0.0.9...0.0.10) - 2013-05-08 ### Commits - Updated tests to play nice with 0.10. [`932b39b`](https://github.com/form-data/form-data/commit/932b39b773e49edcb2c5d2e58fe389ab6c42f47c) - Added dependency tracking. [`3131d7f`](https://github.com/form-data/form-data/commit/3131d7f6996cd519d50547e4de1587fd80d0fa07) ## 0.0.9 - 2013-04-29 ### Merged - Custom params for form.submit() should cover most edge cases. [`#22`](https://github.com/form-data/form-data/pull/22) - Updated Readme and version number. [`#20`](https://github.com/form-data/form-data/pull/20) - Allow custom headers and pre-known length in parts [`#17`](https://github.com/form-data/form-data/pull/17) - Bumped version number. [`#12`](https://github.com/form-data/form-data/pull/12) - Fix for #10 [`#11`](https://github.com/form-data/form-data/pull/11) - Bumped version number. [`#8`](https://github.com/form-data/form-data/pull/8) - Added support for https destination, http-response and mikeal's request streams. [`#7`](https://github.com/form-data/form-data/pull/7) - Updated git url. [`#6`](https://github.com/form-data/form-data/pull/6) - Version bump. [`#5`](https://github.com/form-data/form-data/pull/5) - Changes to support custom content-type and getLengthSync. [`#4`](https://github.com/form-data/form-data/pull/4) - make .submit(url) use host from url, not 'localhost' [`#2`](https://github.com/form-data/form-data/pull/2) - Make package.json JSON [`#1`](https://github.com/form-data/form-data/pull/1) ### Fixed - Add MIT license [`#14`](https://github.com/form-data/form-data/issues/14) ### Commits - Spring cleaning. [`850ba1b`](https://github.com/form-data/form-data/commit/850ba1b649b6856b0fa87bbcb04bc70ece0137a6) - Added custom request params to form.submit(). Made tests more stable. [`de3502f`](https://github.com/form-data/form-data/commit/de3502f6c4a509f6ed12a7dd9dc2ce9c2e0a8d23) - Basic form (no files) working [`6ffdc34`](https://github.com/form-data/form-data/commit/6ffdc343e8594cfc2efe1e27653ea39d8980a14e) - Got initial test to pass [`9a59d08`](https://github.com/form-data/form-data/commit/9a59d08c024479fd3c9d99ba2f0893a47b3980f0) - Implement initial getLength [`9060c91`](https://github.com/form-data/form-data/commit/9060c91b861a6573b73beddd11e866db422b5830) - Make getLength work with file streams [`6f6b1e9`](https://github.com/form-data/form-data/commit/6f6b1e9b65951e6314167db33b446351702f5558) - Implemented a simplistic submit() function [`41e9cc1`](https://github.com/form-data/form-data/commit/41e9cc124124721e53bc1d1459d45db1410c44e6) - added test for custom headers and content-length in parts (felixge/node-form-data/17) [`b16d14e`](https://github.com/form-data/form-data/commit/b16d14e693670f5d52babec32cdedd1aa07c1aa4) - Fixed code styling. [`5847424`](https://github.com/form-data/form-data/commit/5847424c666970fc2060acd619e8a78678888a82) - #29 Added custom filename and content-type options to support identity-less streams. [`adf8b4a`](https://github.com/form-data/form-data/commit/adf8b4a41530795682cd3e35ffaf26b30288ccda) - Initial Readme and package.json [`8c744e5`](https://github.com/form-data/form-data/commit/8c744e58be4014bdf432e11b718ed87f03e217af) - allow append() to completely override header and boundary [`3fb2ad4`](https://github.com/form-data/form-data/commit/3fb2ad491f66e4b4ff16130be25b462820b8c972) - Syntax highlighting [`ab3a6a5`](https://github.com/form-data/form-data/commit/ab3a6a5ed1ab77a2943ce3befcb2bb3cd9ff0330) - Updated Readme.md [`de8f441`](https://github.com/form-data/form-data/commit/de8f44122ca754cbfedc0d2748e84add5ff0b669) - Added examples to Readme file. [`c406ac9`](https://github.com/form-data/form-data/commit/c406ac921d299cbc130464ed19338a9ef97cb650) - pass options.knownLength to set length at beginning, w/o waiting for async size calculation [`e2ac039`](https://github.com/form-data/form-data/commit/e2ac0397ff7c37c3dca74fa9925b55f832e4fa0b) - Updated dependencies and added test command. [`09bd7cd`](https://github.com/form-data/form-data/commit/09bd7cd86f1ad7a58df1b135eb6eef0d290894b4) - Bumped version. Updated readme. [`4581140`](https://github.com/form-data/form-data/commit/4581140f322758c6fc92019d342c7d7d6c94af5c) - Test runner [`1707ebb`](https://github.com/form-data/form-data/commit/1707ebbd180856e6ed44e80c46b02557e2425762) - Added .npmignore, bumped version. [`2e033e0`](https://github.com/form-data/form-data/commit/2e033e0e4be7c1457be090cd9b2996f19d8fb665) - FormData.prototype.append takes and passes along options (for header) [`b519203`](https://github.com/form-data/form-data/commit/b51920387ed4da7b4e106fc07b9459f26b5ae2f0) - Make package.json JSON [`bf1b58d`](https://github.com/form-data/form-data/commit/bf1b58df794b10fda86ed013eb9237b1e5032085) - Add dependencies to package.json [`7413d0b`](https://github.com/form-data/form-data/commit/7413d0b4cf5546312d47ea426db8180619083974) - Add convenient submit() interface [`55855e4`](https://github.com/form-data/form-data/commit/55855e4bea14585d4a3faf9e7318a56696adbc7d) - Fix content type [`08b6ae3`](https://github.com/form-data/form-data/commit/08b6ae337b23ef1ba457ead72c9b133047df213c) - Combatting travis rvm calls. [`409adfd`](https://github.com/form-data/form-data/commit/409adfd100a3cf4968a632c05ba58d92d262d144) - Fixed Issue #2 [`b3a5d66`](https://github.com/form-data/form-data/commit/b3a5d661739dcd6921b444b81d5cb3c32fab655d) - Fix for #10. [`bab70b9`](https://github.com/form-data/form-data/commit/bab70b9e803e17287632762073d227d6c59989e0) - Trying workarounds for formidable - 0.6 "love". [`25782a3`](https://github.com/form-data/form-data/commit/25782a3f183d9c30668ec2bca6247ed83f10611c) - change whitespace to conform with felixge's style guide [`9fa34f4`](https://github.com/form-data/form-data/commit/9fa34f433bece85ef73086a874c6f0164ab7f1f6) - Add async to deps [`b7d1a6b`](https://github.com/form-data/form-data/commit/b7d1a6b10ee74be831de24ed76843e5a6935f155) - typo [`7860a9c`](https://github.com/form-data/form-data/commit/7860a9c8a582f0745ce0e4a0549f4bffc29c0b50) - Bumped version. [`fa36c1b`](https://github.com/form-data/form-data/commit/fa36c1b4229c34b85d7efd41908429b6d1da3bfc) - Updated .gitignore [`de567bd`](https://github.com/form-data/form-data/commit/de567bde620e53b8e9b0ed3506e79491525ec558) - Don't rely on resume() being called by pipe [`1deae47`](https://github.com/form-data/form-data/commit/1deae47e042bcd170bd5dbe2b4a4fa5356bb8aa2) - One more wrong content type [`28f166d`](https://github.com/form-data/form-data/commit/28f166d443e2eb77f2559324014670674b97e46e) - Another typo [`b959b6a`](https://github.com/form-data/form-data/commit/b959b6a2be061cac17f8d329b89cea109f0f32be) - Typo [`698fa0a`](https://github.com/form-data/form-data/commit/698fa0aa5dbf4eeb77377415acc202a6fbe3f4a2) - Being simply dumb. [`b614db8`](https://github.com/form-data/form-data/commit/b614db85702061149fbd98418605106975e72ade) - Fixed typo in the filename. [`30af6be`](https://github.com/form-data/form-data/commit/30af6be13fb0c9e92b32e935317680b9d7599928) form-data-form-data-a661bf5/License000066400000000000000000000021361503610072100171520ustar00rootroot00000000000000Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. form-data-form-data-a661bf5/README.md000066400000000000000000000274021503610072100171270ustar00rootroot00000000000000# Form-Data [![NPM Module](https://img.shields.io/npm/v/form-data.svg)](https://www.npmjs.com/package/form-data) [![Join the chat at https://gitter.im/form-data/form-data](http://form-data.github.io/images/gitterbadge.svg)](https://gitter.im/form-data/form-data) A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications. The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd]. [xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface [![Linux Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=linux:6.x-12.x)](https://travis-ci.org/form-data/form-data) [![MacOS Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=macos:6.x-12.x)](https://travis-ci.org/form-data/form-data) [![Windows Build](https://img.shields.io/travis/form-data/form-data/master.svg?label=windows:6.x-12.x)](https://travis-ci.org/form-data/form-data) [![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/master.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master) [![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data) ## Install ``` npm install --save form-data ``` ## Usage In this example we are constructing a form with 3 fields that contain a string, a buffer and a file stream. ``` javascript var FormData = require('form-data'); var fs = require('fs'); var form = new FormData(); form.append('my_field', 'my value'); form.append('my_buffer', new Buffer(10)); form.append('my_file', fs.createReadStream('/foo/bar.jpg')); ``` Also you can use http-response stream: ``` javascript var FormData = require('form-data'); var http = require('http'); var form = new FormData(); http.request('http://nodejs.org/images/logo.png', function (response) { form.append('my_field', 'my value'); form.append('my_buffer', new Buffer(10)); form.append('my_logo', response); }); ``` Or @mikeal's [request](https://github.com/request/request) stream: ``` javascript var FormData = require('form-data'); var request = require('request'); var form = new FormData(); form.append('my_field', 'my value'); form.append('my_buffer', new Buffer(10)); form.append('my_logo', request('http://nodejs.org/images/logo.png')); ``` In order to submit this form to a web application, call ```submit(url, [callback])``` method: ``` javascript form.submit('http://example.org/', function (err, res) { // res – response object (http.IncomingMessage) // res.resume(); }); ``` For more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods. ### Custom options You can provide custom options, such as `maxDataSize`: ``` javascript var FormData = require('form-data'); var form = new FormData({ maxDataSize: 20971520 }); form.append('my_field', 'my value'); form.append('my_buffer', /* something big */); ``` List of available options could be found in [combined-stream](https://github.com/felixge/node-combined-stream/blob/master/lib/combined_stream.js#L7-L15) ### Alternative submission methods You can use node's http client interface: ``` javascript var http = require('http'); var request = http.request({ method: 'post', host: 'example.org', path: '/upload', headers: form.getHeaders() }); form.pipe(request); request.on('response', function (res) { console.log(res.statusCode); }); ``` Or if you would prefer the `'Content-Length'` header to be set for you: ``` javascript form.submit('example.org/upload', function (err, res) { console.log(res.statusCode); }); ``` To use custom headers and pre-known length in parts: ``` javascript var CRLF = '\r\n'; var form = new FormData(); var options = { header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF, knownLength: 1 }; form.append('my_buffer', buffer, options); form.submit('http://example.com/', function (err, res) { if (err) throw err; console.log('Done'); }); ``` Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually: ``` javascript someModule.stream(function (err, stdout, stderr) { if (err) throw err; var form = new FormData(); form.append('file', stdout, { filename: 'unicycle.jpg', // ... or: filepath: 'photos/toys/unicycle.jpg', contentType: 'image/jpeg', knownLength: 19806 }); form.submit('http://example.com/', function (err, res) { if (err) throw err; console.log('Done'); }); }); ``` The `filepath` property overrides `filename` and may contain a relative path. This is typically used when uploading [multiple files from a directory](https://wicg.github.io/entries-api/#dom-htmlinputelement-webkitdirectory). For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter: ``` javascript form.submit({ host: 'example.com', path: '/probably.php?extra=params', auth: 'username:password' }, function (err, res) { console.log(res.statusCode); }); ``` In case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`: ``` javascript form.submit({ host: 'example.com', path: '/surelynot.php', headers: { 'x-test-header': 'test-header-value' } }, function (err, res) { console.log(res.statusCode); }); ``` ### Methods - [_Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] )](https://github.com/form-data/form-data#void-append-string-field-mixed-value--mixed-options-). - [_Headers_ getHeaders( [**Headers** _userHeaders_] )](https://github.com/form-data/form-data#array-getheaders-array-userheaders-) - [_String_ getBoundary()](https://github.com/form-data/form-data#string-getboundary) - [_Void_ setBoundary()](https://github.com/form-data/form-data#void-setboundary) - [_Buffer_ getBuffer()](https://github.com/form-data/form-data#buffer-getbuffer) - [_Integer_ getLengthSync()](https://github.com/form-data/form-data#integer-getlengthsync) - [_Integer_ getLength( **function** _callback_ )](https://github.com/form-data/form-data#integer-getlength-function-callback-) - [_Boolean_ hasKnownLength()](https://github.com/form-data/form-data#boolean-hasknownlength) - [_Request_ submit( _params_, **function** _callback_ )](https://github.com/form-data/form-data#request-submit-params-function-callback-) - [_String_ toString()](https://github.com/form-data/form-data#string-tostring) #### _Void_ append( **String** _field_, **Mixed** _value_ [, **Mixed** _options_] ) Append data to the form. You can submit about any format (string, integer, boolean, buffer, etc.). However, Arrays are not supported and need to be turned into strings by the user. ```javascript var form = new FormData(); form.append('my_string', 'my value'); form.append('my_integer', 1); form.append('my_boolean', true); form.append('my_buffer', new Buffer(10)); form.append('my_array_as_json', JSON.stringify(['bird', 'cute'])); ``` You may provide a string for options, or an object. ```javascript // Set filename by providing a string for options form.append('my_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg'); // provide an object. form.append('my_file', fs.createReadStream('/foo/bar.jpg'), { filename: 'bar.jpg', contentType: 'image/jpeg', knownLength: 19806 }); ``` #### _Headers_ getHeaders( [**Headers** _userHeaders_] ) This method adds the correct `content-type` header to the provided array of `userHeaders`. #### _String_ getBoundary() Return the boundary of the formData. By default, the boundary consists of 26 `-` followed by 24 numbers for example: ```javascript --------------------------515890814546601021194782 ``` #### _Void_ setBoundary(String _boundary_) Set the boundary string, overriding the default behavior described above. _Note: The boundary must be unique and may not appear in the data._ #### _Buffer_ getBuffer() Return the full formdata request package, as a Buffer. You can insert this Buffer in e.g. Axios to send multipart data. ```javascript var form = new FormData(); form.append('my_buffer', Buffer.from([0x4a,0x42,0x20,0x52,0x6f,0x63,0x6b,0x73])); form.append('my_file', fs.readFileSync('/foo/bar.jpg')); axios.post('https://example.com/path/to/api', form.getBuffer(), form.getHeaders()); ``` **Note:** Because the output is of type Buffer, you can only append types that are accepted by Buffer: *string, Buffer, ArrayBuffer, Array, or Array-like Object*. A ReadStream for example will result in an error. #### _Integer_ getLengthSync() Same as `getLength` but synchronous. _Note: getLengthSync __doesn't__ calculate streams length._ #### _Integer_ getLength(**function** _callback_ ) Returns the `Content-Length` async. The callback is used to handle errors and continue once the length has been calculated ```javascript this.getLength(function (err, length) { if (err) { this._error(err); return; } // add content length request.setHeader('Content-Length', length); ... }.bind(this)); ``` #### _Boolean_ hasKnownLength() Checks if the length of added values is known. #### _Request_ submit(_params_, **function** _callback_ ) Submit the form to a web application. ```javascript var form = new FormData(); form.append('my_string', 'Hello World'); form.submit('http://example.com/', function (err, res) { // res – response object (http.IncomingMessage) // res.resume(); } ); ``` #### _String_ toString() Returns the form data as a string. Don't use this if you are sending files or buffers, use `getBuffer()` instead. ### Integration with other libraries #### Request Form submission using [request](https://github.com/request/request): ```javascript var formData = { my_field: 'my_value', my_file: fs.createReadStream(__dirname + '/unicycle.jpg'), }; request.post({url:'http://service.com/upload', formData: formData}, function (err, httpResponse, body) { if (err) { return console.error('upload failed:', err); } console.log('Upload successful! Server responded with:', body); }); ``` For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads). #### node-fetch You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch): ```javascript var form = new FormData(); form.append('a', 1); fetch('http://example.com', { method: 'POST', body: form }) .then(function (res) { return res.json(); }).then(function (json) { console.log(json); }); ``` #### axios In Node.js you can post a file using [axios](https://github.com/axios/axios): ```javascript const form = new FormData(); const stream = fs.createReadStream(PATH_TO_FILE); form.append('image', stream); // In Node.js environment you need to set boundary in the header field 'Content-Type' by calling method `getHeaders` const formHeaders = form.getHeaders(); axios.post('http://example.com', form, { headers: { ...formHeaders, }, }) .then(response => response) .catch(error => error) ``` ## Notes - ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround. - ```getLength(cb)``` will send an error as first parameter of callback if stream length cannot be calculated (e.g. send in custom streams w/o using ```knownLength```). - ```submit``` will not add `content-length` if form length is unknown or not calculable. - Starting version `2.x` FormData has dropped support for `node@0.10.x`. - Starting version `3.x` FormData has dropped support for `node@4.x`. ## License Form-Data is released under the [MIT](License) license. form-data-form-data-a661bf5/index.d.ts000066400000000000000000000034411503610072100175460ustar00rootroot00000000000000// Definitions by: Carlos Ballesteros Velasco // Leon Yu // BendingBender // Maple Miao /// import * as stream from 'stream'; import * as http from 'http'; export = FormData; // Extracted because @types/node doesn't export interfaces. interface ReadableOptions { highWaterMark?: number; encoding?: string; objectMode?: boolean; read?(this: stream.Readable, size: number): void; destroy?(this: stream.Readable, error: Error | null, callback: (error: Error | null) => void): void; autoDestroy?: boolean; } interface Options extends ReadableOptions { writable?: boolean; readable?: boolean; dataSize?: number; maxDataSize?: number; pauseStreams?: boolean; } declare class FormData extends stream.Readable { constructor(options?: Options); append(key: string, value: any, options?: FormData.AppendOptions | string): void; getHeaders(userHeaders?: FormData.Headers): FormData.Headers; submit( params: string | FormData.SubmitOptions, callback?: (error: Error | null, response: http.IncomingMessage) => void ): http.ClientRequest; getBuffer(): Buffer; setBoundary(boundary: string): void; getBoundary(): string; getLength(callback: (err: Error | null, length: number) => void): void; getLengthSync(): number; hasKnownLength(): boolean; } declare namespace FormData { interface Headers { [key: string]: any; } interface AppendOptions { header?: string | Headers; knownLength?: number; filename?: string; filepath?: string; contentType?: string; } interface SubmitOptions extends http.RequestOptions { protocol?: 'https:' | 'http:'; } } form-data-form-data-a661bf5/lib/000077500000000000000000000000001503610072100164115ustar00rootroot00000000000000form-data-form-data-a661bf5/lib/browser.js000066400000000000000000000001651503610072100204340ustar00rootroot00000000000000'use strict'; /* eslint-env browser */ module.exports = typeof self === 'object' ? self.FormData : window.FormData; form-data-form-data-a661bf5/lib/form_data.js000066400000000000000000000344161503610072100207130ustar00rootroot00000000000000'use strict'; var CombinedStream = require('combined-stream'); var util = require('util'); var path = require('path'); var http = require('http'); var https = require('https'); var parseUrl = require('url').parse; var fs = require('fs'); var Stream = require('stream').Stream; var crypto = require('crypto'); var mime = require('mime-types'); var asynckit = require('asynckit'); var setToStringTag = require('es-set-tostringtag'); var hasOwn = require('hasown'); var populate = require('./populate.js'); /** * Create readable "multipart/form-data" streams. * Can be used to submit forms * and file uploads to other web applications. * * @constructor * @param {object} options - Properties to be added/overriden for FormData and CombinedStream */ function FormData(options) { if (!(this instanceof FormData)) { return new FormData(options); } this._overheadLength = 0; this._valueLength = 0; this._valuesToMeasure = []; CombinedStream.call(this); options = options || {}; // eslint-disable-line no-param-reassign for (var option in options) { // eslint-disable-line no-restricted-syntax this[option] = options[option]; } } // make it a Stream util.inherits(FormData, CombinedStream); FormData.LINE_BREAK = '\r\n'; FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream'; FormData.prototype.append = function (field, value, options) { options = options || {}; // eslint-disable-line no-param-reassign // allow filename as single option if (typeof options === 'string') { options = { filename: options }; // eslint-disable-line no-param-reassign } var append = CombinedStream.prototype.append.bind(this); // all that streamy business can't handle numbers if (typeof value === 'number' || value == null) { value = String(value); // eslint-disable-line no-param-reassign } // https://github.com/felixge/node-form-data/issues/38 if (Array.isArray(value)) { /* * Please convert your array into string * the way web server expects it */ this._error(new Error('Arrays are not supported.')); return; } var header = this._multiPartHeader(field, value, options); var footer = this._multiPartFooter(); append(header); append(value); append(footer); // pass along options.knownLength this._trackLength(header, value, options); }; FormData.prototype._trackLength = function (header, value, options) { var valueLength = 0; /* * used w/ getLengthSync(), when length is known. * e.g. for streaming directly from a remote server, * w/ a known file a size, and not wanting to wait for * incoming file to finish to get its size. */ if (options.knownLength != null) { valueLength += Number(options.knownLength); } else if (Buffer.isBuffer(value)) { valueLength = value.length; } else if (typeof value === 'string') { valueLength = Buffer.byteLength(value); } this._valueLength += valueLength; // @check why add CRLF? does this account for custom/multiple CRLFs? this._overheadLength += Buffer.byteLength(header) + FormData.LINE_BREAK.length; // empty or either doesn't have path or not an http response or not a stream if (!value || (!value.path && !(value.readable && hasOwn(value, 'httpVersion')) && !(value instanceof Stream))) { return; } // no need to bother with the length if (!options.knownLength) { this._valuesToMeasure.push(value); } }; FormData.prototype._lengthRetriever = function (value, callback) { if (hasOwn(value, 'fd')) { // take read range into a account // `end` = Infinity –> read file till the end // // TODO: Looks like there is bug in Node fs.createReadStream // it doesn't respect `end` options without `start` options // Fix it when node fixes it. // https://github.com/joyent/node/issues/7819 if (value.end != undefined && value.end != Infinity && value.start != undefined) { // when end specified // no need to calculate range // inclusive, starts with 0 callback(null, value.end + 1 - (value.start ? value.start : 0)); // eslint-disable-line callback-return // not that fast snoopy } else { // still need to fetch file size from fs fs.stat(value.path, function (err, stat) { if (err) { callback(err); return; } // update final size based on the range options var fileSize = stat.size - (value.start ? value.start : 0); callback(null, fileSize); }); } // or http response } else if (hasOwn(value, 'httpVersion')) { callback(null, Number(value.headers['content-length'])); // eslint-disable-line callback-return // or request stream http://github.com/mikeal/request } else if (hasOwn(value, 'httpModule')) { // wait till response come back value.on('response', function (response) { value.pause(); callback(null, Number(response.headers['content-length'])); }); value.resume(); // something else } else { callback('Unknown stream'); // eslint-disable-line callback-return } }; FormData.prototype._multiPartHeader = function (field, value, options) { /* * custom header specified (as string)? * it becomes responsible for boundary * (e.g. to handle extra CRLFs on .NET servers) */ if (typeof options.header === 'string') { return options.header; } var contentDisposition = this._getContentDisposition(value, options); var contentType = this._getContentType(value, options); var contents = ''; var headers = { // add custom disposition as third element or keep it two elements if not 'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []), // if no content type. allow it to be empty array 'Content-Type': [].concat(contentType || []) }; // allow custom headers. if (typeof options.header === 'object') { populate(headers, options.header); } var header; for (var prop in headers) { // eslint-disable-line no-restricted-syntax if (hasOwn(headers, prop)) { header = headers[prop]; // skip nullish headers. if (header == null) { continue; // eslint-disable-line no-restricted-syntax, no-continue } // convert all headers to arrays. if (!Array.isArray(header)) { header = [header]; } // add non-empty headers. if (header.length) { contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK; } } } return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK; }; FormData.prototype._getContentDisposition = function (value, options) { // eslint-disable-line consistent-return var filename; if (typeof options.filepath === 'string') { // custom filepath for relative paths filename = path.normalize(options.filepath).replace(/\\/g, '/'); } else if (options.filename || (value && (value.name || value.path))) { /* * custom filename take precedence * formidable and the browser add a name property * fs- and request- streams have path property */ filename = path.basename(options.filename || (value && (value.name || value.path))); } else if (value && value.readable && hasOwn(value, 'httpVersion')) { // or try http response filename = path.basename(value.client._httpMessage.path || ''); } if (filename) { return 'filename="' + filename + '"'; } }; FormData.prototype._getContentType = function (value, options) { // use custom content-type above all var contentType = options.contentType; // or try `name` from formidable, browser if (!contentType && value && value.name) { contentType = mime.lookup(value.name); } // or try `path` from fs-, request- streams if (!contentType && value && value.path) { contentType = mime.lookup(value.path); } // or if it's http-reponse if (!contentType && value && value.readable && hasOwn(value, 'httpVersion')) { contentType = value.headers['content-type']; } // or guess it from the filepath or filename if (!contentType && (options.filepath || options.filename)) { contentType = mime.lookup(options.filepath || options.filename); } // fallback to the default content type if `value` is not simple value if (!contentType && value && typeof value === 'object') { contentType = FormData.DEFAULT_CONTENT_TYPE; } return contentType; }; FormData.prototype._multiPartFooter = function () { return function (next) { var footer = FormData.LINE_BREAK; var lastPart = this._streams.length === 0; if (lastPart) { footer += this._lastBoundary(); } next(footer); }.bind(this); }; FormData.prototype._lastBoundary = function () { return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK; }; FormData.prototype.getHeaders = function (userHeaders) { var header; var formHeaders = { 'content-type': 'multipart/form-data; boundary=' + this.getBoundary() }; for (header in userHeaders) { // eslint-disable-line no-restricted-syntax if (hasOwn(userHeaders, header)) { formHeaders[header.toLowerCase()] = userHeaders[header]; } } return formHeaders; }; FormData.prototype.setBoundary = function (boundary) { if (typeof boundary !== 'string') { throw new TypeError('FormData boundary must be a string'); } this._boundary = boundary; }; FormData.prototype.getBoundary = function () { if (!this._boundary) { this._generateBoundary(); } return this._boundary; }; FormData.prototype.getBuffer = function () { var dataBuffer = new Buffer.alloc(0); // eslint-disable-line new-cap var boundary = this.getBoundary(); // Create the form content. Add Line breaks to the end of data. for (var i = 0, len = this._streams.length; i < len; i++) { if (typeof this._streams[i] !== 'function') { // Add content to the buffer. if (Buffer.isBuffer(this._streams[i])) { dataBuffer = Buffer.concat([dataBuffer, this._streams[i]]); } else { dataBuffer = Buffer.concat([dataBuffer, Buffer.from(this._streams[i])]); } // Add break after content. if (typeof this._streams[i] !== 'string' || this._streams[i].substring(2, boundary.length + 2) !== boundary) { dataBuffer = Buffer.concat([dataBuffer, Buffer.from(FormData.LINE_BREAK)]); } } } // Add the footer and return the Buffer object. return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]); }; FormData.prototype._generateBoundary = function () { // This generates a 50 character boundary similar to those used by Firefox. // They are optimized for boyer-moore parsing. this._boundary = '--------------------------' + crypto.randomBytes(12).toString('hex'); }; // Note: getLengthSync DOESN'T calculate streams length // As workaround one can calculate file size manually and add it as knownLength option FormData.prototype.getLengthSync = function () { var knownLength = this._overheadLength + this._valueLength; // Don't get confused, there are 3 "internal" streams for each keyval pair so it basically checks if there is any value added to the form if (this._streams.length) { knownLength += this._lastBoundary().length; } // https://github.com/form-data/form-data/issues/40 if (!this.hasKnownLength()) { /* * Some async length retrievers are present * therefore synchronous length calculation is false. * Please use getLength(callback) to get proper length */ this._error(new Error('Cannot calculate proper length in synchronous way.')); } return knownLength; }; // Public API to check if length of added values is known // https://github.com/form-data/form-data/issues/196 // https://github.com/form-data/form-data/issues/262 FormData.prototype.hasKnownLength = function () { var hasKnownLength = true; if (this._valuesToMeasure.length) { hasKnownLength = false; } return hasKnownLength; }; FormData.prototype.getLength = function (cb) { var knownLength = this._overheadLength + this._valueLength; if (this._streams.length) { knownLength += this._lastBoundary().length; } if (!this._valuesToMeasure.length) { process.nextTick(cb.bind(this, null, knownLength)); return; } asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function (err, values) { if (err) { cb(err); return; } values.forEach(function (length) { knownLength += length; }); cb(null, knownLength); }); }; FormData.prototype.submit = function (params, cb) { var request; var options; var defaults = { method: 'post' }; // parse provided url if it's string or treat it as options object if (typeof params === 'string') { params = parseUrl(params); // eslint-disable-line no-param-reassign /* eslint sort-keys: 0 */ options = populate({ port: params.port, path: params.pathname, host: params.hostname, protocol: params.protocol }, defaults); } else { // use custom params options = populate(params, defaults); // if no port provided use default one if (!options.port) { options.port = options.protocol === 'https:' ? 443 : 80; } } // put that good code in getHeaders to some use options.headers = this.getHeaders(params.headers); // https if specified, fallback to http in any other case if (options.protocol === 'https:') { request = https.request(options); } else { request = http.request(options); } // get content length and fire away this.getLength(function (err, length) { if (err && err !== 'Unknown stream') { this._error(err); return; } // add content length if (length) { request.setHeader('Content-Length', length); } this.pipe(request); if (cb) { var onResponse; var callback = function (error, responce) { request.removeListener('error', callback); request.removeListener('response', onResponse); return cb.call(this, error, responce); // eslint-disable-line no-invalid-this }; onResponse = callback.bind(this, null); request.on('error', callback); request.on('response', onResponse); } }.bind(this)); return request; }; FormData.prototype._error = function (err) { if (!this.error) { this.error = err; this.pause(); this.emit('error', err); } }; FormData.prototype.toString = function () { return '[object FormData]'; }; setToStringTag(FormData, 'FormData'); // Public API module.exports = FormData; form-data-form-data-a661bf5/lib/populate.js000066400000000000000000000003501503610072100205760ustar00rootroot00000000000000'use strict'; // populates missing values module.exports = function (dst, src) { Object.keys(src).forEach(function (prop) { dst[prop] = dst[prop] || src[prop]; // eslint-disable-line no-param-reassign }); return dst; }; form-data-form-data-a661bf5/package.json000066400000000000000000000056761503610072100201470ustar00rootroot00000000000000{ "author": "Felix Geisendörfer (http://debuggable.com/)", "name": "form-data", "description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.", "version": "4.0.4", "repository": { "type": "git", "url": "git://github.com/form-data/form-data.git" }, "main": "./lib/form_data", "browser": "./lib/browser", "typings": "./index.d.ts", "scripts": { "pretest": "npm run lint", "pretests-only": "rimraf coverage test/tmp", "tests-only": "istanbul cover test/run.js", "posttests-only": "istanbul report lcov text", "test": "npm run tests-only", "posttest": "npx npm@'>=10.2' audit --production", "lint": "eslint --ext=js,mjs .", "report": "istanbul report lcov text", "ci-lint": "is-node-modern 8 && npm run lint || is-node-not-modern 8", "ci-test": "npm run tests-only && npm run browser && npm run report", "predebug": "rimraf coverage test/tmp", "debug": "verbose=1 ./test/run.js", "browser": "browserify -t browserify-istanbul test/run-browser.js | obake --coverage", "check": "istanbul check-coverage coverage/coverage*.json", "files": "pkgfiles --sort=name", "get-version": "node -e \"console.log(require('./package.json').version)\"", "update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md", "postupdate-readme": "mv README.md.bak READ.ME.md.bak", "restore-readme": "mv READ.ME.md.bak README.md", "prepublish": "not-in-publish || npm run prepublishOnly", "prepack": "npm run update-readme", "postpack": "npm run restore-readme", "version": "auto-changelog && git add CHANGELOG.md", "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\"" }, "engines": { "node": ">= 6" }, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" }, "devDependencies": { "@ljharb/eslint-config": "^21.2.0", "auto-changelog": "^2.5.0", "browserify": "^13.3.0", "browserify-istanbul": "^2.0.0", "coveralls": "^3.1.1", "cross-spawn": "^6.0.6", "eslint": "=8.8.0", "fake": "^0.2.2", "far": "^0.0.7", "formidable": "^1.2.6", "in-publish": "^2.0.1", "is-node-modern": "^1.0.0", "istanbul": "^0.4.5", "obake": "^0.1.2", "pkgfiles": "^2.3.2", "pre-commit": "^1.2.2", "predict-v8-randomness": "^1.0.35", "puppeteer": "^1.20.0", "request": "~2.87.0", "rimraf": "^2.7.1", "semver": "^6.3.1", "tape": "^5.9.0" }, "license": "MIT", "auto-changelog": { "output": "CHANGELOG.md", "template": "keepachangelog", "unreleased": false, "commitLimit": false, "backfillLimit": false, "hideCredit": true } } form-data-form-data-a661bf5/test/000077500000000000000000000000001503610072100166225ustar00rootroot00000000000000form-data-form-data-a661bf5/test/common.js000066400000000000000000000064671503610072100204650ustar00rootroot00000000000000var fs = require('fs'); var path = require('path'); var assert = require('assert'); var fake = require('fake'); var mime = require('mime-types'); var http = require('http'); var IncomingForm = require('formidable').IncomingForm; var hasOwn = require('hasown'); var common = module.exports; var rootDir = path.join(__dirname, '..'); common.dir = { lib: path.join(rootDir, '/lib'), fixture: path.join(rootDir, '/test/fixture'), tmp: path.join(rootDir, '/test/tmp') }; common.defaultTypeValue = function () { return new Buffer([1, 2, 3]); }; common.assert = assert; common.fake = fake; common.port = 8432; common.staticPort = 9432; common.httpsPort = 9443; // store server cert in common for later reuse, because self-signed common.httpsServerKey = fs.readFileSync(path.join(__dirname, './fixture/key.pem')); common.httpsServerCert = fs.readFileSync(path.join(__dirname, './fixture/cert.pem')); common.testFields = function (FIELDS, callback) { var fieldsPassed = Object.keys(FIELDS).length; return http.createServer(function (req, res) { var incomingForm = new IncomingForm({ uploadDir: common.dir.tmp }); incomingForm.parse(req); common.actions.checkForm(incomingForm, FIELDS, function (fieldsChecked) { // keep track of number of the processed fields callback(fieldsPassed - fieldsChecked); // eslint-disable-line callback-return // finish it common.actions.formOnEnd(res); }); }); }; // Actions common.actions = {}; // generic form field population common.actions.populateFields = function (form, fields) { var field; for (var name in fields) { // eslint-disable-line no-restricted-syntax if (hasOwn(fields, name)) { field = fields[name]; // important to append ReadStreams within the same tick if (typeof field.value == 'function') { field.value = field.value(); } form.append(name, field.value); } } }; // generic form submit common.actions.submit = function (form, server) { return form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); // unstuck new streams res.resume(); server.close(); }); }; common.actions.checkForm = function (form, fields, callback) { var fieldChecked = 0; form .on('field', function (name, value) { fieldChecked++; common.actions.formOnField(fields, name, value); }) .on('file', function (name, file) { fieldChecked++; common.actions.formOnFile(fields, name, file); }) .on('end', function () { callback(fieldChecked); }); }; common.actions.basicFormOnField = function (name, value) { assert.strictEqual(name, 'my_field'); assert.strictEqual(value, 'my_value'); }; common.actions.formOnField = function (FIELDS, name, value) { assert.ok(name in FIELDS); var field = FIELDS[name]; assert.strictEqual(value, String(field.value)); }; common.actions.formOnFile = function (FIELDS, name, file) { assert.ok(name in FIELDS); var field = FIELDS[name]; assert.strictEqual(file.name, path.basename(field.value.path || field.name)); assert.strictEqual(file.type, field.type ? field.type : mime.lookup(file.name)); }; // after form has finished parsing common.actions.formOnEnd = function (res) { res.writeHead(200); res.end('done'); }; form-data-form-data-a661bf5/test/fixture/000077500000000000000000000000001503610072100203105ustar00rootroot00000000000000form-data-form-data-a661bf5/test/fixture/cert.pem000066400000000000000000000036601503610072100217550ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIFfzCCA2egAwIBAgIJALeHtgIY/UKcMA0GCSqGSIb3DQEBCwUAMFUxCzAJBgNV BAYTAk5MMQswCQYDVQQIDAJPVjESMBAGA1UEBwwJUGFsbyBBbHRvMREwDwYDVQQK DAhGb3JtRGF0YTESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE5MDMyMDExNTI1NVoY DzIwNTkwMzEwMTE1MjU1WjBVMQswCQYDVQQGEwJOTDELMAkGA1UECAwCT1YxEjAQ BgNVBAcMCVBhbG8gQWx0bzERMA8GA1UECgwIRm9ybURhdGExEjAQBgNVBAMMCWxv Y2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALHtx1z8nZIr kQo8UbeLxv+S38xHwYSSCHzJBAXGx6PMTFcXdvDvvFrbf772/Gq76tfWtthao+nu 0n14aWepVSucltRUpfwTXau5knoN5J9EL+FbLwfFIUGLEdjnky7UOdtFLN2SYM0B O5/+Nk+ywtBMzXMXHb0sJ0lrNPM8AOD57sIJ/KcqjG33bCgx0GLxuLmLwNupvDNp p3lIvghgTKIOWRKyVOGPpM25DNvI8OT+ldj0KV7y3xJPtNdMcu0bZ+fapJSb48UN koiQb8jxRnl295MAb82piohsLeZE0HGpwT/CWwvUxqgBahDJDmYVBaK9JVEvcMiz wt+wy+xHd9TrgyfrHmBuHKWpgQPbumfWh2OzEeyF1N9dbAbgQ7Tmo/L6zz576Q2x 7Ee5tuyX1apEEpXM5fHxMcM04kHuyz3wqUe4U//LOPmoJ4oAUpkMC/8QMluAFK4i 1yZAw1kB0B4UbLkTIqJYvI3uEzzWe4Q33kVn1AyNBOLXw79t4ZFfhEf6oU0Zjyqp OBNs81imLtgQU4L+D1Rt6aIL8BMhpSM9dGG2ujXqwhZnqtgVuSMY8gI7N+Hjg433 hdxbvpzl0HjnruWvoXDKOWv08sYJhtMqclRQRGDSmxdwps+f5Iocap9AN2wfDmeO cHJohZyw+8l/L2MAp19xJGfN2wRsVrOrAgMBAAGjUDBOMB0GA1UdDgQWBBR+hImn BxHZ03bONEdB6JPPyo0kGDAfBgNVHSMEGDAWgBR+hImnBxHZ03bONEdB6JPPyo0k GDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAhpfrm79WQuMbudbIz pOjp26OO51cM4CKzH2vUXdgzjNEDHL2JwN0MiLHK0vwT5SkH1uoHRvECHIG8FHrA t9ky7W0Xw4vza9pC5GJEcCHVFGEaPJVXA7+fg5JCjejeWV1PU1LsMLBibbikVFUN JXTbKLL1EWbDLSX4ICJEyc3fptYB/w/lpDZqiKF2uIm2LSubo+fRg3D1mCexsXv1 nl2g9eZkx6uhUl7yq8o5lB6Ejzr1t5npA8w0RlYpvMwagqSfblM7UgvcrEW6Cusl ICELrCY/mfZwKvTgIRrj4Te19ARgXwkrG0KxcgDb+UCBaIca79t53AbpHVVrVPh6 hXHOQrRMjf0taFILPJYn6RcC08zx7FCet4x5WqX4900yRZX7Lr0VLDZI8/c1gf0j PsTA9JqARiQG8qeM5abLxSiXGPypYNkBlbf9H8WDpJgxRNK9RszogNhKdPkYzv0b HgHrAOels9u3roR+wNVIy2PX+LFeSnfUCJjJZEeqs5ewpP9vgBxVIzszO2lZu1oq uUEoFRPnIDA3TsYLzjw9MNMH0CeKUv+83QX7C9UuSyNdKZIgq2z/ABclgBtyFDSX 6EAL5WP55CCCiIG93A0y84rALIS7mPVBzVnxzRY96M2Ifs8GCwMi2Q5ykcVIPkyR HVi0h+PsbIWC9+H9Ljl2vgu0cw== -----END CERTIFICATE----- form-data-form-data-a661bf5/test/fixture/key.pem000066400000000000000000000062531503610072100216110ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIIJKQIBAAKCAgEAse3HXPydkiuRCjxRt4vG/5LfzEfBhJIIfMkEBcbHo8xMVxd2 8O+8Wtt/vvb8arvq19a22Fqj6e7SfXhpZ6lVK5yW1FSl/BNdq7mSeg3kn0Qv4Vsv B8UhQYsR2OeTLtQ520Us3ZJgzQE7n/42T7LC0EzNcxcdvSwnSWs08zwA4Pnuwgn8 pyqMbfdsKDHQYvG4uYvA26m8M2mneUi+CGBMog5ZErJU4Y+kzbkM28jw5P6V2PQp XvLfEk+010xy7Rtn59qklJvjxQ2SiJBvyPFGeXb3kwBvzamKiGwt5kTQcanBP8Jb C9TGqAFqEMkOZhUFor0lUS9wyLPC37DL7Ed31OuDJ+seYG4cpamBA9u6Z9aHY7MR 7IXU311sBuBDtOaj8vrPPnvpDbHsR7m27JfVqkQSlczl8fExwzTiQe7LPfCpR7hT /8s4+agnigBSmQwL/xAyW4AUriLXJkDDWQHQHhRsuRMioli8je4TPNZ7hDfeRWfU DI0E4tfDv23hkV+ER/qhTRmPKqk4E2zzWKYu2BBTgv4PVG3pogvwEyGlIz10Yba6 NerCFmeq2BW5IxjyAjs34eODjfeF3Fu+nOXQeOeu5a+hcMo5a/TyxgmG0ypyVFBE YNKbF3Cmz5/kihxqn0A3bB8OZ45wcmiFnLD7yX8vYwCnX3EkZ83bBGxWs6sCAwEA AQKCAgEApJk2K9RZpEX/V/uzENwSzI0/0Ye0AwLhLSb8PKfGOcYd/Rds5bixg0+5 Xpy3p7mNp/wui/lV12widwX0ZHwmmUCz21svbgEwT1NNqPG/RILc1Fn5KPP5LtwL N6AK7XBQ0YKt3Y+zUxLH6NtPvOy/Adl62fRRg5YcBfRSOI2Sto0fjYuVmcNnw7b2 7Dwg7dd1rtgVImBkBR/BWRatDaygV+50AjLNCRlMOS/uMEg0aXMGhnxg5UBCknr/ 7YgAbU5EEh2W0Q9hZwKGQyVy8+4X5vfiUbA+vYAQ8uE4mOOh/PQwHN6cQVamK/ea +ko0ssTRwNm/ctozOMfrB+pSy5LVy6rePVKRWnvI+6w5HZgcGXVFegL8Tcky/SBd LNUBKI1LTPDFgxTfMU+QaAt6ABa5xG7sfG9E2EyDIctKX3oNwqARUSIxAlTNFXin IcsX2mjWvc0u1ps17eHyboYhG3JP3/cHL6avTU5u3kbX8I7gb+ioPke2eqm/G/JM kRQ7pRvB1L83x2TrIWlXLZ49r4oMACDBvP4G4reYM/ExPsc6Xnwl+qyuFiyo/ENW NbdS/v6k+Cn6+kIAD/0K3S5x1y/tu3VGnioVV2b7zNGnKqMWtlqUB2sr0IdvgFk4 cDtOJYUd4iUt5/4jJ208GCV7NVvHLezZZ5C/y7W9st1Y5jD8LsECggEBAOxodq+9 J40/3g8YtdBQCOH0W+C/qKqf9DhVCKKDs3p1aTjcjYpG0A900+NjHKEHzX6PkoUh PY+hNqhg+FJUBFKK7XDySRzPKcRJVcAhL/cZ3oTZYzDeJyCcv9/XxIrCni8MDNrn VJl+G1Katw2E+UjJmujuCioOcdDNMzQ/uKyfvCoZm8mhKNLkbp5wm1/y/1Oqjpnl C1FiioAxY4YpkUGKnHI7nsb6FVH0zA3YIW4GFWJttiSVbotKkCPVENA/O0vUHQq2 OH0dRd7EC2ikvQ4X/y7MkCRfuhi4tp9Za8QWWCwGe6iKZ15rKo4Md+VwZy7TN8Db istpNMHeMyiosKECggEBAMCspMWk3w06CFef52GJGJBlE1A5ON36R1rxXYBAOH21 zmULxPyV+2E4mgOCJexq1JkWNYaAYaoMBfUxm/LuAJWivs+ozVYGfQHIOmXXuc4x OMtxaTHTeYBWU2iYGiLiKq1V3lzla+Wo7cE07Bf/Erno67V0aKFWyMhVCcZYaBci 2hIamLIy3fKmKBisk8SVJOmhb3Q5WTW/0LlHq2dnzTC495oIEYkREkgn5AUbHrhj LdLRhon7fLTrSKp7fyW5HvUUsJkdXE0dAtFtTTeUdztxGs7jBcPsRv+8GL3M47sX vgCTxo3WCtXO3Pln80Gc5oAcghberIXE5EzrKBA8JMsCggEBAIT+285QBqEzDfTG PPp9HBIpy0pr6DJdHCJYzCvJFb5NsS1Y/pOM9N3NJqrkhiWdYyDRGmek5KIZ2srt CqYeN/RLzfpdg34emWugqgoVYYuM1R89wMysHaz+If+Gvj4l8KGdENpRi8lyJWLa QSLs7OTi7jAeQj+YsrT5y9WYB4etsUip8XeEH5hNBGJEDVT0OmnSKLkxHqXhXvNx VYETf3E0zoCBQ/jClh3uLqGXNm9UItGl0PNR0cew4dgWtIfDGtO098Wf77WLM1R4 S8bJ7sWwAFJOqMSdye7Ac5S/1J2SyHW0C/ssKaz3cxBIuWatTo8MKnBn0fRPMmvi WjuEcyECggEATIYFJ051HH65A3xJ3I4jyG2sfwdLE7askm0ckqxvA1aq86z5/sve vF1LpisRvtUrPOX6OkJRB8WgtCKQ6qomZ0fs+vLzIsCO858/umU0sbUQ9pRDkHuK XTNsCzWl48bp5lAdcc3Yza0LSNopDtrK6DWfMEFcsP+T3SURLcq9BLtd2yTfEp9r UU02zZ31TnVh5LyuVH3WdaeKUZwqcnZio4BDLtUXidXS6f+V64U67UbO01VOVw0g GYb9JGDKPgRJTFN8VEO5/hKQpPcBXRrFREGGwTafepIkHLvrI671n8AtQXNvv7OM OCDh2Ni1X5DeZ3FrJYQpBzQM7JPVJKWOgwKCAQATd3cKqQCFgrenqbdpj6Xyrj6/ YgGt3DmsVRkBiyXrIXTJw1nsWhTCnQMx0pV904zeR7jObkLpHK0TaZKHglhwBRpI E4m94BSdmeTqnzDOsVGHxGlbU2FbSJQHwMNGzoK2G9XVzmQ3cqtilgEIRzwoE9tS WBcNdtFFGSfCYeTYhOnDCgRawldGq1UQ5uzJU8Juvm3Vdtl6XttKlRJuRLaiEdlg LliW/lhyYfeQWe/Zl8h0HPdoJUMWrWBenEQzWQWVj23REx5D6s6HnZFCf3UliRDo /aSn0j6nfheIya3grmO1EPEeBuCw5BX4pLx8MqZFVjir3/8GbD1gm4z1uhqk -----END RSA PRIVATE KEY----- form-data-form-data-a661bf5/test/fixture/unicycle.jpg000066400000000000000000000465361503610072100226430ustar00rootroot00000000000000JFIFHH(ICC_PROFILEappl scnrRGB XYZ acspAPPLappl-appl rXYZgXYZbXYZ0wtptDchadX,rTRCgTRCbTRCdesc=cprtAdscmXYZ tK>XYZ Zs&XYZ (W3XYZ Rsf32 B&lcurv3descCamera RGB ProfileCamera RGB Profilemluc enUS$esES,LdaDK4deDE,fiFI(frFU<itIT,rnlNL$noNO xptBR(JsvSE*jaJPkoKR2zhTW2zhCNKameran RGB-profiiliRGB-profil fr Kamera000 RGB 000000exOMvj_ RGB r_icϏPerfil RGB para CmaraRGB-kameraprofilRGB-Profil fr Kamerasvg: RGB cϏeNRGB-beskrivelse til KameraRGB-profiel CameratT| RGB \ |Perfil RGB de CmeraProfilo RGB FotocameraCamera RGB ProfileProfil RVB de l appareil-phototextCopyright 2003 Apple Computer Inc., all rights reserved.ExifMM* z(12iCASIO COMPUTER CO.,LTD QV-R41 HH1.00 2005:06:21 01:44:12&"0221.BV ^f  n0100v'  2005:06:21 01:44:122005:06:21 01:44:12wC     C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ?4J;k2;qggyzPnaoTzU1He8aqZx\ sH.֦:Ÿr)iA ڝRN<+cE|~*W&UGK8 Oaq%[[Q\MΙrq>H= \t@Zgj>VfT}@6m#RҮIE{ q4D2+'ƪ}-|c=empG>߅~-W TMSX~= Լ-;Ơ>{ L['eSЍЭd`sz,x1nGFWF)# _ĭK¹cxn~e3Z3#] ֮:sR* `QךOϳ[NF<k|CIERw(`OC]GϋVJ]SsX|0YJ9C",UAQRVhᱰs׿^-f=>Tܴ.>s\أ@ڐ%d!cSө\^ x׽d&r^`xV?v6]lc'xέT9P͌6xY<%YX1TU85mw_%te<}4= Xn>XkM{v7 sm5kɵV_$&H2ϵt 5Ñm+u&H$1N o4{%k n,8Vr:phc<%doZdrx|>˞P}-#9 e@+T:u퟈4X0$]D)Ł\'~c6 ??o8+"8ngѡ3YIgrڥFo@$zrZCĤ (u78ҶbojjuؠlmyesHutخOO3]x<LNjfUk*{+Qԉzkî~"iSэnGd-W+/%VƷqs$mSaz/"ikQULCk2 =܁ξy?-tx%༚w8'eh؎Y KxM,-ȟqcױOU]7Z[ VݝC 9$W4t-'ϕ 'vr@<`׍*nNZTD-ޣld@d]]#&S td$eH^SPY a̅fܤc+dɢ\dmsxVJ#)Ez6|2(ez7T ?9cK!WϫǧZG֦)sYys9qIj4F_ #|[۟NXb/i a`u(|2Njy7зpzmH80Z֗7-WSzh"Iyn!|CȯEPVCw eΏOQCsvψVmm>TRGsծThv"-Ju5o=tRyC꧷ӥz?ÏNy\@0pN/p~t j^Z3s(?)T1mV(I$yqc 9;x\DTU#>|ygN;db7ұ- Ǫ,+Ef H^-)ӵ+8 i6zMEea4; eJ m~|C9E'}O|/YVmӢ'nW n?g/xnhx^oaeI( lqW3׵Cykc4;@^q|TZ=Ob%tޭ B"tEi2nc ~"k$7OȇBZ2n<x ax6~_[<ߥ׏)9:_׿-%ZRךv:.hR# )-"I֍ky.v[>VJ)$D}3#Vs俏>!5]ZXIbϖ=$xZz<6:3,eBȅK>R_"e,hLs!s޽ÒNInq 꽖5mNo34+a PS'tO|o6a sœ+ҽ cOEYx*K-`6k)#^kukTΔő; Oְ[|-upTVΏi{j֗Aw m rbR$r:r[-d}0|#Ծ>5[4JH, `y;^٫Ǟ4oᘖyM!\A?/x_V<+ Fӡq(O|jN*TNVkxE}*i1Q"kC5͞,[Gw!l$y+JDm bmG$t+{ T)qhđH6yjU'$r|UHsׇ:Jǚךͤp[[Z_n%[2an~^ska(R^[X2/;]/., ЪjTNm  [*+˵ k6ޑt0ܪsBT3קT>flCtytuدdeky#;Xҥ]RQ]2yxZ44"mBnϜ4@pO}9KOxMa{-2lHdĕsNr c_٧x襯b?^'SQ>"uX5F,d(x[[>PkH *ez;;0oD9+ J:x?5fG㧁9: I^W%|nO¡_2=Bp)O{5?w6%T:lA R Z#-{V\o2Ism?"hY?#R0}MG+&Qmtm?j̴b~7،yFc?wҴIǡWBz|ՕeOT~h.oNJ>$6Ye5E#lnَԂ=|ӼIk}sF`a` a+FH2:J*c;wX3nZznxNo,-W"4AQE ϠS^ Kwg ˹m,ԳUgzZ.mwdld-/q܊쯾g s j*pH#gxY)|ጣr..#1 eqBq;rvq'ԏǚK񯌬t>/j̑ȋiurȥ* _ 藰E 6/&I30|X&LMK[{>2މ9)xwfĤ h3mz@+2 sWK'+t2n bP+|Y=GP.!!r}[>WȠH;H :okقlX ?CW-< ,TϽ}[q1lMO‰A+azxG)|LG+ H1=3ׁ!Q~$Ixa!qo$|F?\G_? ?|LOoG&x_L_/-$F0d8?;!D>ث!';u <ȶ&J?_ <5({Cƫ*{q??@hZu>gc#5 }58fRc y4۟r4K| ɒ9+tUWZ%q!x*OvŪNJ5q= /ua3 i~Qm$de }*R@{U[h=<9cm-Hd$U'gqL$ž6a'}J* ¯ qISgEa ~{Vމkeqszम34ͻ{ܓ~]$|e/y֧/ ǧ2+5l/'9o|e[Kn,toY{u>2 kddy6耪+l/^ҿh C/h0iv! }r1$.}0~ҵ3sLڗlZDRebL2:c= fTG=ji~cXto$.ّ_'i\V煮>8N%܎]Ā3Th_7Unm\n/.M>lW/~jwa'[ +tZG- ZG lH$Wº<:Z<&(b y#͟ \.Zu)$poz?6Y~'-.FKYˍ)P9 _7~(i{~'!ѼIM-V) mrݫ3VJmgpݟֱ\ &T<8ledYVdzqvƩ;iO yCͳG"ܴD#WϪjZMbU\KpӹiWtp8=+ښ]Ou ;g<"ĉ֔^)sM8u:)B[ |Z?rB r8֨rP}:zV5DL  F;匑R_a4}?ɣGS8nLTb&Q6cig>ߟYv>3,B78ZǨ6Q+CjmawSzv4i:$q^{Ū<+fWhl>yo%UI0@=xаMˣ.vt>[K(͟<($yѥٱa}kb,Y|X&Kr7sW "Fk;FHU(#uNꖅZb. Rk̯r۩.I(~xš}m!4@:漷ƛtK4Okfoa0/XHgƽ6fM!qu{V|ijqy: 85ۈqG5:?`.ol[꺝%؈"7^'Oعͣ^Gd,\o_$O=Rbm;KkaȀyakY[ړziЮ4DUaVPqGNkJ :oZ+WѯE?Jy! k}Q2|4$SDPݸҫì^iumjDv!Qw >^:)I3fYK 8w:MsR ?Ig&nwB5 =k>:~d%Ƥۏ8*@0s+dU gR{g]SN[mF) w[J`XMK?=?g"~QMB _Rh:n E3^z !bP"27{ҾP7s> Z`y( c5i?~:/ux~Ѧ~DžE2}nFCʫn_\𳪽_GSzC=hnL6VPr1XPx7I5,4Ůyeg vݻ{q-|bŏ*PY*J9G)}?w gr>vnj~^"KK#|ij)E;)ag ;7Z>.iv&wqD'ˌ1+̓]SM[IWҢSJg <E [l6`Ue3ǵs|}2 hA;d\m`qWGv^5ھ/`nMEb6qY}_kF(,vlp@kkZf,Y9ݹOsYW:]F,HN;H8 E{t6Puf{_Kg[nɠPydž}xo ޿&xc5K;iZ 36 3хM29ibpJ>74}B{<{l(Ưx+[fF\gnt8?VnNwuԊ4K%gh;lĞy$fƳӁY؁@@׫9ګ"*gs-O#!>⻿xv\F Pcd*ٓIŨ۷@A+_cӖ2wm\fƤUGPn)G'mkֺߊ5B7@mоv-կGK u@ݹoA2nT1\m_,%$ͳ|zחQsٹdфcSwC3674+KS{Jxw_©OZv} ԙ疩4Y4//EsOB0 ڹvkXK} 7nY~R_Q/_V΃%&j mܬ)<8qlfp۔b${"[7LIr)<P #בF2sV=Җ]]M_gLdybsGJijj7rZɴ& *Xq2VUN1,pFx9YuԺg9㸕[ ;=zW9J:m+=Zv(jTw44Eir[M$=_ kϭ^ۨK60PNG>fzk~kܮWogw>$i%M݌Q@fܸ6Yt=\3Q%yJ-G[kWasjkm+ȯdP?{vھoym]˅bj6|52mM0vCՎ;q^}~{ i bku!EoЌ!*OԮ$]b-g{g|Y޷wPmxv;{ZM kKZvuϥbx GR8 "8a2pk223ھ^j o/Aܒ.AU6173YpۿWY"nz5VK!f囖WGR՞ νNXW>qs_lKHZ98>%m[Դ+{U'-frLyU⾐)"RR8#:l5Euښ0CGehYg^ b¾ ӛ.l#/[`w/#r+ԗ~V}Ԓ;;k 4m-lrX%9*x!{՚Li\cy5v}Gk |*|cou{._·Hm,F`*& ʉG^e 9Oe/q6< 1>?u ƺ9SK4+|qU{R|?p\*"ZE!{ߵtFsS_Ye-#NP|ɲ*˱KJ$zhc+y~#NIBQI{m4nu5cH#l-ʑ(;Jm?Z<5j#!MOA%%K"g+q :+Ɓ-;S1\ ӧ.5g\6# PѤh98!+zM;>O[ N?GkDû`#E~ixQ~(}$Iovƀ|aԚ ;C=ИY"rd%'3$#bOP__3Qc}I֧V>ዻK b=8=2 d ^o[Ȃ8!Ms&[ea<盖-`jgs>dO9g}kjW=FL<Ui5M]ݴ=.$ZvwR{mlax{e:\fҤExrnjq_GO7v3έͯ+o#RɄ)nIoq.c'MgyK[Hӓ_wK' 52b;mG(CJ[;Hb J0xX-q0UcV6rL򿃾 .<[k3\[k%FW5LT4?b刖")GOr\ww&8"xJK-6Vr+` `w9?gMX\OmiqtĴsl]G8ǽt>3x'/ص G)ϺD} tӓo/絗Qͼ, ' j|DʼZ5%mV%/G2]Ќuw]sgs33 " %c ذn.~PէXg–sݐe1\~F|7:z&]DhYK K(K+*כ :I?XVcR>T)>fڽoE}z/cq[]2Vkxs2xEҵkVּζ[<YA&/AҮ>C])NK4#qctnc5ͦEr<-^ q!3} fuƔi>Xϳ|󺕥UJڏnk?a}{=mI3BUF@ppA'َJ֣V5l6ӑnXgWֽՆ二J ͵#ǻnXF̎(릿_AMgz[լzf@_FX)y8 4Zohx;~ۑc[h1)bnܪ@\s%;V Dl1<ܬG͌ϭ};[xb]G>K NU#]\_-X}{?Zxi6ge$,vHf吖F>5]Yq<2 R;_W_K+llIt8j9î^S&)5%]`״gUL,$dLӟʪxe -,8g޾l]v{- xiRO㡯IU['Q-q͚Ƭ**9<}6,, >[[?'3sb0*wVzWk^ +ĄQhVX^ 7 f̹\1N]lUfqtv^3}+"F鉕=X=`qELR֪9±XZ6vq@u6]隸${EٍڀׯJ_7%ŏtGzqyMmf0ˏxJvK"K;fK KуBz1S0=; P9\Z'miw<leυ~-5\ǧ&A<>#39O5QkEvp2GZ)aq}g]KKb5TӤLwOp$LU%NV+^ќ 6׳ [4*rwzv4gi7o+iں)rnch@'y40U}~}kroo9t [Ygv@0hI`N5\#QS[8Ճ2pS|VhTN3WwO!~45+ }vt}BǷz Wֱ\I5q:;=|i*aSGn^TIu[[̇KosXZXy$; ̬:OBj 8qҼtxmv?  %z`i]y3> eQ-V6tTkΚp+Ru#zsmȇ$)ԱK8guFGӊ4k%\۴( N ([HkdIp{utԞ |)TqM+~'ul < 66Zb)1/֠}$'tiqțpۑnUS~)nŨB =Zqc+#=:(tH m9?HmCy8O&<Yyt&xq' |?59'k?)U5gĨxW83_Q O޼)]y/oSkZ(%OaC{/2i+Ws>N1_xbz>k~3"09r5ZKW_N^FI46.%r;_sKfhMcԦap=\_ h^,wV2n}s޾ү!ִK'QIG,6S] @۵%y{WK1u0 C_Jm-֠zx:όn$i- FTG!A~xnu)bB>{#Mg᷋|e5޵;{5Ҡ ARz?SS,g{q1#B,7Smߐf1T+%Ӣ>/95rk¢[jՆȮ.m_'?Eo}M-٤2*nvcS^7Oђ=.L`t^f]J.e90`[[?0okwG=1*pߕmj:hܷkBOUeC~+8=HG3m]0(?luZiy3FO'|ys+{KMFħMEvp@{W5wr-) ~f>13_hj_@&[X:O(Kpm3)wMbUU;T[ZRI ]>Mg_H$e#wS׆Zu[;m#T ႗_UyᾒZ Fa2yM[x:oBѡ60Lν%wMz=S_qɌ˽fɢGO&kgwmh^*ljQYCjQ[:hm zZ+|C:-9ui蠞V9>ʓtz439N3nIYM|<3VjzMUk7Oi xHԺucUL>!Qv&{-m)&ɐ?Xj1 ׅ@0V &s6`~_@w⹏_Z⾑ <0*ַ#8I'٧ ʬ8kתkdG^쭶wUDe<-jH b>9V_6z_X}ľ  }j@ ,eE Nsx<+sL$^t2XKʽ~PznC?{$^߳ǁ:,v0<[2qp1I|H/Kڬ bhWn3͚=Շuilt/oBڄ2pr_hPRZ3}:=zױjrP}7A$NG|+u6f3$L.z֥\4_H49!Ip H-ƿٶ7P ڇͺꚘ#OU~ڟTiϞ>uxwAc=C #)m yqМr鋨&WzmιeCvX2D~5PSOkpOp.nLt9{|form-data-form-data-a661bf5/test/fixture/unknown_file_type000066400000000000000000000000001503610072100237600ustar00rootroot00000000000000form-data-form-data-a661bf5/test/fixture/veggies.txt000066400000000000000000000000251503610072100224770ustar00rootroot00000000000000Veggies are healthy. form-data-form-data-a661bf5/test/integration/000077500000000000000000000000001503610072100211455ustar00rootroot00000000000000form-data-form-data-a661bf5/test/integration/test-boundary-prediction.js000066400000000000000000000027761503610072100264550ustar00rootroot00000000000000var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var satisfies = require('semver').satisfies; var predictV8Randomness = satisfies(process.version, '^17 - ^23') && require('predict-v8-randomness'); // eslint-disable-line global-require var initialSequence = [ Math.random(), Math.random(), Math.random(), Math.random() ]; var predictor = predictV8Randomness && new predictV8Randomness.Predictor(initialSequence); if (predictor) { predictor.predictNext(24).then(function (next24RandomOutputs) { var predictedBoundary = next24RandomOutputs .map(function (v) { return Math.floor(v * 10).toString(16); }) .join(''); var boundaryIntro = '----------------------------'; var payload = 'zzz\r\n' + boundaryIntro + predictedBoundary + '\r\nContent-Disposition: form-data; name="is_admin"\r\n\r\ntrue\r\n' + boundaryIntro + predictedBoundary + '--\r\n'; var FIELDS = { my_field: { value: payload } }; // count total var fieldsPassed = Object.keys(FIELDS).length; // prepare form-receiving http server var server = common.testFields(FIELDS, function (fields) { fieldsPassed = fields; }); server.listen(common.port, function () { var form = new FormData(); common.actions.populateFields(form, FIELDS); common.actions.submit(form, server); }); process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); }); } form-data-form-data-a661bf5/test/integration/test-custom-content-type.js000066400000000000000000000051631503610072100264260ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var http = require('http'); var mime = require('mime-types'); var fs = require('fs'); var hasOwn = require('hasown'); var FormData = require(common.dir.lib + '/form_data'); /* * wrap non simple values into function * just to deal with ReadStream "autostart" */ var FIELDS = { no_type: { value: 'my_value' }, custom_type: { value: 'my_value', expectedType: 'image/png', options: { contentType: 'image/png' } }, default_type: { expectedType: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, implicit_type: { expectedType: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, overridden_type: { expectedType: 'image/png', options: { contentType: 'image/png' }, value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } } }; var fieldsPassed = false; var server = http.createServer(function (req, res) { var body = ''; var boundry = req.headers['content-type'].split('boundary=').pop(); req.on('data', function (data) { body += data.toString('utf-8'); }); req.on('end', function () { // Separate body into individual files/fields and remove leading and trailing content. var fields = body.split(boundry).slice(1, -1); var fieldNames = Object.keys(FIELDS); assert.ok(fields.length === fieldNames.length); for (var i = 0; i < fieldNames.length; i++) { assert.ok(fields[i].indexOf('name="' + fieldNames[i] + '"') > -1); if (FIELDS[fieldNames[i]].expectedType) { assert.ok(fields[i].indexOf('Content-Type: ' + FIELDS[fieldNames[i]].expectedType) > -1, 'Expecting ' + fieldNames[i] + ' to have Content-Type ' + FIELDS[fieldNames[i]].expectedType); } else { assert.equal(fields[i].indexOf('Content-Type'), -1, 'Expecting ' + fieldNames[i] + ' not to have Content-Type'); } } fieldsPassed = true; res.end(); }); }); server.listen(common.port, function () { var form = new FormData(); for (var name in FIELDS) { // eslint-disable-line no-restricted-syntax if (hasOwn(FIELDS, name)) { var field = FIELDS[name]; // important to append ReadStreams within the same tick if (typeof field.value === 'function') { field.value = field.value(); } form.append(name, field.value, field.options); } } // custom params object passed to submit common.actions.submit(form, server); }); process.on('exit', function () { assert.ok(fieldsPassed); }); form-data-form-data-a661bf5/test/integration/test-custom-filename.js000066400000000000000000000074061503610072100255570ustar00rootroot00000000000000'use strict'; /* *test custom filename and content-type: *re: https://github.com/felixge/node-form-data/issues/29 */ var common = require('../common'); var assert = common.assert; var mime = require('mime-types'); var http = require('http'); var fs = require('fs'); var path = require('path'); var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var knownFile = path.join(common.dir.fixture, 'unicycle.jpg'); var unknownFile = path.join(common.dir.fixture, 'unknown_file_type'); var relativeFile = path.relative(path.join(knownFile, '..', '..'), knownFile); var options = { filename: 'test.png', contentType: 'image/gif' }; var server = http.createServer(function (req, res) { var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req, function (err, fields, files) { assert(!err); assert('custom_everything' in files); assert.strictEqual(files.custom_everything.name, options.filename, 'Expects custom filename'); assert.strictEqual(files.custom_everything.type, options.contentType, 'Expects custom content-type'); assert('custom_filename' in files); assert.strictEqual(files.custom_filename.name, options.filename, 'Expects custom filename'); assert.strictEqual(files.custom_filename.type, mime.lookup(knownFile), 'Expects original content-type'); assert('custom_filepath' in files); assert.strictEqual(files.custom_filepath.name, relativeFile.replace(/\\/g, '/'), 'Expects custom filepath'); assert.strictEqual(files.custom_filepath.type, mime.lookup(knownFile), 'Expects original content-type'); assert('unknown_with_filename' in files); assert.strictEqual(files.unknown_with_filename.name, options.filename, 'Expects custom filename'); assert.strictEqual(files.unknown_with_filename.type, mime.lookup(options.filename), 'Expects filename-derived content-type'); assert('unknown_with_filename_as_object' in files); assert.strictEqual(files.unknown_with_filename_as_object.name, options.filename, 'Expects custom filename'); assert.strictEqual(files.unknown_with_filename_as_object.type, mime.lookup(options.filename), 'Expects filename-derived content-type'); assert('unknown_with_name_prop' in files); assert.strictEqual(files.unknown_with_name_prop.name, options.filename, 'Expects custom filename'); assert.strictEqual(files.unknown_with_name_prop.type, mime.lookup(options.filename), 'Expects filename-derived content-type'); assert('unknown_everything' in files); assert.strictEqual(files.unknown_everything.type, FormData.DEFAULT_CONTENT_TYPE, 'Expects default content-type'); res.writeHead(200); res.end('done'); }); }); server.listen(common.port, function () { var form = new FormData(); // Explicit contentType and filename. form.append('custom_everything', fs.createReadStream(knownFile), options); // Filename only with real file form.append('custom_filename', fs.createReadStream(knownFile), options.filename); // Filename only with unknown file form.append('unknown_with_filename', fs.createReadStream(unknownFile), options.filename); // Filename only with unknown file form.append('unknown_with_filename_as_object', fs.createReadStream(unknownFile), { filename: options.filename }); // Filename with relative path form.append('custom_filepath', fs.createReadStream(knownFile), { filepath: relativeFile }); // No options or implicit file type from extension on name property. var customNameStream = fs.createReadStream(unknownFile); customNameStream.name = options.filename; form.append('unknown_with_name_prop', customNameStream); // No options or implicit file type from extension. form.append('unknown_everything', fs.createReadStream(unknownFile)); common.actions.submit(form, server); }); form-data-form-data-a661bf5/test/integration/test-custom-headers-object.js000066400000000000000000000023351503610072100266520ustar00rootroot00000000000000/* *test custom headers object. *https://github.com/form-data/form-data/issues/133 */ var common = require('../common'); var assert = common.assert; var http = require('http'); var FormData = require(common.dir.lib + '/form_data'); var testHeader = { 'X-Test-Fake': 123 }; var expectedLength; var server = http.createServer(function (req, res) { assert.ok(typeof req.headers['content-length'] !== 'undefined'); assert.equal(req.headers['content-length'], expectedLength); req.on('data', function (data) { assert.equal( data.toString('utf8').split('\n')[3], 'X-Test-Fake: 123\r' ); }); res.writeHead(200); res.end('done'); }); server.listen(common.port, function () { var form = new FormData(); var options = { header: testHeader, /* * override content-length, * much lower than actual buffer size (1000) */ knownLength: 1 }; var bufferData = []; for (var z = 0; z < 1000; z++) { bufferData.push(1); } var buffer = new Buffer(bufferData); form.append('my_buffer', buffer, options); // (available to req handler) expectedLength = form._lastBoundary().length + form._overheadLength + options.knownLength; common.actions.submit(form, server); }); form-data-form-data-a661bf5/test/integration/test-custom-headers-string.js000066400000000000000000000024731503610072100267150ustar00rootroot00000000000000/* *test custom headers, added in pull request: *https://github.com/felixge/node-form-data/pull/17 */ var common = require('../common'); var assert = common.assert; var http = require('http'); var FormData = require(common.dir.lib + '/form_data'); var CRLF = '\r\n'; var testHeader = 'X-Test-Fake: 123'; var expectedLength; var server = http.createServer(function (req, res) { assert.ok(typeof req.headers['content-length'] !== 'undefined'); assert.equal(req.headers['content-length'], expectedLength); req.on('data', function (data) { assert.equal( data.toString('utf8').split('\n')[2], 'X-Test-Fake: 123\r' ); }); res.writeHead(200); res.end('done'); }); server.listen(common.port, function () { var form = new FormData(); var options = { header: CRLF + '--' + form.getBoundary() + CRLF + testHeader + CRLF + CRLF, /* * override content-length, * much lower than actual buffer size (1000) */ knownLength: 1 }; var bufferData = []; for (var z = 0; z < 1000; z++) { bufferData.push(1); } var buffer = new Buffer(bufferData); form.append('my_buffer', buffer, options); // (available to req handler) expectedLength = form._lastBoundary().length + form._overheadLength + options.knownLength; common.actions.submit(form, server); }); form-data-form-data-a661bf5/test/integration/test-errors.js000066400000000000000000000043531503610072100240010ustar00rootroot00000000000000var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var fake = require('fake').create(); var path = require('path'); var fs = require('fs'); var http = require('http'); // https://github.com/felixge/node-form-data/issues/38 (function testAppendArray() { var form = new FormData(); var callback = fake.callback('testAppendArray-onError-append'); fake.expectAnytime(callback, ['Arrays are not supported.']); form.on('error', function (err) { // workaround for expectAnytime handling objects callback(err.message); }); form.append('my_array', ['bird', 'cute']); }()); (function testGetLengthSync() { var fields = [ { name: 'my_string', value: 'Test 123' }, { name: 'my_image', value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg') } ]; var form = new FormData(); var expectedLength = 0; fields.forEach(function (field) { form.append(field.name, field.value); if (field.value.path) { var stat = fs.statSync(field.value.path); expectedLength += stat.size; } else { expectedLength += field.value.length; } }); expectedLength += form._overheadLength + form._lastBoundary().length; var callback = fake.callback('testGetLengthSync-onError-getLengthSync'); fake.expectAnytime(callback, ['Cannot calculate proper length in synchronous way.']); form.on('error', function (err) { // workaroud for expectAnytime handling objects callback(err.message); }); var calculatedLength = form.getLengthSync(); // getLengthSync DOESN'T calculate streams length assert.ok(expectedLength > calculatedLength); }()); (function testStreamError() { var req; var form = new FormData(); // make it windows friendly var fakePath = path.resolve('/why/u/no/exists'); var src = fs.createReadStream(fakePath); var server = http.createServer(); var addr = 'http://localhost:' + common.port; form.append('fake-stream', src); form.on('error', function (err) { assert.equal(err.code, 'ENOENT'); assert.equal(err.path, fakePath); req.on('error', function () {}); server.close(); }); server.listen(common.port, function () { req = form.submit(addr); }); }()); form-data-form-data-a661bf5/test/integration/test-form-get-length-sync.js000066400000000000000000000046351503610072100264410ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var fs = require('fs'); var Readable = require('stream').Readable; var util = require('util'); (function testGetLengthSync() { var fields = [ { name: 'my_number', value: 123 }, { name: 'my_string', value: 'Test 123' }, { name: 'my_buffer', value: new Buffer('123') } ]; var form = new FormData(); var expectedLength = 0; fields.forEach(function (field) { form.append(field.name, field.value); expectedLength += String(field.value).length; }); expectedLength += form._overheadLength + form._lastBoundary().length; var calculatedLength = form.getLengthSync(); assert.equal(expectedLength, calculatedLength); }()); (function testGetLengthSyncWithKnownLength() { var fields = [ { name: 'my_number', value: 123 }, { name: 'my_string', value: 'Test 123' }, { name: 'my_buffer', value: new Buffer('123') }, { name: 'my_image', value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg'), options: { knownLength: fs.statSync(common.dir.fixture + '/unicycle.jpg').size } } ]; var form = new FormData(); var expectedLength = 0; fields.forEach(function (field) { form.append(field.name, field.value, field.options); if (field.value.path) { var stat = fs.statSync(field.value.path); expectedLength += stat.size; } else { expectedLength += String(field.value).length; } }); expectedLength += form._overheadLength + form._lastBoundary().length; var calculatedLength = form.getLengthSync(); assert.equal(expectedLength, calculatedLength); }()); (function testReadableStreamData() { var form = new FormData(); /** * Custion readable constructor * @param {object} opt options * @constructor */ function CustomReadable(opt) { Readable.call(this, opt); this._max = 2; this._index = 1; } util.inherits(CustomReadable, Readable); CustomReadable.prototype._read = function () { var i = this._index++; if (i > this._max) { this.push(null); } else { this.push(String(i)); } }; form.append('my_txt', new CustomReadable()); assert['throws'](function () { form.getLengthSync(); }, /Cannot calculate proper length in synchronous way/); }()); form-data-form-data-a661bf5/test/integration/test-form-get-length.js000066400000000000000000000062601503610072100254630ustar00rootroot00000000000000var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var fake = require('fake').create(); var fs = require('fs'); var Readable = require('stream').Readable; var util = require('util'); (function testEmptyForm() { var form = new FormData(); var callback = fake.callback('testEmptyForm-getLength'); var calls = fake.expectAnytime(callback, [null, 0]).calls; form.getLength(callback); // Make sure our response is async assert.strictEqual(calls.length, 0); }()); (function testUtf8String() { var FIELD = 'my_field'; var VALUE = 'May the € be with you'; var form = new FormData(); form.append(FIELD, VALUE); var callback = fake.callback('testUtf8String-getLength'); var expectedLength = form._overheadLength + Buffer.byteLength(VALUE) + form._lastBoundary().length; fake.expectAnytime(callback, [null, expectedLength]); form.getLength(callback); }()); (function testBuffer() { var FIELD = 'my_field'; var VALUE = new Buffer(23); var form = new FormData(); form.append(FIELD, VALUE); var callback = fake.callback('testBuffer-getLength'); var expectedLength = form._overheadLength + VALUE.length + form._lastBoundary().length; fake.expectAnytime(callback, [null, expectedLength]); form.getLength(callback); }()); (function testStringFileBufferFile() { var fields = [ { name: 'my_field', value: 'Test 123' }, { name: 'my_image', value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg') }, { name: 'my_buffer', value: new Buffer('123') }, { name: 'my_txt', value: fs.createReadStream(common.dir.fixture + '/veggies.txt') } ]; var form = new FormData(); var expectedLength = 0; fields.forEach(function (field) { form.append(field.name, field.value); if (field.value.path) { var stat = fs.statSync(field.value.path); expectedLength += stat.size; } else { expectedLength += field.value.length; } }); expectedLength += form._overheadLength + form._lastBoundary().length; var callback = fake.callback('testStringFileBufferFile-getLength'); fake.expectAnytime(callback, [null, expectedLength]); form.getLength(callback); }()); (function testReadableStreamData() { var form = new FormData(); // var expectedLength = 0; /** * Custion readable constructor * @param {object} opt options * @constructor */ function CustomReadable(opt) { Readable.call(this, opt); this._max = 2; this._index = 1; } util.inherits(CustomReadable, Readable); CustomReadable.prototype._read = function () { var i = this._index++; if (i > this._max) { this.push(null); } else { this.push(String(i)); } }; form.append('my_txt', new CustomReadable()); // expectedLength += form._overheadLength + form._lastBoundary().length; // there is no way to determine the length of this readable stream. var callback = fake.callback(arguments.callee.name + '-getLength'); // eslint-disable-line no-restricted-properties fake.expectAnytime(callback, ['Unknown stream', undefined]); form.getLength(function (err, len) { callback(err, len); }); }()); form-data-form-data-a661bf5/test/integration/test-get-boundary.js000066400000000000000000000007601503610072100250630ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); (function testOneBoundaryPerForm() { var form = new FormData(); var boundary = form.getBoundary(); assert.equal(boundary, form.getBoundary()); assert.equal(boundary.length, 50); }()); (function testUniqueBoundaryPerForm() { var formA = new FormData(); var formB = new FormData(); assert.notEqual(formA.getBoundary(), formB.getBoundary()); }()); form-data-form-data-a661bf5/test/integration/test-get-buffer.js000066400000000000000000000034771503610072100245210ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); (function testTypeIsBuffer() { var form = new FormData(); form.append('String', 'Some random string'); var buffer = form.getBuffer(); assert.equal(typeof buffer === 'object' && Buffer.isBuffer(buffer), true); }()); (function testBufferIsValid() { var form = new FormData(); var stringName = 'String'; var stringValue = 'This is a random string'; var intName = 'Int'; var intValue = 1549873167987; var bufferName = 'Buffer'; var bufferValue = Buffer.from([0x00, 0x4a, 0x45, 0x46, 0x46, 0x52, 0x45, 0x59, 0x255]); // Fill the formData object form.append(stringName, stringValue); form.append(intName, intValue); form.append(bufferName, bufferValue); // Get the resulting Buffer var buffer = form.getBuffer(); // Generate expected code. var boundary = form.getBoundary(); var expected = Buffer.concat([ Buffer.from('--' + boundary + FormData.LINE_BREAK + 'Content-Disposition: form-data; name="' + stringName + '"' + FormData.LINE_BREAK + FormData.LINE_BREAK + stringValue + FormData.LINE_BREAK + '--' + boundary + FormData.LINE_BREAK + 'Content-Disposition: form-data; name="' + intName + '"' + FormData.LINE_BREAK + FormData.LINE_BREAK + intValue + FormData.LINE_BREAK + '--' + boundary + FormData.LINE_BREAK + 'Content-Disposition: form-data; name="' + bufferName + '"' + FormData.LINE_BREAK + 'Content-Type: application/octet-stream' + FormData.LINE_BREAK + FormData.LINE_BREAK), bufferValue, Buffer.from(FormData.LINE_BREAK + '--' + boundary + '--' + FormData.LINE_BREAK) ]); // Test if the buffer content, equals the expected buffer. assert.equal(buffer.length, expected.length); assert.equal(buffer.toString('hex'), expected.toString('hex')); }()); form-data-form-data-a661bf5/test/integration/test-http-response.js000066400000000000000000000024171503610072100252770ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var http = require('http'); var parseUrl = require('url').parse; var FormData = require(common.dir.lib + '/form_data'); // static server prepared for all tests var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; var server; var parsedUrl = parseUrl(remoteFile); var options = { method: 'get', port: parsedUrl.port || 80, path: parsedUrl.pathname, host: parsedUrl.hostname }; var FIELDS = { my_field: { value: 'my_value' }, my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, remote_file: { value: 'TBD', name: remoteFile } }; // request static file http.request(options, function (response) { var form = new FormData(); // add http response to the form fields FIELDS.remote_file.value = response; common.actions.populateFields(form, FIELDS); server.listen(common.port, function () { common.actions.submit(form, server); }); }).end(); // count total var fieldsPassed = Object.keys(FIELDS).length; // prepare form-receiving http server server = common.testFields(FIELDS, function (fields) { fieldsPassed = fields; }); process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); form-data-form-data-a661bf5/test/integration/test-last_boundary-line_break.js000066400000000000000000000015411503610072100274200ustar00rootroot00000000000000'use strict'; var http = require('http'); var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var server; /** * Test submission of proper line ending */ function submitForm() { var form = new FormData(); form.append('field', 'value'); common.actions.submit(form, server); } // create https server server = http.createServer(function (req, res) { var body = ''; req.setEncoding('utf8'); // old and simple req.on('data', function (data) { body += data; }); req.on('end', function () { // last character(s) sequence equals predefined line break assert.strictEqual(body.substr(-1 * FormData.LINE_BREAK.length), FormData.LINE_BREAK); res.writeHead(200); res.end(); }); }); // when https server ready submit form server.listen(common.port, submitForm); form-data-form-data-a661bf5/test/integration/test-options-override.js000066400000000000000000000003721503610072100257720ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var form = new FormData({ maxDataSize: 20 * 1024 * 1024 }); assert.strictEqual(form.maxDataSize, 20 * 1024 * 1024); form-data-form-data-a661bf5/test/integration/test-pipe.js000066400000000000000000000041331503610072100234160ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var http = require('http'); var mime = require('mime-types'); var request = require('request'); var fs = require('fs'); var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var hasOwn = require('hasown'); var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; /* * wrap non simple values into function * just to deal with ReadStream "autostart" */ var FIELDS = { my_field: { value: 'my_value' }, my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return request(remoteFile); } } }; var fieldsPassed = Object.keys(FIELDS).length; var server = http.createServer(function (req, res) { var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); common.actions.checkForm(form, FIELDS, function (fieldsChecked) { // keep track of number of the processed fields fieldsPassed = fieldsPassed - fieldsChecked; // finish it common.actions.formOnEnd(res); }); }); server.listen(common.port, function () { var form = new FormData(); for (var name in FIELDS) { // eslint-disable-line no-restricted-syntax if (hasOwn(FIELDS, name)) { var field = FIELDS[name]; // important to append ReadStreams within the same tick if (typeof field.value === 'function') { field.value = field.value(); } form.append(name, field.value); } } var req = http.request({ method: 'post', port: common.port, path: '/upload', headers: form.getHeaders() }); form.pipe(req); req.on('response', function (res) { // unstuck new streams res.resume(); server.close(); }); }); process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); form-data-form-data-a661bf5/test/integration/test-ranged-filestream.js000066400000000000000000000055311503610072100260550ustar00rootroot00000000000000'use strict'; /* *test ranged fs.createReadStream *re: https://github.com/felixge/node-form-data/issues/71 */ var common = require('../common'); var assert = common.assert; var http = require('http'); var fs = require('fs'); var hasOwn = require('hasown'); var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var testSubjects = { a_file: { file: 'veggies.txt', start: 8, end: 18 }, b_file: { file: 'veggies.txt', start: 6 }, c_file: { file: 'veggies.txt', end: 16 }, d_file: { file: 'veggies.txt', start: 0, end: 16 }, e_file: { file: 'veggies.txt', start: 0, end: 0 } }; /** * Accumulates read data size * * @param {string} data - chunk of read data */ function readSizeAccumulator(data) { this.readSize += data.length; // eslint-disable-line no-invalid-this } var server = http.createServer(function (req, res) { var requestBodyLength = 0; // calculate actual length of the request body req.on('data', function (data) { requestBodyLength += data.length; }); req.on('end', function () { // make sure total Content-Length is properly calculated assert.equal(req.headers['content-length'], requestBodyLength); // successfully accepted request and it's good res.writeHead(200); }); var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); form .on('file', function (name, file) { // make sure chunks are the same size assert.equal(file.size, testSubjects[name].readSize); // clean up tested subject delete testSubjects[name]; }) .on('end', function () { // done here res.end(); }); }); server.listen(common.port, function () { var form = new FormData(); var name, options; // add test subjects to the form for (name in testSubjects) { // eslint-disable-line no-restricted-syntax if (hasOwn(testSubjects, name)) { options = { encoding: 'utf8' }; if (testSubjects[name].start) { options.start = testSubjects[name].start; } if (testSubjects[name].end) { options.end = testSubjects[name].end; } form.append(name, testSubjects[name].fsStream = fs.createReadStream(common.dir.fixture + '/' + testSubjects[name].file, options)); // calculate data size testSubjects[name].readSize = 0; testSubjects[name].fsStream.on('data', readSizeAccumulator.bind(testSubjects[name])); } } form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); // wait for server to finish res.on('end', function () { // check that all subjects were tested assert.strictEqual(Object.keys(testSubjects).length, 0); server.close(); }); // unstuck new streams res.resume(); }); }); form-data-form-data-a661bf5/test/integration/test-request.js000066400000000000000000000047271503610072100241620ustar00rootroot00000000000000'use strict'; /** * Show & Test for `mikeal/request` library * as bonus shows progress monitor implementation */ var common = require('../common'); var assert = common.assert; var http = require('http'); var path = require('path'); var mime = require('mime-types'); var request = require('request'); var FormData = require(common.dir.lib + '/form_data'); var fs = require('fs'); var IncomingForm = require('formidable').IncomingForm; var fileName = common.dir.fixture + '/unicycle.jpg'; var myFile = function () { return fs.createReadStream(fileName); }; var numItems = 5; // Make request to use our FormData request.prototype.form = function (form) { var self = this; if (form) { if (!(/^application\/x-www-form-urlencoded\b/).test(self.getHeader('content-type'))) { self.setHeader('content-type', 'application/x-www-form-urlencoded'); } self.body = typeof form === 'string' ? self._qs.rfc3986(form.toString('utf8')) : self._qs.stringify(form).toString('utf8'); return self; } // create form-data object self._form = new FormData(); self._form.on('error', function (err) { err.message = 'form-data: ' + err.message; // eslint-disable-line no-param-reassign self.emit('error', err); self.abort(); }); return self._form; }; var server = http.createServer(function (req, res) { var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); form .on('file', function (name, file) { numItems -= 1; assert.strictEqual(file.name, path.basename(fileName)); assert.strictEqual(file.type, mime.lookup(file.name)); }) .on('end', common.actions.formOnEnd.bind(null, res)); }); server.listen(common.port, function () { var uploadSize = 0; var uploaded = 0; var r = request.post('http://localhost:' + common.port + '/', function (err, res) { assert.ifError(err); assert.strictEqual(res.statusCode, 200); server.close(); }); var form = r.form(); for (var i = 0; i < numItems; i++) { form.append('file_' + i, myFile()); } // get upload size form.getLength(function (err, size) { assert.equal(err, null); uploadSize = size; assert.ok(uploadSize > 0); }); // calculate uploaded size chunk by chunk form.on('data', function (data) { uploaded += data.length; }); // done uploading compare sizes form.on('end', function () { assert.equal(uploaded, uploadSize); }); }); process.on('exit', function () { assert.strictEqual(numItems, 0); }); form-data-form-data-a661bf5/test/integration/test-return-http-request.js000066400000000000000000000035571503610072100264540ustar00rootroot00000000000000'use strict'; /* *test return http request, added for issue #47: *https://github.com/felixge/node-form-data/issues/47 * *Checking correct length header and request object */ var common = require('../common'); var assert = common.assert; var http = require('http'); var FormData = require(common.dir.lib + '/form_data'); var expectedLength; var dataSize = 1000000; var server = http.createServer(function (req, res) { var uploaded = 0; assert.ok(typeof req.headers['content-length'] !== 'undefined'); assert.equal(req.headers['content-length'], expectedLength); // check for uploaded body req.on('data', function (data) { uploaded += data.length; }); req.on('end', function () { // compare uploaded total to the expected length assert.equal(uploaded, expectedLength); res.writeHead(200); res.end('done'); }); }); server.listen(common.port, function () { var progress = 0; var form = new FormData(); var bufferData = []; for (var z = 0; z < dataSize; z++) { bufferData.push(1); } var buffer = new Buffer(bufferData); form.append('my_buffer', buffer); // (available to req handler) expectedLength = form._lastBoundary().length + form._overheadLength + dataSize; var R = form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); // unstuck new streams res.resume(); server.close(); // compare progress total to the expected length assert.equal(progress, expectedLength); }); // augment into request var oWrite = R.write; R.write = function (chunk) { return oWrite.call(this, chunk, function () { form.emit('progress', chunk); }); }; // track progress form.on('progress', function (chunk) { progress += chunk.length; assert.ok(progress <= expectedLength); }); }); form-data-form-data-a661bf5/test/integration/test-set-boundary.js000066400000000000000000000016231503610072100250760ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); (function testSetBoundary() { var userBoundary = '---something'; var form = new FormData(); form.setBoundary(userBoundary); assert.equal(form.getBoundary(), userBoundary); }()); (function testUniqueBoundaryPerFormAfterSet() { var userBoundary = '---something'; var formA = new FormData(); formA.setBoundary(userBoundary); var formB = new FormData(); assert.equal(formA.getBoundary(), userBoundary); assert.notEqual(formA.getBoundary(), formB.getBoundary()); }()); (function testSetBoundaryWithNonString() { var form = new FormData(); var invalidValues = [123, null, undefined, { value: 123 }, ['---something']]; invalidValues.forEach(function (value) { assert.throws(function () { form.setBoundary(value); }, TypeError); }); }()); form-data-form-data-a661bf5/test/integration/test-set-nonstring.js000066400000000000000000000007461503610072100253010ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); (function testSetUndefined() { var form = new FormData(); assert.doesNotThrow(function () { form.append('key', undefined); }); var buffer = form.getBuffer(); assert.deepEqual(buffer.toString().split(form.getBoundary()), [ '--', '\r\nContent-Disposition: form-data; name="key"\r\n\r\nundefined\r\n--', '--\r\n' ]); }()); form-data-form-data-a661bf5/test/integration/test-submit-custom-header.js000066400000000000000000000036721503610072100265310ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var http = require('http'); var mime = require('mime-types'); var request = require('request'); var fs = require('fs'); var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; /* * wrap non simple values into function * just to deal with ReadStream "autostart" */ var FIELDS = { my_field: { value: 'my_value' }, my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return request(remoteFile); } } }; var fieldsPassed = Object.keys(FIELDS).length; var server = http.createServer(function (req, res) { assert.ok(req.headers['x-test-header'], 'test-header-value'); var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); common.actions.checkForm(form, FIELDS, function (fieldsChecked) { // keep track of number of the processed fields fieldsPassed = fieldsPassed - fieldsChecked; // finish it common.actions.formOnEnd(res); }); }); server.listen(common.port, function () { var form = new FormData(); common.actions.populateFields(form, FIELDS); // custom params object passed to submit form.submit({ port: common.port, path: '/', headers: { 'x-test-header': 'test-header-value' } }, function (error, result) { if (error) { throw error; } assert.strictEqual(result.statusCode, 200); // unstuck streams result.resume(); server.close(); }); }); process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); form-data-form-data-a661bf5/test/integration/test-submit-custom.js000066400000000000000000000027361503610072100253030ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var mime = require('mime-types'); var request = require('request'); var fs = require('fs'); var FormData = require(common.dir.lib + '/form_data'); var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; /* * wrap non simple values into function * just to deal with ReadStream "autostart" */ var FIELDS = { my_field: { value: 'my_value' }, my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return request(remoteFile); } } }; // count total var fieldsPassed = Object.keys(FIELDS).length; // prepare form-receiving http server var server = common.testFields(FIELDS, function (fields) { fieldsPassed = fields; }); server.listen(common.port, function () { var form = new FormData(); common.actions.populateFields(form, FIELDS); // custom params object passed to submit form.submit({ port: common.port, path: '/' }, function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); res.resume(); server.close(); }); }); process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); form-data-form-data-a661bf5/test/integration/test-submit-https.js000066400000000000000000000023051503610072100251230ustar00rootroot00000000000000'use strict'; var https = require('https'); var constants = require('constants'); var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); var server; /** * Test submission to HTTPS endpoint */ function submitForm() { var form = new FormData(); form.append('field', 'value'); form.submit({ protocol: 'https:', hostname: 'localhost', port: common.httpsPort, pathname: '/', // for self-signed certs on localhost secureOptions: constants.SSL_OP_NO_TLSv1_2, ca: common.httpsServerCert }, function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); assert.strictEqual(res.headers['x-success'], 'OK'); // unstuck new streams res.resume(); server.close(); }); } // create https server server = https.createServer({ key: common.httpsServerKey, cert: common.httpsServerCert }, function (req, res) { // old and simple req.on('data', function () {}); req.on('end', function () { res.writeHead(200, { 'x-success': 'OK' }); res.end('Great Success'); }); }); // when https server ready submit form server.listen(common.httpsPort, submitForm); form-data-form-data-a661bf5/test/integration/test-submit-multi-nocallback.js000066400000000000000000000017431503610072100272070ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var http = require('http'); var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var times = 10; var server = http.createServer(function (req, res) { // no need to have tmp dir here, since no files being uploaded // but formidable would fail in 0.6 otherwise var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); form .on('field', common.actions.basicFormOnField) .on('end', function () { res.writeHead(200); res.end('done'); times -= 1; if (times === 0) { server.close(); } }); }); server.listen(common.port, function () { for (var i = 0; i < times; i++) { var form = new FormData(); form.append('my_field', 'my_value'); form.submit('http://localhost:' + common.port + '/'); } }); process.on('exit', function () { assert.strictEqual(times, 0); }); form-data-form-data-a661bf5/test/integration/test-submit-multi.js000066400000000000000000000025061503610072100251160ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var http = require('http'); var FormData = require(common.dir.lib + '/form_data'); var IncomingForm = require('formidable').IncomingForm; var times = 10; var server; /** * Test parallel submissions to the same server */ function submitForm() { var form = new FormData(); form.append('my_field', 'my_value'); form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); /* * Needed for node-0.10.x because Streams2 * more info: http://nodejs.org/api/stream.html#stream_compatibility_with_older_node_versions */ res.resume(); times -= 1; if (times === 0) { server.close(); } }); } server = http.createServer(function (req, res) { // no need to have tmp dir here, since no files being uploaded // but formidable would fail in 0.6 otherwise var form = new IncomingForm({ uploadDir: common.dir.tmp }); form.parse(req); form .on('field', common.actions.basicFormOnField) .on('end', common.actions.formOnEnd.bind(null, res)); }); server.listen(common.port, function () { for (var i = 0; i < times; i++) { submitForm(); } }); process.on('exit', function () { assert.strictEqual(times, 0); }); form-data-form-data-a661bf5/test/integration/test-submit-readable-stream.js000066400000000000000000000023111503610072100270060ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var http = require('http'); var FormData = require(common.dir.lib + '/form_data'); var Readable = require('stream').Readable; var util = require('util'); var server = http.createServer(function (req, res) { assert.strictEqual(req.headers['Content-Length'], undefined); res.writeHead(200); res.end('done'); }); server.listen(common.port, function () { var form = new FormData(); /** * Custion readable constructor * @param {object} opt options * @constructor */ function CustomReadable(opt) { Readable.call(this, opt); this._max = 2; this._index = 1; } util.inherits(CustomReadable, Readable); CustomReadable.prototype._read = function () { var i = this._index++; // console.error('send back read data'); if (i > this._max) { this.push(null); } else { this.push(String(i)); } }; form.append('readable', new CustomReadable()); form.submit('http://localhost:' + common.port + '/', function (err, res) { if (err) { throw err; } assert.strictEqual(res.statusCode, 200); // unstuck new streams res.resume(); server.close(); }); }); form-data-form-data-a661bf5/test/integration/test-submit-url-parsing.js000066400000000000000000000017421503610072100262300ustar00rootroot00000000000000'use strict'; var http = require('http'); var https = require('https'); var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); /** * Test url parsing during submission */ var req; var form = new FormData(); form.append('field', 'value'); // Basic parsing req = form.submit('http://localhost/path', function () {}); assert.strictEqual(req.path, '/path'); assert.ok(req.agent instanceof http.Agent, 'req.agent instanceof http.Agent'); assert.strictEqual(req.getHeader('Host'), 'localhost'); req.abort(); // Non-default port handling req = form.submit('http://localhost:' + common.port, function () {}); assert.strictEqual(req.getHeader('Host'), 'localhost:' + common.port); req.abort(); // HTTPS protocol handling req = form.submit('https://localhost/path', function () {}); assert.ok(req.agent instanceof https.Agent, 'req.agent instanceof https.Agent'); assert.strictEqual(req.getHeader('Host'), 'localhost'); req.abort(); form-data-form-data-a661bf5/test/integration/test-submit.js000066400000000000000000000024101503610072100237600ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var mime = require('mime-types'); var request = require('request'); var fs = require('fs'); var FormData = require(common.dir.lib + '/form_data'); var remoteFile = 'http://localhost:' + common.staticPort + '/unicycle.jpg'; /* * wrap non simple values into function * just to deal with ReadStream "autostart" */ var FIELDS = { my_field: { value: 'my_value' }, my_buffer: { type: FormData.DEFAULT_CONTENT_TYPE, value: common.defaultTypeValue }, my_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return fs.createReadStream(common.dir.fixture + '/unicycle.jpg'); } }, remote_file: { type: mime.lookup(common.dir.fixture + '/unicycle.jpg'), value: function () { return request(remoteFile); } } }; // count total var fieldsPassed = Object.keys(FIELDS).length; // prepare form-receiving http server var server = common.testFields(FIELDS, function (fields) { fieldsPassed = fields; }); server.listen(common.port, function () { var form = new FormData(); common.actions.populateFields(form, FIELDS); common.actions.submit(form, server); }); process.on('exit', function () { assert.strictEqual(fieldsPassed, 0); }); form-data-form-data-a661bf5/test/integration/test-to-string.js000066400000000000000000000002761503610072100244130ustar00rootroot00000000000000'use strict'; var common = require('../common'); var assert = common.assert; var FormData = require(common.dir.lib + '/form_data'); assert(String(new FormData()) === '[object FormData]'); form-data-form-data-a661bf5/test/run-browser.js000066400000000000000000000006621503610072100214510ustar00rootroot00000000000000'use strict'; var test = require('tape'); var FormData = require('../lib/browser.js'); var form = new FormData(); test('being nice to browser-like environments', function (t) { t.plan(3); t.notEqual(typeof FormData, 'undefined', 'FormData should be defined'); t.equal(typeof form, 'object', 'FormData instance should be object'); t.equal(typeof form.append, 'function', 'FormData instance should have `append` method'); }); form-data-form-data-a661bf5/test/run.js000077500000000000000000000037441503610072100177770ustar00rootroot00000000000000#!/usr/bin/env node 'use strict'; var path = require('path'); var staticS = require('./static'); var far = require('far').create(); var farPaths = require('far/lib/paths'); var spawn = require('cross-spawn'); var basePath = process.cwd(); var istanbul = path.join(basePath, './node_modules/.bin/istanbul'); // augment Far to support istanbul if (process.env.running_under_istanbul) { far.constructor.prototype._execute = function (file) { this._printStatus(file); var node = spawn(istanbul, [ 'cover', '--report', 'none', '--print', 'none', '--include-all-sources', '--include-pid', '--root', basePath, file ]); var output = ''; node.stdout.setEncoding('utf8'); node.stderr.setEncoding('utf8'); /** * Collects output delivered in chunks * @param {string} chunk - partial output */ function onOutput(chunk) { if (this._verbose > 1) { // eslint-disable-line no-invalid-this process.stderr.write(chunk); } else { output += chunk; } } node.stdout.on('data', onOutput.bind(this)); node.stderr.on('data', onOutput.bind(this)); node.on('exit', function (code) { this._index++; this._printTestResult(file, code, output); this._executeNext(); }.bind(this)); }; } // augment far to work on windows farPaths.expandSync = function (pathList) { var expanded = {}; pathList.forEach(function (p) { p = path.resolve(process.cwd(), p); // eslint-disable-line no-param-reassign if (!farPaths.isDirectory(p)) { expanded[p] = true; return; } farPaths .findRecursiveSync(p) .forEach(function (pp) { expanded[pp] = true; }); }); return Object.keys(expanded); }; // continue as normal if (process.env.verbose) { far.verbose(process.env.verbose); } far.add(__dirname); far.include(/test-.*\.js$/); // start static server for all tests staticS(function () { far.execute(); }); form-data-form-data-a661bf5/test/static.js000066400000000000000000000013441503610072100204510ustar00rootroot00000000000000'use strict'; // serves static files var http = require('http'); var fs = require('fs'); var path = require('path'); var mime = require('mime-types'); var common = require('./common'); // prepare tmp folder if (!fs.existsSync(common.dir.tmp)) { fs.mkdirSync(common.dir.tmp); } module.exports = function (callback) { // create http server var httpServer = http.createServer(function (req, res) { var target = path.join(common.dir.fixture, req.url); var stat = fs.statSync(target); res.writeHead(200, { 'Content-Type': mime.lookup(target), 'Content-Length': stat.size }); fs.createReadStream(target).pipe(res); }); httpServer.listen(common.staticPort, callback.bind(undefined, httpServer)); };