| 128 | } |
| 129 | |
| 130 | onResponseStart (controller, statusCode, headers, _statusMessage) { |
| 131 | const { factory, opaque, context, responseHeaders } = this |
| 132 | |
| 133 | const rawHeaders = controller?.rawHeaders |
| 134 | const responseHeaderData = responseHeaders === 'raw' |
| 135 | ? util.parseRawHeaders(rawHeaders) |
| 136 | : headers |
| 137 | |
| 138 | if (statusCode < 200) { |
| 139 | if (this.onInfo) { |
| 140 | this.onInfo({ statusCode, headers: responseHeaderData }) |
| 141 | } |
| 142 | return |
| 143 | } |
| 144 | |
| 145 | this.factory = null |
| 146 | |
| 147 | if (factory === null) { |
| 148 | return |
| 149 | } |
| 150 | |
| 151 | const res = this.runInAsyncScope(factory, null, { |
| 152 | statusCode, |
| 153 | headers: responseHeaderData, |
| 154 | opaque, |
| 155 | context |
| 156 | }) |
| 157 | |
| 158 | if ( |
| 159 | !res || |
| 160 | typeof res.write !== 'function' || |
| 161 | typeof res.end !== 'function' || |
| 162 | typeof res.on !== 'function' |
| 163 | ) { |
| 164 | throw new InvalidReturnValueError('expected Writable') |
| 165 | } |
| 166 | |
| 167 | trackWritableLifecycle(res, (err, fromErrorEvent) => { |
| 168 | const { callback, res, opaque, trailers, abort } = this |
| 169 | |
| 170 | this.res = null |
| 171 | if (err || !res?.readable) { |
| 172 | util.destroy(res, fromErrorEvent ? undefined : err) |
| 173 | } |
| 174 | |
| 175 | this.callback = null |
| 176 | this.runInAsyncScope(callback, null, err || null, { opaque, trailers }) |
| 177 | |
| 178 | if (err) { |
| 179 | abort(err) |
| 180 | } |
| 181 | }) |
| 182 | |
| 183 | res.on('drain', () => controller.resume()) |
| 184 | |
| 185 | this.res = res |
| 186 | |
| 187 | const needDrain = res.writableNeedDrain !== undefined |