123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- 'use strict'
- const { InvalidArgumentError, RequestAbortedError } = require('../core/errors')
- const DecoratorHandler = require('../handler/decorator-handler')
- class DumpHandler extends DecoratorHandler {
- #maxSize = 1024 * 1024
- #dumped = false
- #size = 0
- #controller = null
- aborted = false
- reason = false
- constructor ({ maxSize, signal }, handler) {
- if (maxSize != null && (!Number.isFinite(maxSize) || maxSize < 1)) {
- throw new InvalidArgumentError('maxSize must be a number greater than 0')
- }
- super(handler)
- this.#maxSize = maxSize ?? this.#maxSize
- // this.#handler = handler
- }
- #abort (reason) {
- this.aborted = true
- this.reason = reason
- }
- onRequestStart (controller, context) {
- controller.abort = this.#abort.bind(this)
- this.#controller = controller
- return super.onRequestStart(controller, context)
- }
- onResponseStart (controller, statusCode, headers, statusMessage) {
- const contentLength = headers['content-length']
- if (contentLength != null && contentLength > this.#maxSize) {
- throw new RequestAbortedError(
- `Response size (${contentLength}) larger than maxSize (${
- this.#maxSize
- })`
- )
- }
- if (this.aborted === true) {
- return true
- }
- return super.onResponseStart(controller, statusCode, headers, statusMessage)
- }
- onResponseError (controller, err) {
- if (this.#dumped) {
- return
- }
- err = this.#controller.reason ?? err
- super.onResponseError(controller, err)
- }
- onResponseData (controller, chunk) {
- this.#size = this.#size + chunk.length
- if (this.#size >= this.#maxSize) {
- this.#dumped = true
- if (this.aborted === true) {
- super.onResponseError(controller, this.reason)
- } else {
- super.onResponseEnd(controller, {})
- }
- }
- return true
- }
- onResponseEnd (controller, trailers) {
- if (this.#dumped) {
- return
- }
- if (this.#controller.aborted === true) {
- super.onResponseError(controller, this.reason)
- return
- }
- super.onResponseEnd(controller, trailers)
- }
- }
- function createDumpInterceptor (
- { maxSize: defaultMaxSize } = {
- maxSize: 1024 * 1024
- }
- ) {
- return dispatch => {
- return function Intercept (opts, handler) {
- const { dumpMaxSize = defaultMaxSize } = opts
- const dumpHandler = new DumpHandler({ maxSize: dumpMaxSize, signal: opts.signal }, handler)
- return dispatch(opts, dumpHandler)
- }
- }
- }
- module.exports = createDumpInterceptor
|