Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

postman-request

Package Overview
Dependencies
Maintainers
4
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

postman-request - npm Package Compare versions

Comparing version 2.88.1-postman.5-beta.1 to 2.88.1-postman.8-beta.1

87

index.js

@@ -17,2 +17,3 @@ // Copyright 2010-2012 Mikeal Rogers

var tls = require('tls')
var extend = require('extend')

@@ -134,2 +135,88 @@ var cookies = require('./lib/cookies')

// As of now (Node v10.x LTS), the only way to extend the well known "root" CA
// is by using an environment variable called `NODE_EXTRA_CA_CERTS`.
// This function enables the same functionality and provides a programmatic way
// to extend the CA certificates.
// Refer: https://nodejs.org/docs/latest-v10.x/api/cli.html#cli_node_extra_ca_certs_file
//
// @note Unlike NODE_EXTRA_CA_CERTS, this method extends the CA for every
// request sent and since its an expensive operation its advised to use a
// keepAlive agent(agentOptions.keepAlive: true) when this is enabled.
//
// Benchmarks using a local server:
// NODE_EXTRA_CA_CERTS (keepAlive: false) : 422 ops/sec ±1.73% (77 runs sampled)
// NODE_EXTRA_CA_CERTS (keepAlive: true) : 2,096 ops/sec ±4.23% (69 runs sampled)
//
// enableNodeExtraCACerts (keepAlive: false) : 331 ops/sec ±5.64% (77 runs sampled)
// enableNodeExtraCACerts (keepAlive: true) : 2,045 ops/sec ±5.20% (69 runs sampled)
//
// @note Enabling this will override the singleton `tls.createSecureContext` method
// which will be affected for every request sent (using native HTTPS etc.) on the
// same process. BUT, this will only be effective when `extraCA` option is
// passed to `tls.createSecureContext`, which is limited to this library.
request.enableNodeExtraCACerts = function (callback) {
// @note callback is optional to catch missing tls method
!callback && (callback = function () {})
// bail out if already enabled
if (tls.__createSecureContext) {
return callback()
}
// enable only if `SecureContext.addCACert` is present
// otherwise return callback with error.
// @note try-catch is used to make sure testing this will not break
// the main process due to OpenSSL error.
try {
var testContext = tls.createSecureContext()
if (!(testContext && testContext.context &&
typeof testContext.context.addCACert === 'function')) {
return callback(new Error('SecureContext.addCACert is not a function'))
}
} catch (err) {
return callback(err)
}
// store the original tls.createSecureContext method.
// used to extend existing functionality as well as restore later.
tls.__createSecureContext = tls.createSecureContext
// override tls.createSecureContext with extraCA support
// @note if agent is keepAlive, same context will be reused.
tls.createSecureContext = function () {
// call original createSecureContext and store the context
var secureContext = tls.__createSecureContext.apply(this, arguments)
// if `extraCA` is present in options, extend CA certs
// @note this request option is available here because all the
// Request properties are passed to HTTPS Agent.
if (arguments[0] && arguments[0].extraCA) {
// extend root CA with specified CA certificates
// @note `addCACert` is an undocumented API and performs an expensive operations
// Refer: https://github.com/nodejs/node/blob/v10.15.1/lib/_tls_common.js#L97
secureContext.context.addCACert(arguments[0].extraCA)
}
return secureContext
}
// enabled extra CA support
return callback()
}
// disable the extended CA certificates feature
request.disableNodeExtraCACerts = function () {
// bail out if not enabled
if (typeof tls.__createSecureContext !== 'function') {
return
}
// reset `tls.createSecureContext` with the original method
tls.createSecureContext = tls.__createSecureContext
// delete the reference of original method
delete tls.__createSecureContext
}
// Exports

@@ -136,0 +223,0 @@

45

lib/redirect.js

@@ -124,22 +124,34 @@ 'use strict'

// remove the host header if the response is a 307 or 308, & the host has changed.
// (the new host will be populated auto-magically).
// For other types of redirects, it's removed automatically (see code below)
if (self.followAllRedirects &&
(response.statusCode === 307 || response.statusCode === 308) &&
request.headers && uriPrev.host !== request.uri.host) {
self.redirects.push({ statusCode: response.statusCode, redirectUri: redirectTo })
// if the redirect hostname (not just port or protocol) is changed:
// 1. remove host header, the new host will be populated on request.init
// 2. remove authorization header, avoid authentication leak
// @note: This is done because of security reasons, irrespective of the
// status code or request method used.
if (request.headers && uriPrev.hostname !== request.uri.hostname) {
request.removeHeader('host')
// use followAuthorizationHeader option to retain authorization header
if (!self.followAuthorizationHeader) {
request.removeHeader('authorization')
}
}
self.redirects.push({ statusCode: response.statusCode, redirectUri: redirectTo })
if (self.followAllRedirects && request.method !== 'HEAD' &&
response.statusCode !== 401 && response.statusCode !== 307 && response.statusCode !== 308) {
request.method = self.followOriginalHttpMethod ? request.method : 'GET'
}
// request.method = 'GET' // Force all redirects to use GET || commented out fixes #215
delete request.src
delete request.req
delete request._started
// if statusCode code is 401, 307 or 308:
// 1. Switch request method to GET if followOriginalHttpMethod is not set
// 2. Remove request body on redirect
if (response.statusCode !== 401 && response.statusCode !== 307 && response.statusCode !== 308) {
// force all redirects to use GET (due to legacy shenanigans)
// use followOriginalHttpMethod option to avoid this
// @todo: figure out why its only done for HEAD method and not for similar
// request methods like OPTIONS or CONNECT.
if (!self.followOriginalHttpMethod && request.method !== 'HEAD') {
request.method = 'GET'
}
// Remove parameters from the previous response, unless this is the second request

@@ -153,9 +165,2 @@ // for a server that requires digest authentication.

request.removeHeader('content-length')
if (!self.followAuthorizationHeader && request.uri.hostname !== request.originalHost.split(':')[0]) {
// Remove authorization if changing hostnames (but not if just
// changing ports or protocols). This matches the behavior of curl:
// https://github.com/bagder/curl/blob/6beb0eee/lib/http.c#L710
// Change this behavior using the followAuthorizationHeader option
request.removeHeader('authorization')
}
}

@@ -162,0 +167,0 @@ } else if (request.formData &&

@@ -10,3 +10,3 @@ {

],
"version": "2.88.1-postman.5-beta.1",
"version": "2.88.1-postman.8-beta.1",
"repository": {

@@ -13,0 +13,0 @@ "type": "git",

@@ -16,2 +16,7 @@

- Respect form-data fields ordering
- Fixed authentication leak in 307 and 308 redirects
- Added `secureConnect` to timings and `secureHandshake` to timingPhases
- Fixed `Request~getNewAgent` to account for `passphrase` while generating poolKey
- Added support for extending the root CA certificates
- Added `verbose` mode to bubble up low-level request-response information

@@ -686,3 +691,3 @@ ## Super simple to use

1. its own public key, which is signed by:
2. an intermediate "Corp Issuing Server", that is in turn signed by:
2. an intermediate "Corp Issuing Server", that is in turn signed by:
3. a root CA "Corp Root CA";

@@ -704,2 +709,111 @@

### Using `options.verbose`
Using this option the debug object holds low level request response information like remote address, negotiated ciphers etc. Example debug object:
```js
request({url: 'https://www.google.com', verbose: true}, function (error, response, body, debug) {
// debug:
/*
[
{
"request": {
"method": "GET",
"href": "https://www.google.com/",
"httpVersion": "1.1"
},
"session": {
"id": "9a1ac0d7-b757-48ad-861c-d59d6af5f43f",
"reused": false,
"data": {
"addresses": {
"local": {
"address": "8.8.4.4",
"family": "IPv4",
"port": 61632
},
"remote": {
"address": "172.217.31.196",
"family": "IPv4",
"port": 443
}
},
"tls": {
"reused": false,
"authorized": true,
"authorizationError": null,
"cipher": {
"name": "ECDHE-ECDSA-AES128-GCM-SHA256",
"version": "TLSv1/SSLv3"
},
"protocol": "TLSv1.2",
"ephemeralKeyInfo": {
"type": "ECDH",
"name": "X25519",
"size": 253
},
"peerCertificate": {
"subject": {
"country": "US",
"stateOrProvince": "California",
"locality": "Mountain View",
"organization": "Google LLC",
"commonName": "www.google.com",
"alternativeNames": "DNS:www.google.com"
},
"issuer": {
"country": "US",
"organization": "Google Trust Services",
"commonName": "Google Internet Authority G3"
},
"validFrom": "2019-03-01T09:46:35.000Z",
"validTo": "2019-05-24T09:25:00.000Z",
"fingerprint": "DF:6B:95:81:C6:03:EB:ED:48:EB:6C:CF:EE:FE:E6:1F:AD:01:78:34",
"serialNumber": "3A15F4C87FB4D33993D3EEB3BF4AE5E4"
}
}
}
},
"response": {
"statusCode": 200,
"httpVersion": "1.1"
},
"timingStart": 1552908287924,
"timingStartTimer": 805.690674,
"timings": {
"socket": 28.356426000000056,
"lookup": 210.3752320000001,
"connect": 224.57993499999998,
"secureConnect": 292.80315800000017,
"response": 380.61268100000007,
"end": 401.8332560000001
}
}
]
*/
});
```
### Extending root CAs
When this feature is enabled, the root CAs can be extended using the `extraCA` option. The file should consist of one or more trusted certificates in PEM format.
This is similar to [NODE_EXTRA_CA_CERTS](https://nodejs.org/api/cli.html#cli_node_extra_ca_certs_file). But, if `options.ca` is specified, those will be extended as well.
```js
// enable extending CAs
request.enableNodeExtraCACerts();
// request with extra CA certs
request.get({
url: 'https://api.some-server.com/',
extraCA: fs.readFileSync('Extra CA Certificates .pem')
});
// disable this feature
request.disableNodeExtraCACerts()
```
[back to top](#table-of-contents)

@@ -869,2 +983,3 @@

- `connect`: Relative timestamp when the [`net`](https://nodejs.org/api/net.html#net_event_connect) module's `connect` event fires. This happens when the server acknowledges the TCP connection.
- `secureConnect`: Relative timestamp when the [`tls`](https://nodejs.org/api/tls.html#tls_event_secureconnect) module's `secureconnect` event fires. This happens when the handshaking process for a new connection has successfully completed.
- `response`: Relative timestamp when the [`http`](https://nodejs.org/api/http.html#http_event_response) module's `response` event fires. This happens when the first bytes are received from the server.

@@ -875,4 +990,5 @@ - `end`: Relative timestamp when the last bytes of the response are received.

- `dns`: Duration of DNS lookup (`timings.lookup` - `timings.socket`)
- `tcp`: Duration of TCP connection (`timings.connect` - `timings.socket`)
- `firstByte`: Duration of HTTP server response (`timings.response` - `timings.connect`)
- `tcp`: Duration of TCP connection (`timings.connect` - `timings.lookup`)
- `secureHandshake`: Duration of SSL handshake (`timings.secureConnect` - `timings.connect`)
- `firstByte`: Duration of HTTP server response (`timings.response` - `timings.connect`|`timings.secureConnect`)
- `download`: Duration of HTTP download (`timings.end` - `timings.response`)

@@ -879,0 +995,0 @@ - `total`: Duration entire HTTP round-trip (`timings.end`)

'use strict'
var tls = require('tls')
var http = require('http')

@@ -11,2 +12,3 @@ var https = require('https')

var aws4 = require('aws4')
var uuid = require('uuid/v4')
var httpSignature = require('http-signature')

@@ -159,2 +161,3 @@ var mime = require('mime-types')

self.writable = true
self._debug = []
if (options.method) {

@@ -195,2 +198,7 @@ self.explicitMethod = true

// for this request (or redirect) store its debug logs in `_reqResInfo` and
// store its reference in `_debug` which holds debug logs of every request
self._reqResInfo = {}
self._debug.push(self._reqResInfo)
// additional postman feature starts

@@ -245,3 +253,3 @@ // bind default events sent via options

self._callback = self.callback
self.callback = function () {
self.callback = function (error, response, body) {
if (self._callbackCalled) {

@@ -251,3 +259,3 @@ return // Print a warning maybe?

self._callbackCalled = true
self._callback.apply(self, arguments)
self._callback(error, response, body, self._debug)
}

@@ -469,3 +477,4 @@ self.on('error', self.callback.bind())

if (options.time) {
// enable timings if verbose is true
if (options.time || options.verbose) {
self.timing = true

@@ -477,2 +486,6 @@

if (options.verbose) {
self.verbose = true
}
function setContentLength () {

@@ -670,2 +683,5 @@ if (isTypedArray(self.body)) {

}
if (self.extraCA) {
options.extraCA = self.extraCA
}
if (self.ciphers) {

@@ -719,2 +735,10 @@ options.ciphers = self.ciphers

// only add when NodeExtraCACerts is enabled
if (tls.__createSecureContext && options.extraCA) {
if (poolKey) {
poolKey += ':'
}
poolKey += options.extraCA
}
if (typeof options.rejectUnauthorized !== 'undefined') {

@@ -741,2 +765,9 @@ if (poolKey) {

if (options.passphrase) {
if (poolKey) {
poolKey += ':'
}
poolKey += options.passphrase
}
if (options.ciphers) {

@@ -817,2 +848,9 @@ if (poolKey) {

self._reqResInfo.request = {
method: self.method,
href: self.uri.href,
proxy: (self.proxy && { href: self.proxy.href }) || undefined,
httpVersion: '1.1'
}
// We have a method named auth, which is completely different from the http.request

@@ -869,2 +907,22 @@ // auth option. If we don't remove it, we're gonna have a bad time.

self.req.on('socket', function (socket) {
if (self.verbose) {
// The reused socket holds all the session data which was injected in
// during the first connection. This is done because events like
// `lookup`, `connect` & `secureConnect` will not be triggered for a
// reused socket and debug information will be lost for that request.
var reusedSocket = Boolean(socket.__SESSION_ID && socket.__SESSION_DATA)
if (!reusedSocket) {
socket.__SESSION_ID = uuid()
socket.__SESSION_DATA = {}
}
// @note make sure you don't serialize this object to avoid memory leak
self._reqResInfo.session = {
id: socket.__SESSION_ID,
reused: reusedSocket,
data: socket.__SESSION_DATA
}
}
// `._connecting` was the old property which was made public in node v6.1.0

@@ -882,6 +940,81 @@ var isConnecting = socket._connecting || socket.connecting

self.timings.connect = now() - self.startTimeNow
if (self.verbose) {
socket.__SESSION_DATA.addresses = {
// local address
// @note there's no `socket.localFamily` but `.address` method
// returns same output as of remote.
local: (typeof socket.address === 'function') && socket.address(),
// remote address
remote: {
address: socket.remoteAddress,
family: socket.remoteFamily,
port: socket.remotePort
}
}
}
}
var onSecureConnectTiming = function () {
self.timings.secureConnect = now() - self.startTimeNow
if (self.verbose) {
socket.__SESSION_DATA.tls = {
// true if the session was reused
reused: (typeof socket.isSessionReused === 'function') && socket.isSessionReused(),
// true if the peer certificate was signed by one of the CAs specified
authorized: socket.authorized,
// reason why the peer's certificate was not been verified
authorizationError: socket.authorizationError,
// negotiated cipher name
cipher: (typeof socket.getCipher === 'function') && socket.getCipher(),
// negotiated SSL/TLS protocol version
// @note Node >= v5.7.0
protocol: (typeof socket.getProtocol === 'function') && socket.getProtocol(),
// type, name, and size of parameter of an ephemeral key exchange
// @note Node >= v5.0.0
ephemeralKeyInfo: (typeof socket.getEphemeralKeyInfo === 'function') && socket.getEphemeralKeyInfo()
}
// peer certificate information
// @note if session is reused, all certificate information is
// stripped from the socket (returns {}).
// Refer: https://github.com/nodejs/node/issues/3940
var peerCert = (typeof socket.getPeerCertificate === 'function') && (socket.getPeerCertificate() || {})
socket.__SESSION_DATA.tls.peerCertificate = {
subject: peerCert.subject && {
country: peerCert.subject.C,
stateOrProvince: peerCert.subject.ST,
locality: peerCert.subject.L,
organization: peerCert.subject.O,
organizationalUnit: peerCert.subject.OU,
commonName: peerCert.subject.CN,
alternativeNames: peerCert.subjectaltname
},
issuer: peerCert.issuer && {
country: peerCert.issuer.C,
stateOrProvince: peerCert.issuer.ST,
locality: peerCert.issuer.L,
organization: peerCert.issuer.O,
organizationalUnit: peerCert.issuer.OU,
commonName: peerCert.issuer.CN
},
validFrom: peerCert.valid_from && new Date(peerCert.valid_from),
validTo: peerCert.valid_to && new Date(peerCert.valid_to),
fingerprint: peerCert.fingerprint,
serialNumber: peerCert.serialNumber
}
}
}
socket.once('lookup', onLookupTiming)
socket.once('connect', onConnectTiming)
socket.once('secureConnect', onSecureConnectTiming)

@@ -981,2 +1114,3 @@ // clean up timing event listeners if needed on error

response.timingStart = self.startTime
response.timingStartTimer = self.startTimeNow

@@ -994,2 +1128,5 @@ // fill in the blanks for any periods that didn't trigger, such as

}
if (!self.timings.secureConnect && self.httpModule === https) {
self.timings.secureConnect = self.timings.connect
}
if (!self.timings.response) {

@@ -1019,3 +1156,10 @@ self.timings.response = self.timings.connect

}
// if secureConnect is present, add secureHandshake and update firstByte
if (self.timings.secureConnect) {
response.timingPhases.secureHandshake = self.timings.secureConnect - self.timings.connect
response.timingPhases.firstByte = self.timings.response - self.timings.secureConnect
}
}
debug('response end', self.uri.href, response.statusCode, response.headers)

@@ -1030,2 +1174,13 @@ })

self._reqResInfo.response = {
statusCode: response.statusCode,
httpVersion: response.httpVersion
}
if (self.timing) {
self._reqResInfo.timingStart = self.startTime
self._reqResInfo.timingStartTimer = self.startTimeNow
self._reqResInfo.timings = self.timings
}
self.response = response

@@ -1032,0 +1187,0 @@ response.request = self

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc