source: node_modules/undici/lib/api/api-upgrade.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 2.5 KB
Line 
1'use strict'
2
3const { InvalidArgumentError, RequestAbortedError, SocketError } = require('../core/errors')
4const { AsyncResource } = require('async_hooks')
5const util = require('../core/util')
6const { addSignal, removeSignal } = require('./abort-signal')
7const assert = require('assert')
8
9class UpgradeHandler extends AsyncResource {
10 constructor (opts, callback) {
11 if (!opts || typeof opts !== 'object') {
12 throw new InvalidArgumentError('invalid opts')
13 }
14
15 if (typeof callback !== 'function') {
16 throw new InvalidArgumentError('invalid callback')
17 }
18
19 const { signal, opaque, responseHeaders } = opts
20
21 if (signal && typeof signal.on !== 'function' && typeof signal.addEventListener !== 'function') {
22 throw new InvalidArgumentError('signal must be an EventEmitter or EventTarget')
23 }
24
25 super('UNDICI_UPGRADE')
26
27 this.responseHeaders = responseHeaders || null
28 this.opaque = opaque || null
29 this.callback = callback
30 this.abort = null
31 this.context = null
32
33 addSignal(this, signal)
34 }
35
36 onConnect (abort, context) {
37 if (!this.callback) {
38 throw new RequestAbortedError()
39 }
40
41 this.abort = abort
42 this.context = null
43 }
44
45 onHeaders () {
46 throw new SocketError('bad upgrade', null)
47 }
48
49 onUpgrade (statusCode, rawHeaders, socket) {
50 const { callback, opaque, context } = this
51
52 assert.strictEqual(statusCode, 101)
53
54 removeSignal(this)
55
56 this.callback = null
57 const headers = this.responseHeaders === 'raw' ? util.parseRawHeaders(rawHeaders) : util.parseHeaders(rawHeaders)
58 this.runInAsyncScope(callback, null, null, {
59 headers,
60 socket,
61 opaque,
62 context
63 })
64 }
65
66 onError (err) {
67 const { callback, opaque } = this
68
69 removeSignal(this)
70
71 if (callback) {
72 this.callback = null
73 queueMicrotask(() => {
74 this.runInAsyncScope(callback, null, err, { opaque })
75 })
76 }
77 }
78}
79
80function upgrade (opts, callback) {
81 if (callback === undefined) {
82 return new Promise((resolve, reject) => {
83 upgrade.call(this, opts, (err, data) => {
84 return err ? reject(err) : resolve(data)
85 })
86 })
87 }
88
89 try {
90 const upgradeHandler = new UpgradeHandler(opts, callback)
91 this.dispatch({
92 ...opts,
93 method: opts.method || 'GET',
94 upgrade: opts.protocol || 'Websocket'
95 }, upgradeHandler)
96 } catch (err) {
97 if (typeof callback !== 'function') {
98 throw err
99 }
100 const opaque = opts && opts.opaque
101 queueMicrotask(() => callback(err, { opaque }))
102 }
103}
104
105module.exports = upgrade
Note: See TracBrowser for help on using the repository browser.