wrap-handler.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. 'use strict'
  2. const { InvalidArgumentError } = require('../core/errors')
  3. module.exports = class WrapHandler {
  4. #handler
  5. constructor (handler) {
  6. this.#handler = handler
  7. }
  8. static wrap (handler) {
  9. // TODO (fix): More checks...
  10. return handler.onRequestStart ? handler : new WrapHandler(handler)
  11. }
  12. // Unwrap Interface
  13. onConnect (abort, context) {
  14. return this.#handler.onConnect?.(abort, context)
  15. }
  16. onResponseStarted () {
  17. return this.#handler.onResponseStarted?.()
  18. }
  19. onHeaders (statusCode, rawHeaders, resume, statusMessage) {
  20. return this.#handler.onHeaders?.(statusCode, rawHeaders, resume, statusMessage)
  21. }
  22. onUpgrade (statusCode, rawHeaders, socket) {
  23. return this.#handler.onUpgrade?.(statusCode, rawHeaders, socket)
  24. }
  25. onData (data) {
  26. return this.#handler.onData?.(data)
  27. }
  28. onComplete (trailers) {
  29. return this.#handler.onComplete?.(trailers)
  30. }
  31. onError (err) {
  32. if (!this.#handler.onError) {
  33. throw err
  34. }
  35. return this.#handler.onError?.(err)
  36. }
  37. // Wrap Interface
  38. onRequestStart (controller, context) {
  39. this.#handler.onConnect?.((reason) => controller.abort(reason), context)
  40. }
  41. onRequestUpgrade (controller, statusCode, headers, socket) {
  42. const rawHeaders = []
  43. for (const [key, val] of Object.entries(headers)) {
  44. rawHeaders.push(Buffer.from(key, 'latin1'), toRawHeaderValue(val))
  45. }
  46. this.#handler.onUpgrade?.(statusCode, rawHeaders, socket)
  47. }
  48. onResponseStart (controller, statusCode, headers, statusMessage) {
  49. const rawHeaders = []
  50. for (const [key, val] of Object.entries(headers)) {
  51. rawHeaders.push(Buffer.from(key, 'latin1'), toRawHeaderValue(val))
  52. }
  53. if (this.#handler.onHeaders?.(statusCode, rawHeaders, () => controller.resume(), statusMessage) === false) {
  54. controller.pause()
  55. }
  56. }
  57. onResponseData (controller, data) {
  58. if (this.#handler.onData?.(data) === false) {
  59. controller.pause()
  60. }
  61. }
  62. onResponseEnd (controller, trailers) {
  63. const rawTrailers = []
  64. for (const [key, val] of Object.entries(trailers)) {
  65. rawTrailers.push(Buffer.from(key, 'latin1'), toRawHeaderValue(val))
  66. }
  67. this.#handler.onComplete?.(rawTrailers)
  68. }
  69. onResponseError (controller, err) {
  70. if (!this.#handler.onError) {
  71. throw new InvalidArgumentError('invalid onError method')
  72. }
  73. this.#handler.onError?.(err)
  74. }
  75. }
  76. function toRawHeaderValue (value) {
  77. return Array.isArray(value)
  78. ? value.map((item) => Buffer.from(item, 'latin1'))
  79. : Buffer.from(value, 'latin1')
  80. }