Skip to content

Commit

Permalink
Revert "Dispatch compose (nodejs#2795)"
Browse files Browse the repository at this point in the history
This reverts commit 649185a.
  • Loading branch information
ronag authored and KhafraDev committed Jun 24, 2024
1 parent 5398e14 commit fe8e14f
Show file tree
Hide file tree
Showing 21 changed files with 458 additions and 274 deletions.
18 changes: 14 additions & 4 deletions lib/api/api-connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const assert = require('node:assert')
const { AsyncResource } = require('node:async_hooks')
const { InvalidArgumentError, SocketError } = require('../core/errors')
const util = require('../core/util')
const redirect = require('../interceptor/redirect')
const RedirectHandler = require('../handler/RedirectHandler')
const { addSignal, removeSignal } = require('./abort-signal')

class ConnectHandler extends AsyncResource {
Expand Down Expand Up @@ -95,9 +95,19 @@ function connect (opts, callback) {
}

try {
this
.compose(redirect(opts))
.dispatch({ ...opts, method: opts?.method || 'CONNECT' }, new ConnectHandler(opts, callback))
const connectHandler = new ConnectHandler(opts, callback)
const connectOptions = { ...opts, method: 'CONNECT' }

if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

if (opts?.maxRedirections > 0) {
RedirectHandler.buildDispatch(this, opts.maxRedirections)(connectOptions, connectHandler)
return
}

this.dispatch(connectOptions, connectHandler)
} catch (err) {
if (typeof callback !== 'function') {
throw err
Expand Down
14 changes: 10 additions & 4 deletions lib/api/api-pipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const {
RequestAbortedError
} = require('../core/errors')
const util = require('../core/util')
const redirect = require('../interceptor/redirect')
const RedirectHandler = require('../handler/RedirectHandler')
const { addSignal, removeSignal } = require('./abort-signal')

const kResume = Symbol('resume')
Expand Down Expand Up @@ -243,9 +243,15 @@ function pipeline (opts, handler) {
try {
const pipelineHandler = new PipelineHandler(opts, handler)

this
.compose(redirect(opts))
.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler)
if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

if (opts?.maxRedirections > 0) {
RedirectHandler.buildDispatch(this, opts.maxRedirections)({ ...opts, body: pipelineHandler.req }, pipelineHandler)
} else {
this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler)
}

return pipelineHandler.ret
} catch (err) {
Expand Down
17 changes: 13 additions & 4 deletions lib/api/api-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const assert = require('node:assert')
const { Readable } = require('./readable')
const { InvalidArgumentError, RequestAbortedError } = require('../core/errors')
const util = require('../core/util')
const redirect = require('../interceptor/redirect')
const RedirectHandler = require('../handler/RedirectHandler')
const { getResolveErrorBodyCallback } = require('./util')
const { AsyncResource } = require('node:async_hooks')

Expand Down Expand Up @@ -195,9 +195,18 @@ function request (opts, callback) {
}

try {
this
.compose(redirect(opts))
.dispatch(opts, new RequestHandler(opts, callback))
const handler = new RequestHandler(opts, callback)

if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

if (opts?.maxRedirections > 0) {
RedirectHandler.buildDispatch(this, opts.maxRedirections)(opts, handler)
return
}

this.dispatch(opts, handler)
} catch (err) {
if (typeof callback !== 'function') {
throw err
Expand Down
17 changes: 13 additions & 4 deletions lib/api/api-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const assert = require('node:assert')
const { finished, PassThrough } = require('node:stream')
const { InvalidArgumentError, InvalidReturnValueError } = require('../core/errors')
const util = require('../core/util')
const redirect = require('../interceptor/redirect')
const RedirectHandler = require('../handler/RedirectHandler')
const { getResolveErrorBodyCallback } = require('./util')
const { AsyncResource } = require('node:async_hooks')
const { addSignal, removeSignal } = require('./abort-signal')
Expand Down Expand Up @@ -208,9 +208,18 @@ function stream (opts, factory, callback) {
}

try {
this
.compose(redirect(opts))
.dispatch(opts, new StreamHandler(opts, factory, callback))
const handler = new StreamHandler(opts, factory, callback)

if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

if (opts?.maxRedirections > 0) {
RedirectHandler.buildDispatch(this, opts.maxRedirections)(opts, handler)
return
}

this.dispatch(opts, handler)
} catch (err) {
if (typeof callback !== 'function') {
throw err
Expand Down
22 changes: 18 additions & 4 deletions lib/api/api-upgrade.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const { InvalidArgumentError, SocketError } = require('../core/errors')
const { AsyncResource } = require('node:async_hooks')
const { InvalidArgumentError, SocketError } = require('../core/errors')
const util = require('../core/util')
const redirect = require('../interceptor/redirect')
const RedirectHandler = require('../handler/RedirectHandler')
const { addSignal, removeSignal } = require('./abort-signal')

class UpgradeHandler extends AsyncResource {
Expand Down Expand Up @@ -91,9 +91,23 @@ function upgrade (opts, callback) {
}

try {
this
.compose(redirect(opts))
.dispatch({ ...opts, method: opts?.method || 'GET', upgrade: opts?.protocol || 'Websocket' }, new UpgradeHandler(opts, callback))
const upgradeHandler = new UpgradeHandler(opts, callback)
const upgradeOpts = {
...opts,
method: opts.method || 'GET',
upgrade: opts.protocol || 'Websocket'
}

if (opts?.maxRedirections != null && (!Number.isInteger(opts?.maxRedirections) || opts?.maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

if (opts?.maxRedirections > 0) {
RedirectHandler.buildDispatch(this, opts.maxRedirections)(upgradeOpts, upgradeHandler)
return
}

this.dispatch(upgradeOpts, upgradeHandler)
} catch (err) {
if (typeof callback !== 'function') {
throw err
Expand Down
19 changes: 19 additions & 0 deletions lib/dispatcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict'

const EventEmitter = require('node:events')

class Dispatcher extends EventEmitter {
dispatch () {
throw new Error('not implemented')
}

close () {
throw new Error('not implemented')
}

destroy () {
throw new Error('not implemented')
}
}

module.exports = Dispatcher
31 changes: 31 additions & 0 deletions lib/handler/DecoratorHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use strict'

module.exports = class DecoratorHandler {
constructor (handler) {
this.handler = handler
}

onConnect (...args) {
return this.handler.onConnect(...args)
}

onError (...args) {
return this.handler.onError(...args)
}

onUpgrade (...args) {
return this.handler.onUpgrade(...args)
}

onHeaders (...args) {
return this.handler.onHeaders(...args)
}

onData (...args) {
return this.handler.onData(...args)
}

onComplete (...args) {
return this.handler.onComplete(...args)
}
}
62 changes: 20 additions & 42 deletions lib/interceptor/redirect.js → lib/handler/RedirectHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const { kBodyUsed } = require('../core/symbols')
const assert = require('node:assert')
const { InvalidArgumentError } = require('../core/errors')
const EE = require('node:events')
const Dispatcher = require('../dispatcher')

const redirectableStatusCodes = [300, 301, 302, 303, 307, 308]

Expand All @@ -25,14 +24,27 @@ class BodyAsyncIterable {
}

class RedirectHandler {
constructor (dispatcher, dispatcherOpts, redirectOpts, handler) {
const { maxRedirections } = redirectOpts ?? {}
static buildDispatch (dispatcher, maxRedirections) {
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

const dispatch = dispatcher.dispatch.bind(dispatcher)
return (opts, originalHandler) => dispatch(opts, new RedirectHandler(dispatch, maxRedirections, opts, originalHandler))
}

constructor (dispatch, maxRedirections, opts, handler) {
if (maxRedirections != null && (!Number.isInteger(maxRedirections) || maxRedirections < 0)) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

util.validateHandler(handler, opts.method, opts.upgrade)

this.dispatcher = dispatcher
this.dispatch = dispatch
this.location = null
this.abort = null
this.opts = { ...dispatcherOpts } // opts must be a copy
this.maxRedirections = maxRedirections ?? 0
this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy
this.maxRedirections = maxRedirections
this.handler = handler
this.history = []
this.redirectionLimitReached = false
Expand Down Expand Up @@ -165,7 +177,7 @@ class RedirectHandler {
this.location = null
this.abort = null

this.dispatcher.dispatch(this.opts, this)
this.dispatch(this.opts, this)
} else {
this.handler.onComplete(trailers)
}
Expand Down Expand Up @@ -220,38 +232,4 @@ function cleanRequestHeaders (headers, removeContent, unknownOrigin) {
return ret
}

class RedirectDispatcher extends Dispatcher {
#opts
#dispatcher

constructor (dispatcher, opts) {
super()

this.#dispatcher = dispatcher
this.#opts = opts
}

dispatch (opts, handler) {
return this.#dispatcher.dispatch(opts, new RedirectHandler(this.#dispatcher, opts, this.#opts, handler))
}

close (...args) {
return this.#dispatcher.close(...args)
}

destroy (...args) {
return this.#dispatcher.destroy(...args)
}
}

module.exports = (opts) => {
if (opts?.maxRedirections == null || opts?.maxRedirections === 0) {
return null
}

if (!Number.isInteger(opts.maxRedirections) || opts.maxRedirections < 0) {
throw new InvalidArgumentError('maxRedirections must be a positive number')
}

return (dispatcher) => new RedirectDispatcher(dispatcher, opts)
}
module.exports = RedirectHandler
40 changes: 7 additions & 33 deletions lib/interceptor/retry.js → lib/handler/RetryHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ const assert = require('node:assert')
const { kRetryHandlerDefaultRetry } = require('../core/symbols')
const { RequestRetryError } = require('../core/errors')
const { isDisturbed, parseHeaders, parseRangeHeader } = require('../core/util')
const Dispatcher = require('../dispatcher')

function calculateRetryAfterHeader (retryAfter) {
const current = Date.now()
Expand All @@ -13,7 +12,8 @@ function calculateRetryAfterHeader (retryAfter) {
}

class RetryHandler {
constructor (dispatcher, dispatchOpts, retryOpts, handler) {
constructor (opts, handlers) {
const { retryOptions, ...dispatchOpts } = opts
const {
// Retry scoped
retry: retryFn,
Expand All @@ -26,10 +26,10 @@ class RetryHandler {
errorCodes,
retryAfter,
statusCodes
} = retryOpts ?? {}
} = retryOptions ?? {}

this.dispatcher = dispatcher
this.handler = handler
this.dispatch = handlers.dispatch
this.handler = handlers.handler
this.opts = dispatchOpts
this.abort = null
this.aborted = false
Expand Down Expand Up @@ -324,38 +324,12 @@ class RetryHandler {
}

try {
this.dispatcher.dispatch(this.opts, this)
this.dispatch(this.opts, this)
} catch (err) {
this.handler.onError(err)
}
}
}
}

class RetryDispatcher extends Dispatcher {
#dispatcher
#opts

constructor (dispatcher, opts) {
super()

this.#dispatcher = dispatcher
this.#opts = opts
}

dispatch (opts, handler) {
return this.#dispatcher.dispatch(opts, new RetryHandler(this.#dispatcher, opts, this.#opts, handler))
}

close (...args) {
return this.#dispatcher.close(...args)
}

destroy (...args) {
return this.#dispatcher.destroy(...args)
}
}

module.exports = (opts) => {
return (dispatcher) => new RetryDispatcher(dispatcher, opts)
}
module.exports = RetryHandler
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit fe8e14f

Please sign in to comment.