@@ -16,6 +16,9 @@ import {getSearch} from './utils/get-search.js';
16
16
17
17
const INTERNALS = Symbol ( 'Request internals' ) ;
18
18
19
+ const forbiddenMethods = new Set ( [ "CONNECT" , "TRACE" , "TRACK" ] ) ;
20
+ const normalizedMethods = new Set ( [ "DELETE" , "GET" , "HEAD" , "OPTIONS" , "POST" , "PUT" ] ) ;
21
+
19
22
/**
20
23
* Check if `obj` is an instance of Request.
21
24
*
@@ -33,15 +36,15 @@ const isRequest = object => {
33
36
/**
34
37
* Request class
35
38
* @implements {globalThis.Request}
36
- *
39
+ *
37
40
* @typedef {Object } RequestState
38
41
* @property {string } method
39
42
* @property {RequestRedirect } redirect
40
43
* @property {globalThis.Headers } headers
41
44
* @property {RequestCredentials } credentials
42
45
* @property {URL } parsedURL
43
46
* @property {AbortSignal|null } signal
44
- *
47
+ *
45
48
* @typedef {Object } RequestExtraOptions
46
49
* @property {number } [follow]
47
50
* @property {boolean } [compress]
@@ -50,15 +53,15 @@ const isRequest = object => {
50
53
* @property {Agent } [agent]
51
54
* @property {number } [highWaterMark]
52
55
* @property {boolean } [insecureHTTPParser]
53
- *
56
+ *
54
57
* @typedef {((url:URL) => import('http').Agent | import('https').Agent) | import('http').Agent | import('https').Agent } Agent
55
- *
58
+ *
56
59
* @typedef {Object } RequestOptions
57
60
* @property {string } [method]
58
61
* @property {ReadableStream<Uint8Array>|null } [body]
59
62
* @property {globalThis.Headers } [headers]
60
63
* @property {RequestRedirect } [redirect]
61
- *
64
+ *
62
65
*/
63
66
export default class Request extends Body {
64
67
/**
@@ -81,8 +84,13 @@ export default class Request extends Body {
81
84
82
85
83
86
87
+ // Normalize method: https://fetch.spec.whatwg.org/#methods
84
88
let method = init . method || settings . method || 'GET' ;
85
- method = method . toUpperCase ( ) ;
89
+ if ( forbiddenMethods . has ( method . toUpperCase ( ) ) ) {
90
+ throw new TypeError ( `Failed to construct 'Request': '${ method } ' HTTP method is unsupported.` )
91
+ } else if ( normalizedMethods . has ( method . toUpperCase ( ) ) ) {
92
+ method = method . toUpperCase ( ) ;
93
+ }
86
94
87
95
const inputBody = init . body != null
88
96
? init . body
@@ -100,7 +108,7 @@ export default class Request extends Body {
100
108
} ) ;
101
109
const input = settings
102
110
103
-
111
+
104
112
const headers = /** @type {globalThis.Headers } */
105
113
( new Headers ( init . headers || input . headers || { } ) ) ;
106
114
@@ -121,7 +129,7 @@ export default class Request extends Body {
121
129
if ( signal != null && ! isAbortSignal ( signal ) ) {
122
130
throw new TypeError ( 'Expected signal to be an instanceof AbortSignal or EventTarget' ) ;
123
131
}
124
-
132
+
125
133
if ( ! signal ) {
126
134
let AbortControllerConstructor = typeof AbortController != "undefined"
127
135
? AbortController
@@ -180,11 +188,11 @@ export default class Request extends Body {
180
188
get destination ( ) {
181
189
return ""
182
190
}
183
-
191
+
184
192
get integrity ( ) {
185
193
return ""
186
194
}
187
-
195
+
188
196
/** @type {RequestMode } */
189
197
get mode ( ) {
190
198
return "cors"
@@ -194,7 +202,7 @@ export default class Request extends Body {
194
202
get referrer ( ) {
195
203
return ""
196
204
}
197
-
205
+
198
206
/** @type {ReferrerPolicy } */
199
207
get referrerPolicy ( ) {
200
208
return ""
@@ -318,7 +326,7 @@ export const getNodeRequestOptions = request => {
318
326
port : parsedURL . port ,
319
327
hash : parsedURL . hash ,
320
328
search : parsedURL . search ,
321
- // @ts -ignore - it does not has a query
329
+ // @ts -ignore - it does not has a query
322
330
query : parsedURL . query ,
323
331
href : parsedURL . href ,
324
332
method : request . method ,
0 commit comments