feat: ✨ Created a mini nodeJS server with NewMan for testing without PostMan GUI.
This will mimic a run in a CD/CI environment or docker container.
This commit is contained in:
20
node_modules/@postman/form-data/License
generated
vendored
Normal file
20
node_modules/@postman/form-data/License
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
|
||||
Copyright (c) 2020 Postman Inc.
|
||||
|
||||
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.
|
344
node_modules/@postman/form-data/Readme.md
generated
vendored
Normal file
344
node_modules/@postman/form-data/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
# Form-Data [](https://www.npmjs.com/package/@postman/form-data) [](https://travis-ci.com/postmanlabs/form-data) [](https://codecov.io/gh/postmanlabs/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
|
||||
|
||||
## 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.compostmanlabsa/form-data#void-append-string-field-mixed-value--mixed-options-).
|
||||
- [_Headers_ getHeaders( [**Headers** _userHeaders_] )](https://github.com/postmanlabs/form-data#array-getheaders-array-userheaders-)
|
||||
- [_String_ getBoundary()](https://github.com/postmanlabs/form-data#string-getboundary)
|
||||
- [_Buffer_ getBuffer()](https://github.com/postmanlabs/form-data#buffer-getbuffer)
|
||||
- [_Integer_ getLengthSync()](https://github.com/postmanlabs/form-data#integer-getlengthsync)
|
||||
- [_Integer_ getLength( **function** _callback_ )](https://github.com/postmanlabs/form-data#integer-getlength-function-callback-)
|
||||
- [_Boolean_ hasKnownLength()](https://github.com/postmanlabs/form-data#boolean-hasknownlength)
|
||||
- [_Request_ submit( _params_, **function** _callback_ )](https://github.com/postmanlabs/form-data#request-submit-params-function-callback-)
|
||||
- [_String_ toString()](https://github.com/postmanlabs/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. A boundary consists of 26 `-` followed by 24 numbers
|
||||
for example:
|
||||
```javascript
|
||||
--------------------------515890814546601021194782
|
||||
```
|
||||
_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.
|
||||
- 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.
|
61
node_modules/@postman/form-data/index.d.ts
generated
vendored
Normal file
61
node_modules/@postman/form-data/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Definitions by: Carlos Ballesteros Velasco <https://github.com/soywiz>
|
||||
// Leon Yu <https://github.com/leonyu>
|
||||
// BendingBender <https://github.com/BendingBender>
|
||||
// Maple Miao <https://github.com/mapleeit>
|
||||
|
||||
/// <reference types="node" />
|
||||
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;
|
||||
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:';
|
||||
}
|
||||
}
|
2
node_modules/@postman/form-data/lib/browser.js
generated
vendored
Normal file
2
node_modules/@postman/form-data/lib/browser.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/* eslint-env browser */
|
||||
module.exports = typeof self == 'object' ? self.FormData : window.FormData;
|
525
node_modules/@postman/form-data/lib/form_data.js
generated
vendored
Normal file
525
node_modules/@postman/form-data/lib/form_data.js
generated
vendored
Normal file
@@ -0,0 +1,525 @@
|
||||
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 mime = require('mime-types');
|
||||
var asynckit = require('asynckit');
|
||||
var populate = require('./populate.js');
|
||||
|
||||
// Public API
|
||||
module.exports = FormData;
|
||||
|
||||
// make it a Stream
|
||||
util.inherits(FormData, CombinedStream);
|
||||
|
||||
/**
|
||||
* 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 || {};
|
||||
for (var option in options) {
|
||||
this[option] = options[option];
|
||||
}
|
||||
}
|
||||
|
||||
FormData.LINE_BREAK = '\r\n';
|
||||
FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream';
|
||||
|
||||
FormData.prototype.append = function(field, value, options) {
|
||||
|
||||
options = options || {};
|
||||
value = value || '';
|
||||
|
||||
// allow filename as single option
|
||||
if (typeof options == 'string') {
|
||||
options = {filename: options};
|
||||
}
|
||||
|
||||
var append = CombinedStream.prototype.append.bind(this);
|
||||
|
||||
// all that streamy business can't handle numbers
|
||||
if (typeof value == 'number') {
|
||||
value = '' + value;
|
||||
}
|
||||
|
||||
// https://github.com/felixge/node-form-data/issues/38
|
||||
if (util.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 += +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
|
||||
if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) {
|
||||
return;
|
||||
}
|
||||
|
||||
// no need to bother with the length
|
||||
if (!options.knownLength) {
|
||||
this._valuesToMeasure.push(value);
|
||||
}
|
||||
};
|
||||
|
||||
FormData.prototype._lengthRetriever = function(value, callback) {
|
||||
|
||||
if (value.hasOwnProperty('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));
|
||||
|
||||
// not that fast snoopy
|
||||
} else {
|
||||
// still need to fetch file size from fs
|
||||
fs.stat(value.path, function(err, stat) {
|
||||
|
||||
var fileSize;
|
||||
|
||||
if (err) {
|
||||
callback(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// update final size based on the range options
|
||||
fileSize = stat.size - (value.start ? value.start : 0);
|
||||
callback(null, fileSize);
|
||||
});
|
||||
}
|
||||
|
||||
// or http response
|
||||
} else if (value.hasOwnProperty('httpVersion')) {
|
||||
callback(null, +value.headers['content-length']);
|
||||
|
||||
// or request stream http://github.com/mikeal/request
|
||||
} else if (value.hasOwnProperty('httpModule')) {
|
||||
// wait till response come back
|
||||
value.on('response', function(response) {
|
||||
value.pause();
|
||||
callback(null, +response.headers['content-length']);
|
||||
});
|
||||
value.resume();
|
||||
|
||||
// something else
|
||||
} else {
|
||||
callback('Unknown stream');
|
||||
}
|
||||
};
|
||||
|
||||
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) {
|
||||
if (!headers.hasOwnProperty(prop)) continue;
|
||||
header = headers[prop];
|
||||
|
||||
// skip nullish headers.
|
||||
if (header == null) {
|
||||
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._encodeHeaderParam = function(str, lang) {
|
||||
if (!lang || typeof lang !== 'string') {
|
||||
lang = '';
|
||||
}
|
||||
|
||||
// taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
|
||||
// @note see RFC 8187
|
||||
// @todo use postman-urlencoder instead of encodeURIComponent for consistency
|
||||
return 'UTF-8\'' + lang + '\'' + encodeURIComponent(str).
|
||||
// Note that although RFC3986 reserves "!", RFC8187 does not,
|
||||
// so we do not need to escape it
|
||||
replace(/['()*]/g, function(c) {
|
||||
return '%' + c.charCodeAt(0).toString(16);
|
||||
}).
|
||||
// The following are not required for percent-encoding per RFC8187,
|
||||
// so we can allow for a little better readability over the wire: |`^
|
||||
replace(/%(?:7C|60|5E)/g, unescape);
|
||||
};
|
||||
|
||||
FormData.prototype._getContentDisposition = function(value, options) {
|
||||
|
||||
var filename
|
||||
, contentDisposition = []
|
||||
, NON_ASCII_REGEX = /[^\t\x20-\x7e\x80-\xff]/
|
||||
;
|
||||
|
||||
if (typeof options.filepath === 'string') {
|
||||
// custom filepath for relative paths
|
||||
filename = path.normalize(options.filepath).replace(/\\/g, '/');
|
||||
} else if (typeof options.filename === 'string') {
|
||||
// custom filename take precedence
|
||||
filename = path.basename(options.filename);
|
||||
} else if (value && (value.name || value.path)) {
|
||||
// formidable and the browser add a name property
|
||||
// fs- and request- streams have path property
|
||||
filename = path.basename(value.name || value.path);
|
||||
} else if (value && value.readable && value.hasOwnProperty('httpVersion')) {
|
||||
// or try http response
|
||||
filename = path.basename(value.client._httpMessage.path || '');
|
||||
}
|
||||
|
||||
// bail if no valid filename
|
||||
if (typeof filename !== 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
contentDisposition.push('filename="' + filename + '"');
|
||||
|
||||
// add "filename*" param if filename is not in ASCII
|
||||
if (NON_ASCII_REGEX.test(filename)) {
|
||||
contentDisposition.push('filename*=' + this._encodeHeaderParam(filename));
|
||||
}
|
||||
|
||||
return contentDisposition;
|
||||
};
|
||||
|
||||
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 && value.hasOwnProperty('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 && 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) {
|
||||
if (userHeaders.hasOwnProperty(header)) {
|
||||
formHeaders[header.toLowerCase()] = userHeaders[header];
|
||||
}
|
||||
}
|
||||
|
||||
return formHeaders;
|
||||
};
|
||||
|
||||
FormData.prototype.getBoundary = function() {
|
||||
if (!this._boundary) {
|
||||
this._generateBoundary();
|
||||
}
|
||||
|
||||
return this._boundary;
|
||||
};
|
||||
|
||||
FormData.prototype.getBuffer = function() {
|
||||
var dataBuffer = new Buffer.alloc( 0 );
|
||||
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.
|
||||
var boundary = '--------------------------';
|
||||
for (var i = 0; i < 24; i++) {
|
||||
boundary += Math.floor(Math.random() * 10).toString(16);
|
||||
}
|
||||
|
||||
this._boundary = boundary;
|
||||
};
|
||||
|
||||
// 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
|
||||
, options
|
||||
, defaults = {method: 'post'}
|
||||
;
|
||||
|
||||
// parse provided url if it's string
|
||||
// or treat it as options object
|
||||
if (typeof params == 'string') {
|
||||
|
||||
params = parseUrl(params);
|
||||
options = populate({
|
||||
port: params.port,
|
||||
path: params.pathname,
|
||||
host: params.hostname,
|
||||
protocol: params.protocol
|
||||
}, defaults);
|
||||
|
||||
// use custom params
|
||||
} else {
|
||||
|
||||
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) {
|
||||
this._error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
// add content 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);
|
||||
};
|
||||
|
||||
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]';
|
||||
};
|
10
node_modules/@postman/form-data/lib/populate.js
generated
vendored
Normal file
10
node_modules/@postman/form-data/lib/populate.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
// populates missing values
|
||||
module.exports = function(dst, src) {
|
||||
|
||||
Object.keys(src).forEach(function(prop)
|
||||
{
|
||||
dst[prop] = dst[prop] || src[prop];
|
||||
});
|
||||
|
||||
return dst;
|
||||
};
|
60
node_modules/@postman/form-data/package.json
generated
vendored
Normal file
60
node_modules/@postman/form-data/package.json
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"name": "@postman/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": "3.1.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/postmanlabs/form-data.git"
|
||||
},
|
||||
"main": "./lib/form_data",
|
||||
"browser": "./lib/browser",
|
||||
"typings": "./index.d.ts",
|
||||
"scripts": {
|
||||
"pretest": "rimraf coverage test/tmp",
|
||||
"test": "istanbul cover test/run.js",
|
||||
"posttest": "istanbul report lcov text",
|
||||
"lint": "eslint lib/*.js test/*.js test/integration/*.js",
|
||||
"report": "istanbul report lcov text",
|
||||
"ci-lint": "is-node-modern 8 && npm run lint || is-node-not-modern 8",
|
||||
"ci-test": "npm run test && 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"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint",
|
||||
"ci-test",
|
||||
"check"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
},
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.0.10",
|
||||
"browserify": "^13.1.1",
|
||||
"browserify-istanbul": "^2.0.0",
|
||||
"cross-spawn": "^6.0.5",
|
||||
"eslint": "^6.0.1",
|
||||
"fake": "^0.2.2",
|
||||
"far": "^0.0.7",
|
||||
"formidable": "^1.0.17",
|
||||
"is-node-modern": "^1.0.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"obake": "^0.1.2",
|
||||
"puppeteer": "^1.19.0",
|
||||
"pkgfiles": "^2.3.0",
|
||||
"pre-commit": "^1.1.3",
|
||||
"request": "^2.88.0",
|
||||
"rimraf": "^2.7.1",
|
||||
"tape": "^4.6.2",
|
||||
"typescript": "^3.5.2"
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
55
node_modules/@postman/tunnel-agent/LICENSE
generated
vendored
Normal file
55
node_modules/@postman/tunnel-agent/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
4
node_modules/@postman/tunnel-agent/README.md
generated
vendored
Normal file
4
node_modules/@postman/tunnel-agent/README.md
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
tunnel-agent
|
||||
============
|
||||
|
||||
HTTP proxy tunneling agent.
|
274
node_modules/@postman/tunnel-agent/index.js
generated
vendored
Normal file
274
node_modules/@postman/tunnel-agent/index.js
generated
vendored
Normal file
@@ -0,0 +1,274 @@
|
||||
'use strict'
|
||||
|
||||
var net = require('net')
|
||||
, tls = require('tls')
|
||||
, http = require('http')
|
||||
, https = require('https')
|
||||
, events = require('events')
|
||||
, util = require('util')
|
||||
, Buffer = require('safe-buffer').Buffer
|
||||
;
|
||||
|
||||
exports.httpOverHttp = httpOverHttp
|
||||
exports.httpsOverHttp = httpsOverHttp
|
||||
exports.httpOverHttps = httpOverHttps
|
||||
exports.httpsOverHttps = httpsOverHttps
|
||||
|
||||
|
||||
function httpOverHttp(options) {
|
||||
var agent = new TunnelingAgent(options)
|
||||
agent.request = http.request
|
||||
return agent
|
||||
}
|
||||
|
||||
function httpsOverHttp(options) {
|
||||
var agent = new TunnelingAgent(options)
|
||||
agent.request = http.request
|
||||
agent.createSocket = createSecureSocket
|
||||
agent.defaultPort = 443
|
||||
return agent
|
||||
}
|
||||
|
||||
function httpOverHttps(options) {
|
||||
var agent = new TunnelingAgent(options)
|
||||
agent.request = https.request
|
||||
return agent
|
||||
}
|
||||
|
||||
function httpsOverHttps(options) {
|
||||
var agent = new TunnelingAgent(options)
|
||||
agent.request = https.request
|
||||
agent.createSocket = createSecureSocket
|
||||
agent.defaultPort = 443
|
||||
return agent
|
||||
}
|
||||
|
||||
|
||||
function TunnelingAgent(options) {
|
||||
var self = this
|
||||
self.options = options || {}
|
||||
self.proxyOptions = self.options.proxy || {}
|
||||
self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets
|
||||
self.requests = []
|
||||
self.sockets = []
|
||||
|
||||
self.on('free', function onFree(socket, host, port) {
|
||||
for (var i = 0, len = self.requests.length; i < len; ++i) {
|
||||
var pending = self.requests[i]
|
||||
if (pending.host === host && pending.port === port) {
|
||||
// Detect the request to connect same origin server,
|
||||
// reuse the connection.
|
||||
self.requests.splice(i, 1)
|
||||
pending.request.onSocket(socket)
|
||||
return
|
||||
}
|
||||
}
|
||||
socket.destroy()
|
||||
self.removeSocket(socket)
|
||||
})
|
||||
}
|
||||
util.inherits(TunnelingAgent, events.EventEmitter)
|
||||
|
||||
TunnelingAgent.prototype.addRequest = function addRequest(req, options) {
|
||||
var self = this
|
||||
|
||||
// Legacy API: addRequest(req, host, port, path)
|
||||
if (typeof options === 'string') {
|
||||
options = {
|
||||
host: options,
|
||||
port: arguments[2],
|
||||
path: arguments[3]
|
||||
};
|
||||
}
|
||||
|
||||
if (self.sockets.length >= this.maxSockets) {
|
||||
// We are over limit so we'll add it to the queue.
|
||||
self.requests.push({host: options.host, port: options.port, request: req})
|
||||
return
|
||||
}
|
||||
|
||||
// If we are under maxSockets create a new one.
|
||||
self.createConnection({host: options.host, port: options.port, request: req})
|
||||
}
|
||||
|
||||
TunnelingAgent.prototype.createConnection = function createConnection(pending) {
|
||||
var self = this
|
||||
|
||||
self.createSocket(pending, function(err, socket) {
|
||||
if (err) {
|
||||
pending.request.emit('error', err)
|
||||
return
|
||||
}
|
||||
|
||||
socket.on('free', onFree)
|
||||
socket.on('close', onCloseOrRemove)
|
||||
socket.on('agentRemove', onCloseOrRemove)
|
||||
pending.request.onSocket(socket)
|
||||
|
||||
function onFree() {
|
||||
self.emit('free', socket, pending.host, pending.port)
|
||||
}
|
||||
|
||||
function onCloseOrRemove(err) {
|
||||
self.removeSocket(socket)
|
||||
socket.removeListener('free', onFree)
|
||||
socket.removeListener('close', onCloseOrRemove)
|
||||
socket.removeListener('agentRemove', onCloseOrRemove)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
|
||||
var self = this
|
||||
var placeholder = {}
|
||||
self.sockets.push(placeholder)
|
||||
|
||||
var connectOptions = mergeOptions({}, self.proxyOptions,
|
||||
{ method: 'CONNECT'
|
||||
, path: options.host + ':' + options.port
|
||||
, agent: false
|
||||
}
|
||||
)
|
||||
if (connectOptions.proxyAuth) {
|
||||
connectOptions.headers = connectOptions.headers || {}
|
||||
connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
|
||||
Buffer.from(connectOptions.proxyAuth).toString('base64')
|
||||
}
|
||||
|
||||
debug('making CONNECT request')
|
||||
var connectReq = self.request(connectOptions)
|
||||
connectReq.useChunkedEncodingByDefault = false // for v0.6
|
||||
connectReq.once('response', onResponse) // for v0.6
|
||||
connectReq.once('upgrade', onUpgrade) // for v0.6
|
||||
connectReq.once('connect', onConnect) // for v0.7 or later
|
||||
connectReq.once('error', onError)
|
||||
connectReq.end()
|
||||
|
||||
function onResponse(res) {
|
||||
// Very hacky. This is necessary to avoid http-parser leaks.
|
||||
res.upgrade = true
|
||||
}
|
||||
|
||||
function onUpgrade(res, socket, head) {
|
||||
// Hacky.
|
||||
process.nextTick(function() {
|
||||
onConnect(res, socket, head)
|
||||
})
|
||||
}
|
||||
|
||||
function onConnect(res, socket, head) {
|
||||
connectReq.removeAllListeners()
|
||||
socket.removeAllListeners()
|
||||
|
||||
if (res.statusCode === 200) {
|
||||
// @note `head` is the buffer for the response sent by the proxy server
|
||||
// after a successful tunnel is established. The RFC says that any
|
||||
// response sent after the successful response headers is to be considered
|
||||
// to be sent from the target server. But handling this edge-case requires
|
||||
// a lot of architecture changes which we're deferring for later.
|
||||
//
|
||||
// RFC: https://tools.ietf.org/html/rfc7231#section-4.3.6
|
||||
//
|
||||
// To prevent assertion error for this case we're commenting out the
|
||||
// following statement:
|
||||
//
|
||||
// assert.equal(head.length, 0)
|
||||
|
||||
debug('tunneling connection has established')
|
||||
self.sockets[self.sockets.indexOf(placeholder)] = socket
|
||||
cb(null, socket)
|
||||
} else {
|
||||
debug('tunneling socket could not be established, statusCode=%d', res.statusCode)
|
||||
var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode)
|
||||
error.code = 'ECONNRESET'
|
||||
self.removeSocket(placeholder)
|
||||
cb(error)
|
||||
}
|
||||
}
|
||||
|
||||
function onError(cause) {
|
||||
connectReq.removeAllListeners()
|
||||
|
||||
debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack)
|
||||
var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message)
|
||||
error.code = 'ECONNRESET'
|
||||
options.request.emit('error', error)
|
||||
self.removeSocket(placeholder)
|
||||
}
|
||||
}
|
||||
|
||||
TunnelingAgent.prototype.removeSocket = function removeSocket(socket) {
|
||||
var pos = this.sockets.indexOf(socket)
|
||||
if (pos === -1) return
|
||||
|
||||
this.sockets.splice(pos, 1)
|
||||
|
||||
var pending = this.requests.shift()
|
||||
if (pending) {
|
||||
// If we have pending requests and a socket gets closed a new one
|
||||
// needs to be created to take over in the pool for the one that closed.
|
||||
this.createConnection(pending)
|
||||
}
|
||||
}
|
||||
|
||||
function createSecureSocket(options, cb) {
|
||||
var self = this
|
||||
TunnelingAgent.prototype.createSocket.call(self, options, function(err, socket) {
|
||||
if (err) {
|
||||
return cb(err)
|
||||
}
|
||||
|
||||
var secureSocket
|
||||
|
||||
try {
|
||||
// 0 is dummy port for v0.6
|
||||
secureSocket = tls.connect(0, mergeOptions({}, self.options,
|
||||
{ servername: options.host
|
||||
, socket: socket
|
||||
}
|
||||
))
|
||||
}
|
||||
catch (error) {
|
||||
self.removeSocket(socket)
|
||||
socket.destroy()
|
||||
return cb(error)
|
||||
}
|
||||
|
||||
self.sockets[self.sockets.indexOf(socket)] = secureSocket
|
||||
cb(null, secureSocket)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function mergeOptions(target) {
|
||||
for (var i = 1, len = arguments.length; i < len; ++i) {
|
||||
var overrides = arguments[i]
|
||||
if (typeof overrides === 'object') {
|
||||
var keys = Object.keys(overrides)
|
||||
for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {
|
||||
var k = keys[j]
|
||||
if (overrides[k] !== undefined) {
|
||||
target[k] = overrides[k]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
|
||||
var debug
|
||||
if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
|
||||
debug = function() {
|
||||
var args = Array.prototype.slice.call(arguments)
|
||||
if (typeof args[0] === 'string') {
|
||||
args[0] = 'TUNNEL: ' + args[0]
|
||||
} else {
|
||||
args.unshift('TUNNEL:')
|
||||
}
|
||||
console.error.apply(console, args)
|
||||
}
|
||||
} else {
|
||||
debug = function() {}
|
||||
}
|
||||
exports.debug = debug // for test
|
29
node_modules/@postman/tunnel-agent/package.json
generated
vendored
Normal file
29
node_modules/@postman/tunnel-agent/package.json
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"author": "Postman Labs <help@getpostman.com>",
|
||||
"name": "@postman/tunnel-agent",
|
||||
"license": "Apache-2.0",
|
||||
"description": "HTTP proxy tunneling agent.",
|
||||
"version": "0.6.3",
|
||||
"repository": {
|
||||
"url": "git+https://github.com/postmanlabs/tunnel-agent.git"
|
||||
},
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"optionalDependencies": {},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/postmanlabs/tunnel-agent/issues"
|
||||
},
|
||||
"homepage": "https://github.com/postmanlabs/tunnel-agent#readme",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user