| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- '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
- 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)
- 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) {
- super.onResponseError(controller, this.aborted === true ? this.reason : err)
- }
- onResponseData (controller, chunk) {
- this.#size = this.#size + chunk.length
- if (this.#size > this.#maxSize) {
- throw new RequestAbortedError(
- `Response size (${this.#size}) larger than maxSize (${this.#maxSize})`
- )
- }
- if (this.#size === this.#maxSize) {
- this.#dumped = true
- }
- return true
- }
- onResponseEnd (controller, trailers) {
- if (this.aborted === true) {
- super.onResponseError(controller, this.reason)
- return
- }
- super.onResponseEnd(controller, this.#dumped ? {} : 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
|