|
2 | 2 |
|
3 | 3 | 'use strict' |
4 | 4 |
|
5 | | -const Headers = require('./headers') |
6 | 5 | const { kHeadersList } = require('../../core/symbols') |
7 | | -const { METHODS } = require('http') |
| 6 | +const Headers = require('./headers') |
8 | 7 | const Response = require('./response') |
| 8 | +const { METHODS, STATUS_CODES } = require('http') |
| 9 | + |
9 | 10 | const { |
10 | 11 | InvalidArgumentError, |
11 | 12 | NotSupportedError, |
12 | 13 | RequestAbortedError |
13 | 14 | } = require('../../core/errors') |
14 | | -const { addSignal, removeSignal } = require('../abort-signal') |
15 | 15 | const { extractBody } = require('./body') |
| 16 | +const { kUrlList } = require('./symbols') |
| 17 | +const { addSignal, removeSignal } = require('../abort-signal') |
16 | 18 |
|
| 19 | +let TransformStream |
17 | 20 | let ReadableStream |
18 | 21 |
|
19 | 22 | class FetchHandler { |
@@ -69,46 +72,42 @@ class FetchHandler { |
69 | 72 | let response |
70 | 73 | if (headers.has('location')) { |
71 | 74 | if (this.redirect === 'manual') { |
72 | | - response = new Response({ |
| 75 | + response = new Response(null, { |
73 | 76 | type: 'opaqueredirect', |
| 77 | + status: 0, |
74 | 78 | url: this.url |
75 | 79 | }) |
76 | 80 | } else { |
77 | | - response = new Response({ |
78 | | - type: 'error', |
79 | | - url: this.url |
80 | | - }) |
| 81 | + response = Response.error() |
81 | 82 | } |
82 | 83 | } else { |
83 | 84 | const self = this |
84 | 85 | if (!ReadableStream) { |
85 | 86 | ReadableStream = require('stream/web').ReadableStream |
86 | 87 | } |
87 | | - response = new Response({ |
88 | | - type: 'default', |
89 | | - url: this.url, |
90 | | - body: new ReadableStream({ |
91 | | - async start (controller) { |
92 | | - self.controller = controller |
93 | | - }, |
94 | | - async pull () { |
95 | | - resume() |
96 | | - }, |
97 | | - async cancel (reason) { |
98 | | - let err |
99 | | - if (reason instanceof Error) { |
100 | | - err = reason |
101 | | - } else if (typeof reason === 'string') { |
102 | | - err = new Error(reason) |
103 | | - } else { |
104 | | - err = new RequestAbortedError() |
105 | | - } |
106 | | - abort(err) |
| 88 | + response = new Response(new ReadableStream({ |
| 89 | + async start (controller) { |
| 90 | + self.controller = controller |
| 91 | + }, |
| 92 | + async pull () { |
| 93 | + resume() |
| 94 | + }, |
| 95 | + async cancel (reason) { |
| 96 | + let err |
| 97 | + if (reason instanceof Error) { |
| 98 | + err = reason |
| 99 | + } else if (typeof reason === 'string') { |
| 100 | + err = new Error(reason) |
| 101 | + } else { |
| 102 | + err = new RequestAbortedError() |
107 | 103 | } |
108 | | - }, { highWaterMark: 16384 }), |
109 | | - statusCode, |
| 104 | + abort(err) |
| 105 | + } |
| 106 | + }, { highWaterMark: 16384 }), { |
| 107 | + status: statusCode, |
| 108 | + statusText: STATUS_CODES[statusCode], |
110 | 109 | headers, |
111 | | - context |
| 110 | + [kUrlList]: [this.url, ...((context && context.history) || [])] |
112 | 111 | }) |
113 | 112 | } |
114 | 113 |
|
@@ -182,7 +181,11 @@ async function fetch (opts) { |
182 | 181 | } |
183 | 182 |
|
184 | 183 | if (opts.redirect != null) { |
185 | | - // TODO: Validate |
| 184 | + if ( |
| 185 | + typeof opts.redirect !== 'string' || |
| 186 | + !/^(follow|manual|error)/.test(opts.redirect)) { |
| 187 | + throw new TypeError(`Redirect option '${opts.redirect}' is not a valid value of RequestRedirect`) |
| 188 | + } |
186 | 189 | } else { |
187 | 190 | opts.redirect = 'follow' |
188 | 191 | } |
@@ -214,6 +217,17 @@ async function fetch (opts) { |
214 | 217 |
|
215 | 218 | const [body, contentType] = extractBody(opts.body) |
216 | 219 |
|
| 220 | + if (body.stream) { |
| 221 | + if (!TransformStream) { |
| 222 | + TransformStream = require('stream/web').TransformStream |
| 223 | + } |
| 224 | + |
| 225 | + // https://streams.spec.whatwg.org/#readablestream-create-a-proxy |
| 226 | + const identityTransform = new TransformStream() |
| 227 | + body.pipeThrough(identityTransform) |
| 228 | + body.stream = identityTransform |
| 229 | + } |
| 230 | + |
217 | 231 | if (contentType && !headers.has('content-type')) { |
218 | 232 | headers.set('content-type', contentType) |
219 | 233 | } |
|
0 commit comments