Socket
Socket
Sign inDemoInstall

nock

Package Overview
Dependencies
Maintainers
4
Versions
424
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 13.0.0-beta.4 to 13.0.0-beta.5

138

lib/intercepted_request_router.js

@@ -16,2 +16,16 @@ 'use strict'

function socketOnClose(req) {
debug('socket close')
if (!req.res && !req.socket._hadError) {
// If we don't have a response then we know that the socket
// ended prematurely and we need to emit an error on the request.
req.socket._hadError = true
const err = new Error('socket hang up')
err.code = 'ECONNRESET'
req.emit('error', err)
}
req.emit('close')
}
/**

@@ -52,6 +66,11 @@ * Given a group of interceptors, appropriately route an outgoing request.

this.attachToReq()
// Emit a fake socket event on the next tick to mimic what would happen on a real request.
// Some clients listen for a 'socket' event to be emitted before calling end(),
// which causes Nock to hang.
process.nextTick(() => this.connectSocket())
}
attachToReq() {
const { req, socket, options } = this
const { req, options } = this

@@ -73,14 +92,5 @@ for (const [name, val] of Object.entries(options.headers)) {

// ClientRequest.connection is an alias for ClientRequest.socket
// https://nodejs.org/api/http.html#http_request_socket
// https://github.com/nodejs/node/blob/b0f75818f39ed4e6bd80eb7c4010c1daf5823ef7/lib/_http_client.js#L640-L641
// The same Socket is shared between the request and response to mimic native behavior.
req.socket = req.connection = socket
propagate(['close', 'error', 'timeout'], req.socket, req)
req.write = (...args) => this.handleWrite(...args)
req.end = (...args) => this.handleEnd(...args)
req.flushHeaders = (...args) => this.handleFlushHeaders(...args)
req.abort = (...args) => this.handleAbort(...args)

@@ -94,33 +104,35 @@ // https://github.com/nock/nock/issues/256

}
}
// Emit a fake socket event on the next tick to mimic what would happen on a real request.
// Some clients listen for a 'socket' event to be emitted before calling end(),
// which causes nock to hang.
process.nextTick(() => {
if (req.aborted) {
return
}
connectSocket() {
const { req, socket } = this
socket.connecting = false
req.emit('socket', socket)
// Until Node 14 is the minimum, we need to look at both flags to see if the request has been cancelled.
if (req.destroyed || req.aborted) {
return
}
// https://nodejs.org/api/net.html#net_event_connect
socket.emit('connect')
// ClientRequest.connection is an alias for ClientRequest.socket
// https://nodejs.org/api/http.html#http_request_socket
// https://github.com/nodejs/node/blob/b0f75818f39ed4e6bd80eb7c4010c1daf5823ef7/lib/_http_client.js#L640-L641
// The same Socket is shared between the request and response to mimic native behavior.
req.socket = req.connection = socket
// https://nodejs.org/api/tls.html#tls_event_secureconnect
if (socket.authorized) {
socket.emit('secureConnect')
}
propagate(['error', 'timeout'], socket, req)
socket.on('close', () => socketOnClose(req))
if (this.readyToStartPlaybackOnSocketEvent) {
this.maybeStartPlayback()
}
})
}
socket.connecting = false
req.emit('socket', socket)
emitError(error) {
const { req } = this
process.nextTick(() => {
req.emit('error', error)
})
// https://nodejs.org/api/net.html#net_event_connect
socket.emit('connect')
// https://nodejs.org/api/tls.html#tls_event_secureconnect
if (socket.authorized) {
socket.emit('secureConnect')
}
if (this.readyToStartPlaybackOnSocketEvent) {
this.maybeStartPlayback()
}
}

@@ -131,3 +143,3 @@

handleWrite(buffer, encoding, callback) {
debug('write', arguments)
debug('request write')
const { req } = this

@@ -138,3 +150,3 @@

err.code = 'ERR_STREAM_WRITE_AFTER_END'
this.emitError(err)
process.nextTick(() => req.emit('error', err))

@@ -147,3 +159,3 @@ // It seems odd to return `true` here, not sure why you'd want to have

if (req.aborted) {
if (req.socket && req.socket.destroyed) {
return false

@@ -177,3 +189,3 @@ }

handleEnd(chunk, encoding, callback) {
debug('req.end')
debug('request end')
const { req } = this

@@ -202,38 +214,6 @@

handleFlushHeaders() {
debug('req.flushHeaders')
debug('request flushHeaders')
this.maybeStartPlayback()
}
handleAbort() {
debug('req.abort')
const { req, socket } = this
if (req.aborted) {
return
}
// Historically, `aborted` was undefined or a timestamp.
// Node changed this behavior in v11 to always be a bool.
req.aborted = true
req.destroyed = true
// the order of these next three steps is important to match order of events Node would emit.
process.nextTick(() => req.emit('abort'))
if (!socket.connecting) {
if (!req.res) {
// If we don't have a response then we know that the socket
// ended prematurely and we need to emit an error on the request.
// Node doesn't actually emit this during the `abort` method.
// Instead it listens to the socket's `end` and `close` events, however,
// Nock's socket doesn't have all the complexities and events to
// replicated that directly. This is an easy way to achieve the same behavior.
const connResetError = new Error('socket hang up')
connResetError.code = 'ECONNRESET'
this.emitError(connResetError)
}
socket.destroy()
}
}
/**

@@ -280,3 +260,4 @@ * Set request headers of the given request. This is needed both during the

if (!req.aborted && !playbackStarted) {
// Until Node 14 is the minimum, we need to look at both flags to see if the request has been cancelled.
if (!req.destroyed && !req.aborted && !playbackStarted) {
this.startPlayback()

@@ -358,10 +339,7 @@ }

} else {
const err = new Error(
`Nock: No match for request ${common.stringifyRequest(
options,
requestBodyString
)}`
)
const reqStr = common.stringifyRequest(options, requestBodyString)
const err = new Error(`Nock: No match for request ${reqStr}`)
err.code = 'ERR_NOCK_NO_MATCH'
err.statusCode = err.status = 404
this.emitError(err)
req.destroy(err)
}

@@ -368,0 +346,0 @@ }

@@ -126,8 +126,2 @@ 'use strict'

function emitError(error) {
process.nextTick(() => {
req.emit('error', error)
})
}
function start() {

@@ -149,3 +143,3 @@ interceptor.markConsumed()

const delay = interceptor.delayBodyInMs + interceptor.delayConnectionInMs
common.setTimeout(emitError, delay, error)
common.setTimeout(() => req.destroy(error), delay)
return

@@ -175,3 +169,3 @@ }

.then(continueWithResponseBody)
.catch(emitError)
.catch(err => req.destroy(err))
return

@@ -190,3 +184,3 @@ }

.then(continueWithFullResponse)
.catch(emitError)
.catch(err => req.destroy(err))
return

@@ -241,3 +235,3 @@ }

} catch (err) {
emitError(err)
req.destroy(err)
return

@@ -244,0 +238,0 @@ }

@@ -23,2 +23,5 @@ 'use strict'

// Undocumented flag used by ClientRequest to ensure errors aren't double-fired
this._hadError = false
// Maximum allowed delay. 0 means unlimited.

@@ -87,2 +90,3 @@ this.timeout = 0

debug('socket destroy')
this.destroyed = true

@@ -93,2 +97,3 @@ this.readable = this.writable = false

if (err) {
this._hadError = true
this.emit('error', err)

@@ -95,0 +100,0 @@ }

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

],
"version": "13.0.0-beta.4",
"version": "13.0.0-beta.5",
"author": "Pedro Teixeira <pedro.teixeira@gmail.com>",

@@ -13,0 +13,0 @@ "repository": {

@@ -47,2 +47,6 @@ # Nock

- [Delay the response](#delay-the-response)
- [Delay the connection](#delay-the-connection)
- [Technical Details](#technical-details)
- [Delay the response body](#delay-the-response-body)
- [Technical Details](#technical-details-1)
- [Chaining](#chaining)

@@ -49,0 +53,0 @@ - [Scope filtering](#scope-filtering)

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc