OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "modules/fetch/Request.h" | 6 #include "modules/fetch/Request.h" |
7 | 7 |
8 #include "bindings/core/v8/Dictionary.h" | 8 #include "bindings/core/v8/Dictionary.h" |
9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
10 #include "core/dom/ExecutionContext.h" | 10 #include "core/dom/ExecutionContext.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 request->setCredentials(original->credentials()); | 43 request->setCredentials(original->credentials()); |
44 request->setRedirect(original->redirect()); | 44 request->setRedirect(original->redirect()); |
45 request->setIntegrity(original->integrity()); | 45 request->setIntegrity(original->integrity()); |
46 // FIXME: Set cache mode. | 46 // FIXME: Set cache mode. |
47 // TODO(yhirano): Set redirect mode. | 47 // TODO(yhirano): Set redirect mode. |
48 return request; | 48 return request; |
49 } | 49 } |
50 | 50 |
51 Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req
uest* inputRequest, const String& inputString, RequestInit& init, ExceptionState
& exceptionState) | 51 Request* Request::createRequestWithRequestOrString(ScriptState* scriptState, Req
uest* inputRequest, const String& inputString, RequestInit& init, ExceptionState
& exceptionState) |
52 { | 52 { |
53 // "1. Let |temporaryBody| be null." | |
54 BodyStreamBuffer* temporaryBody = nullptr; | 53 BodyStreamBuffer* temporaryBody = nullptr; |
55 | 54 |
56 if (inputRequest) { | 55 if (inputRequest) { |
57 // We check bodyUsed even when the body is null in spite of the | 56 // We check bodyUsed even when the body is null in spite of the |
58 // spec. See https://github.com/whatwg/fetch/issues/61 for details. | 57 // spec. See https://github.com/whatwg/fetch/issues/61 for details. |
59 if (inputRequest->bodyUsed()) { | 58 if (inputRequest->bodyUsed()) { |
60 exceptionState.throwTypeError("Cannot construct a Request with a Req
uest object that has already been used."); | 59 exceptionState.throwTypeError("Cannot construct a Request with a Req
uest object that has already been used."); |
61 return nullptr; | 60 return nullptr; |
62 } | 61 } |
63 } | 62 } |
64 | 63 |
65 // "2. If |input| is a Request object and |input|'s body is non-null, run | 64 // - "If |input| is a Request object and it is disturbed, throw a |
66 // these substeps:" | 65 // TypeError." |
| 66 // - "Let |temporaryBody| be |input|'s request's body if |input| is a |
| 67 // Request object, and null otherwise." |
67 if (inputRequest && inputRequest->hasBody()) { | 68 if (inputRequest && inputRequest->hasBody()) { |
68 // "1. If |input|'s used flag is set, throw a TypeError." | |
69 // "2. Set |temporaryBody| to |input|'s body." | |
70 if (inputRequest->bodyUsed()) { | 69 if (inputRequest->bodyUsed()) { |
71 exceptionState.throwTypeError("Cannot construct a Request with a Req
uest object that has already been used."); | 70 exceptionState.throwTypeError("Cannot construct a Request with a Req
uest object that has already been used."); |
72 return nullptr; | 71 return nullptr; |
73 } | 72 } |
74 temporaryBody = inputRequest->bodyBuffer(); | 73 temporaryBody = inputRequest->bodyBuffer(); |
75 } | 74 } |
76 | 75 |
77 // "3. Let |request| be |input|'s request, if |input| is a Request object, | 76 // "Let |request| be |input|'s request, if |input| is a Request object, |
78 // and a new request otherwise." | 77 // and a new request otherwise." |
79 // "4. Let origin be entry settings object's origin." | 78 |
80 RefPtr<SecurityOrigin> origin = scriptState->executionContext()->securityOri
gin(); | 79 RefPtr<SecurityOrigin> origin = scriptState->executionContext()->securityOri
gin(); |
81 | 80 |
82 // TODO(yhirano): | 81 // TODO(yhirano): Implement the following steps: |
83 // "5. Let window be client." | 82 // - "Let |window| be client." |
84 // "6. If request's window is an environment settings object and its | 83 // - "If |request|'s window is an environment settings object and its |
85 // origin is same origin with origin, set window to request's window." | 84 // origin is same origin with entry settings object's origin, set |
86 // "7. If init's window member is present and it is not null, throw a | 85 // |window| to |request|'s window." |
| 86 // - "If |init|'s window member is present and it is not null, throw a |
87 // TypeError." | 87 // TypeError." |
88 // "8. If init's window member is present, set window to no-window." | 88 // - "If |init|'s window member is present, set |window| to no-window." |
89 // "9. Set |request| to a new request whose url is |request|'s current url, | 89 // |
90 // method is |request|'s method, header list is a copy of |request|'s header | 90 // "Set |request| to a new request whose url is |request|'s current url, |
91 // list, unsafe-request flag is set, client is entry settings object, window | 91 // method is |request|'s method, header list is a copy of |request|'s |
92 // is window, origin is origin, force-Origin-header flag is set, same-origin | 92 // header list, unsafe-request flag is set, client is entry settings object, |
93 // data-URL flag is set, referrer is request's referrer, referrer policy is | 93 // window is |window|, origin is "client", omit-Origin-header flag is |
94 // |request|'s referrer policy, context is the empty string, mode is | 94 // |request|'s omit-Origin-header flag, same-origin data-URL flag is set, |
95 // |request|'s mode, credentials mode is |request|'s credentials mode, cache | 95 // referrer is |request|'s referrer, referrer policy is |request|'s |
96 // mode is |request|'s cache mode, redirect mode is |request|'s redirect | 96 // referrer policy, destination is the empty string, mode is |request|'s |
97 // mode, and integrity metadata is |request|'s integrity metadata." | 97 // mode, credentials mode is |request|'s credentials mode, cache mode is |
| 98 // |request|'s cache mode, redirect mode is |request|'s redirect mode, and |
| 99 // integrity metadata is |request|'s integrity metadata." |
98 FetchRequestData* request = createCopyOfFetchRequestDataForFetch(scriptState
, inputRequest ? inputRequest->request() : FetchRequestData::create()); | 100 FetchRequestData* request = createCopyOfFetchRequestDataForFetch(scriptState
, inputRequest ? inputRequest->request() : FetchRequestData::create()); |
99 | 101 |
100 // "10. Let |fallbackMode| be null." | |
101 // "11. Let |fallbackCredentials| be null." | |
102 // "12. Let |baseURL| be entry settings object's API base URL." | |
103 // We don't use fallback values. We set these flags directly in below. | 102 // We don't use fallback values. We set these flags directly in below. |
| 103 // - "Let |fallbackMode| be null." |
| 104 // - "Let |fallbackCredentials| be null." |
| 105 // - "Let |baseURL| be entry settings object's API base URL." |
104 | 106 |
105 // "13. If |input| is a string, run these substeps:" | 107 // "If |input| is a string, run these substeps:" |
106 if (!inputRequest) { | 108 if (!inputRequest) { |
107 // "1. Let |parsedURL| be the result of parsing |input| with |baseURL|." | 109 // "Let |parsedURL| be the result of parsing |input| with |baseURL|." |
108 KURL parsedURL = scriptState->executionContext()->completeURL(inputStrin
g); | 110 KURL parsedURL = scriptState->executionContext()->completeURL(inputStrin
g); |
109 // "2. If |parsedURL| is failure, throw a TypeError." | 111 // "If |parsedURL| is failure, throw a TypeError." |
110 if (!parsedURL.isValid()) { | 112 if (!parsedURL.isValid()) { |
111 exceptionState.throwTypeError("Failed to parse URL from " + inputStr
ing); | 113 exceptionState.throwTypeError("Failed to parse URL from " + inputStr
ing); |
112 return nullptr; | 114 return nullptr; |
113 } | 115 } |
114 // TODO(yhirano): "3. If |parsedURL| includes credentials, throw a | 116 // TODO(yhirano): Implement the following substep: |
115 // TypeError." | 117 // "If |parsedURL| includes credentials, throw a TypeError." |
116 // "4. Set |request|'s url to |parsedURL|." | 118 // |
| 119 // "Set |request|'s url to |parsedURL| and replace |request|'s url list |
| 120 // single URL with a copy of |parsedURL|." |
117 request->setURL(parsedURL); | 121 request->setURL(parsedURL); |
118 // "5. Set |fallbackMode| to CORS." | 122 |
119 // "6. Set |fallbackCredentials| to omit." | |
120 // We don't use fallback values. We set these flags directly in below. | 123 // We don't use fallback values. We set these flags directly in below. |
| 124 // - "Set |fallbackMode| to "cors"." |
| 125 // - "Set |fallbackCredentials| to "omit"." |
121 } | 126 } |
122 | 127 |
123 // "14. If any of |init|'s members are present, run these substeps:" | 128 // "If any of |init|'s members are present, run these substeps:" |
124 if (init.areAnyMembersSet) { | 129 if (init.areAnyMembersSet) { |
125 // "1. If |request|'s |mode| is "navigate", throw a TypeError." | 130 // "If |request|'s |mode| is "navigate", throw a TypeError." |
126 if (request->mode() == WebURLRequest::FetchRequestModeNavigate) { | 131 if (request->mode() == WebURLRequest::FetchRequestModeNavigate) { |
127 exceptionState.throwTypeError("Cannot construct a Request with a Req
uest whose mode is 'navigate' and a non-empty RequestInit."); | 132 exceptionState.throwTypeError("Cannot construct a Request with a Req
uest whose mode is 'navigate' and a non-empty RequestInit."); |
128 return nullptr; | 133 return nullptr; |
129 } | 134 } |
130 // "2. Unset |request|'s omit-Origin-header flag." | 135 |
131 // "3. Set |request|'s referrer to "client"." | 136 // TODO(yhirano): Implement the following substep: |
132 // "4. Set |request|'s referrer policy to the empty string." | 137 // "Unset |request|'s omit-Origin-header flag." |
133 // => RequestInit::RequestInit. | 138 |
| 139 // The substep "Set |request|'s referrer to "client"." is performed by |
| 140 // the code below as follows: |
| 141 // - |init.referrer.referrer| gets initialized by the RequestInit |
| 142 // constructor to "about:client" when any of |options|'s members are |
| 143 // present. |
| 144 // - The code below does the equivalent as the step specified in the |
| 145 // spec by processing the "about:client". |
| 146 |
| 147 // The substep "Set |request|'s referrer policy to the empty string." |
| 148 // is also performed by the code below similarly. |
134 } | 149 } |
135 | 150 |
136 // 15. If |init|'s referrer member is present, run these substeps: | 151 // The following if-clause performs the following two steps: |
137 // Note that JS null and undefined are encoded as an empty string and thus | 152 // - "If |init|'s referrer member is present, run these substeps:" |
138 // a null string means referrer member is not set. | 153 // - TODO(yhirano): Implement the following step: |
139 // 16. If |init|'s referrerPolicy member is present, set |request|'s | 154 // "If |init|'s referrerPolicy member is present, set |request|'s |
140 // referrer policy to it. | 155 // referrer policy to it." |
141 // areAnyMembersSet will be True, if any members in RequestInit are set and | 156 // |
142 // hence the referrer member | 157 // The condition "if any of |init|'s members are present" |
| 158 // (areAnyMembersSet) is used for the if-clause instead of conditions |
| 159 // indicating presence of each member as specified in the spec. This is to |
| 160 // perform the substeps in the previous step together here. |
143 if (init.areAnyMembersSet) { | 161 if (init.areAnyMembersSet) { |
144 // 1. Let |referrer| be |init|'s referrer member. | 162 // Nothing to do for the step "Let |referrer| be |init|'s referrer |
| 163 // member." |
| 164 |
145 if (init.referrer.referrer.isEmpty()) { | 165 if (init.referrer.referrer.isEmpty()) { |
146 // 2. if |referrer| is the empty string, set |request|'s referrer to | 166 // "If |referrer| is the empty string, set |request|'s referrer to |
147 // "no-referrer" and terminate these substeps. | 167 // "no-referrer" and terminate these substeps." |
148 request->setReferrerString(FetchRequestData::noReferrerString()); | 168 request->setReferrerString(FetchRequestData::noReferrerString()); |
149 } else { | 169 } else { |
150 // 3. Let |parsedReferrer| be the result of parsing |referrer| with | 170 // "Let |parsedReferrer| be the result of parsing |referrer| with |
151 // |baseURL|. | 171 // |baseURL|." |
152 KURL parsedReferrer = scriptState->executionContext()->completeURL(i
nit.referrer.referrer); | 172 KURL parsedReferrer = scriptState->executionContext()->completeURL(i
nit.referrer.referrer); |
153 if (!parsedReferrer.isValid()) { | 173 if (!parsedReferrer.isValid()) { |
154 // 4. If |parsedReferrer| is failure, throw a TypeError. | 174 // "If |parsedReferrer| is failure, throw a TypeError." |
155 exceptionState.throwTypeError("Referrer '" + init.referrer.refer
rer + "' is not a valid URL."); | 175 exceptionState.throwTypeError("Referrer '" + init.referrer.refer
rer + "' is not a valid URL."); |
156 return nullptr; | 176 return nullptr; |
157 } | 177 } |
158 if (parsedReferrer.protocolIsAbout() && parsedReferrer.host().isEmpt
y() && parsedReferrer.path() == "client") { | 178 if (parsedReferrer.protocolIsAbout() && parsedReferrer.host().isEmpt
y() && parsedReferrer.path() == "client") { |
159 // 5. If |parsedReferrer|'s non-relative flag is set, scheme is | 179 // "If |parsedReferrer|'s non-relative flag is set, scheme is |
160 // "about", and path contains a single string "client", set | 180 // "about", and path contains a single string "client", set |
161 // request's referrer to "client" and terminate these substeps. | 181 // request's referrer to "client" and terminate these |
| 182 // substeps." |
162 request->setReferrerString(FetchRequestData::clientReferrerStrin
g()); | 183 request->setReferrerString(FetchRequestData::clientReferrerStrin
g()); |
163 } else if (!origin->isSameSchemeHostPortAndSuborigin(SecurityOrigin:
:create(parsedReferrer).get())) { | 184 } else if (!origin->isSameSchemeHostPortAndSuborigin(SecurityOrigin:
:create(parsedReferrer).get())) { |
164 // 6. If |parsedReferrer|'s origin is not same origin with | 185 // "If |parsedReferrer|'s origin is not same origin with |
165 // |origin|, throw a TypeError. | 186 // |origin|, throw a TypeError." |
166 exceptionState.throwTypeError("The origin of '" + init.referrer.
referrer + "' should be same as '" + origin->toString() + "'"); | 187 exceptionState.throwTypeError("The origin of '" + init.referrer.
referrer + "' should be same as '" + origin->toString() + "'"); |
167 return nullptr; | 188 return nullptr; |
168 } else { | 189 } else { |
169 // 7. Set |request|'s referrer to |parsedReferrer|. | 190 // "Set |request|'s referrer to |parsedReferrer|." |
170 request->setReferrerString(AtomicString(parsedReferrer.string())
); | 191 request->setReferrerString(AtomicString(parsedReferrer.string())
); |
171 } | 192 } |
172 } | 193 } |
173 request->setReferrerPolicy(init.referrer.referrerPolicy); | 194 request->setReferrerPolicy(init.referrer.referrerPolicy); |
174 } | 195 } |
175 | 196 |
176 // "16. Let |mode| be |init|'s mode member if it is present, and | 197 // The following code performs the following steps: |
177 // |fallbackMode| otherwise." | 198 // - "Let |mode| be |init|'s mode member if it is present, and |
178 // "17. If |mode| is "navigate", throw a TypeError. | 199 // |fallbackMode| otherwise." |
179 // "18. If |mode| is non-null, set |request|'s mode to |mode|." | 200 // - "If |mode| is "navigate", throw a TypeError." |
| 201 // - "If |mode| is non-null, set |request|'s mode to |mode|." |
180 if (init.mode == "navigate") { | 202 if (init.mode == "navigate") { |
181 exceptionState.throwTypeError("Cannot construct a Request with a Request
Init whose mode member is set as 'navigate'."); | 203 exceptionState.throwTypeError("Cannot construct a Request with a Request
Init whose mode member is set as 'navigate'."); |
182 return nullptr; | 204 return nullptr; |
183 } | 205 } |
184 if (init.mode == "same-origin") { | 206 if (init.mode == "same-origin") { |
185 request->setMode(WebURLRequest::FetchRequestModeSameOrigin); | 207 request->setMode(WebURLRequest::FetchRequestModeSameOrigin); |
186 } else if (init.mode == "no-cors") { | 208 } else if (init.mode == "no-cors") { |
187 request->setMode(WebURLRequest::FetchRequestModeNoCORS); | 209 request->setMode(WebURLRequest::FetchRequestModeNoCORS); |
188 } else if (init.mode == "cors") { | 210 } else if (init.mode == "cors") { |
189 request->setMode(WebURLRequest::FetchRequestModeCORS); | 211 request->setMode(WebURLRequest::FetchRequestModeCORS); |
190 } else { | 212 } else { |
| 213 // |inputRequest| is directly checked here instead of setting and |
| 214 // checking |fallbackMode| as specified in the spec. |
191 if (!inputRequest) | 215 if (!inputRequest) |
192 request->setMode(WebURLRequest::FetchRequestModeCORS); | 216 request->setMode(WebURLRequest::FetchRequestModeCORS); |
193 } | 217 } |
194 | 218 |
195 // "19. Let |credentials| be |init|'s credentials member if it is present, | 219 // "Let |credentials| be |init|'s credentials member if it is present, and |
196 // and |fallbackCredentials| otherwise." | 220 // |fallbackCredentials| otherwise." |
197 // "20. If |credentials| is non-null, set |request|'s credentials mode to | 221 // "If |credentials| is non-null, set |request|'s credentials mode to |
198 // |credentials|. | 222 // |credentials|." |
199 if (init.credentials == "omit") { | 223 if (init.credentials == "omit") { |
200 request->setCredentials(WebURLRequest::FetchCredentialsModeOmit); | 224 request->setCredentials(WebURLRequest::FetchCredentialsModeOmit); |
201 } else if (init.credentials == "same-origin") { | 225 } else if (init.credentials == "same-origin") { |
202 request->setCredentials(WebURLRequest::FetchCredentialsModeSameOrigin); | 226 request->setCredentials(WebURLRequest::FetchCredentialsModeSameOrigin); |
203 } else if (init.credentials == "include") { | 227 } else if (init.credentials == "include") { |
204 request->setCredentials(WebURLRequest::FetchCredentialsModeInclude); | 228 request->setCredentials(WebURLRequest::FetchCredentialsModeInclude); |
205 } else { | 229 } else { |
206 if (!inputRequest) | 230 if (!inputRequest) |
207 request->setCredentials(WebURLRequest::FetchCredentialsModeOmit); | 231 request->setCredentials(WebURLRequest::FetchCredentialsModeOmit); |
208 } | 232 } |
209 | 233 |
210 // TODO(yhirano): "21. If |init|'s cache member is present, set |request|'s | 234 // TODO(yhirano): Implement the following step: |
211 // cache mode to it." | 235 // "If |init|'s cache member is present, set |request|'s cache mode to |
| 236 // it." |
212 | 237 |
213 // "22. If |init|'s redirect member is present, set |request|'s redirect | 238 // "If |init|'s redirect member is present, set |request|'s redirect mode |
214 // mode to it." | 239 // to it." |
215 if (init.redirect == "follow") { | 240 if (init.redirect == "follow") { |
216 request->setRedirect(WebURLRequest::FetchRedirectModeFollow); | 241 request->setRedirect(WebURLRequest::FetchRedirectModeFollow); |
217 } else if (init.redirect == "error") { | 242 } else if (init.redirect == "error") { |
218 request->setRedirect(WebURLRequest::FetchRedirectModeError); | 243 request->setRedirect(WebURLRequest::FetchRedirectModeError); |
219 } else if (init.redirect == "manual") { | 244 } else if (init.redirect == "manual") { |
220 request->setRedirect(WebURLRequest::FetchRedirectModeManual); | 245 request->setRedirect(WebURLRequest::FetchRedirectModeManual); |
221 } | 246 } |
222 | 247 |
223 // "If |init|'s integrity member is present, set |request|'s | 248 // "If |init|'s integrity member is present, set |request|'s |
224 // integrity metadata to it." | 249 // integrity metadata to it." |
225 if (!init.integrity.isNull()) | 250 if (!init.integrity.isNull()) |
226 request->setIntegrity(init.integrity); | 251 request->setIntegrity(init.integrity); |
227 | 252 |
228 // "24. If |init|'s method member is present, let |method| be it and run | 253 // "If |init|'s method member is present, let |method| be it and run these |
229 // these substeps:" | 254 // substeps:" |
230 if (!init.method.isNull()) { | 255 if (!init.method.isNull()) { |
231 // "1. If |method| is not a method or method is a forbidden method, | 256 // "If |method| is not a method or method is a forbidden method, throw |
232 // throw a TypeError." | 257 // a TypeError." |
233 if (!isValidHTTPToken(init.method)) { | 258 if (!isValidHTTPToken(init.method)) { |
234 exceptionState.throwTypeError("'" + init.method + "' is not a valid
HTTP method."); | 259 exceptionState.throwTypeError("'" + init.method + "' is not a valid
HTTP method."); |
235 return nullptr; | 260 return nullptr; |
236 } | 261 } |
237 if (FetchUtils::isForbiddenMethod(init.method)) { | 262 if (FetchUtils::isForbiddenMethod(init.method)) { |
238 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); | 263 exceptionState.throwTypeError("'" + init.method + "' HTTP method is
unsupported."); |
239 return nullptr; | 264 return nullptr; |
240 } | 265 } |
241 // "2. Normalize |method|." | 266 // "Normalize |method|." |
242 // "3. Set |request|'s method to |method|." | 267 // "Set |request|'s method to |method|." |
243 request->setMethod(FetchUtils::normalizeMethod(AtomicString(init.method)
)); | 268 request->setMethod(FetchUtils::normalizeMethod(AtomicString(init.method)
)); |
244 } | 269 } |
245 // "25. Let |r| be a new Request object associated with |request| and a new | 270 // "Let |r| be a new Request object associated with |request| and a new |
246 // Headers object whose guard is request." | 271 // Headers object whose guard is "request"." |
247 Request* r = Request::create(scriptState->executionContext(), request); | 272 Request* r = Request::create(scriptState->executionContext(), request); |
248 // "26. Let |headers| be a copy of |r|'s Headers object." | 273 // Perform the following steps: |
249 // "27. If |init|'s headers member is present, set |headers| to |init|'s | 274 // - "Let |headers| be a copy of |r|'s Headers object." |
250 // headers member." | 275 // - "If |init|'s headers member is present, set |headers| to |init|'s |
| 276 // headers member." |
| 277 // |
251 // We don't create a copy of r's Headers object when init's headers member | 278 // We don't create a copy of r's Headers object when init's headers member |
252 // is present. | 279 // is present. |
253 Headers* headers = nullptr; | 280 Headers* headers = nullptr; |
254 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { | 281 if (!init.headers && init.headersDictionary.isUndefinedOrNull()) { |
255 headers = r->headers()->clone(); | 282 headers = r->headers()->clone(); |
256 } | 283 } |
257 // "28. Empty |r|'s request's header list." | 284 // "Empty |r|'s request's header list." |
258 r->m_request->headerList()->clearList(); | 285 r->m_request->headerList()->clearList(); |
259 // "29. If |r|'s request's mode is no CORS, run these substeps: | 286 // "If |r|'s request's mode is "no-cors", run these substeps: |
260 if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { | 287 if (r->request()->mode() == WebURLRequest::FetchRequestModeNoCORS) { |
261 // "1. If |r|'s request's method is not a simple method, throw a | 288 // "If |r|'s request's method is not a simple method, throw a |
262 // TypeError." | 289 // TypeError." |
263 if (!FetchUtils::isSimpleMethod(r->request()->method())) { | 290 if (!FetchUtils::isSimpleMethod(r->request()->method())) { |
264 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); | 291 exceptionState.throwTypeError("'" + r->request()->method() + "' is u
nsupported in no-cors mode."); |
265 return nullptr; | 292 return nullptr; |
266 } | 293 } |
267 // "2. If |request|'s integrity metadata is not the empty string, throw | 294 // "If |request|'s integrity metadata is not the empty string, throw a |
268 // a TypeError." | 295 // TypeError." |
269 if (!request->integrity().isEmpty()) { | 296 if (!request->integrity().isEmpty()) { |
270 exceptionState.throwTypeError("The integrity attribute is unsupporte
d in no-cors mode."); | 297 exceptionState.throwTypeError("The integrity attribute is unsupporte
d in no-cors mode."); |
271 return nullptr; | 298 return nullptr; |
272 } | 299 } |
273 // "3. Set |r|'s Headers object's guard to |request-no-CORS|. | 300 // "Set |r|'s Headers object's guard to "request-no-cors"." |
274 r->headers()->setGuard(Headers::RequestNoCORSGuard); | 301 r->headers()->setGuard(Headers::RequestNoCORSGuard); |
275 } | 302 } |
276 // "30. Fill |r|'s Headers object with |headers|. Rethrow any exceptions." | 303 // "Fill |r|'s Headers object with |headers|. Rethrow any exceptions." |
277 if (init.headers) { | 304 if (init.headers) { |
278 ASSERT(init.headersDictionary.isUndefinedOrNull()); | 305 ASSERT(init.headersDictionary.isUndefinedOrNull()); |
279 r->headers()->fillWith(init.headers.get(), exceptionState); | 306 r->headers()->fillWith(init.headers.get(), exceptionState); |
280 } else if (!init.headersDictionary.isUndefinedOrNull()) { | 307 } else if (!init.headersDictionary.isUndefinedOrNull()) { |
281 r->headers()->fillWith(init.headersDictionary, exceptionState); | 308 r->headers()->fillWith(init.headersDictionary, exceptionState); |
282 } else { | 309 } else { |
283 ASSERT(headers); | 310 ASSERT(headers); |
284 r->headers()->fillWith(headers, exceptionState); | 311 r->headers()->fillWith(headers, exceptionState); |
285 } | 312 } |
286 if (exceptionState.hadException()) | 313 if (exceptionState.hadException()) |
287 return nullptr; | 314 return nullptr; |
288 | 315 |
289 // "31. If either |init|'s body member is present or |temporaryBody| is | 316 // "If either |init|'s body member is present or |temporaryBody| is |
290 // non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError. | 317 // non-null, and |request|'s method is `GET` or `HEAD`, throw a TypeError. |
291 if (init.body || temporaryBody) { | 318 if (init.body || temporaryBody) { |
292 if (request->method() == "GET" || request->method() == "HEAD") { | 319 if (request->method() == "GET" || request->method() == "HEAD") { |
293 exceptionState.throwTypeError("Request with GET/HEAD method cannot h
ave body."); | 320 exceptionState.throwTypeError("Request with GET/HEAD method cannot h
ave body."); |
294 return nullptr; | 321 return nullptr; |
295 } | 322 } |
296 } | 323 } |
297 | 324 |
298 // "32. If |init|'s body member is present, run these substeps:" | 325 // "If |init|'s body member is present, run these substeps:" |
299 if (init.body) { | 326 if (init.body) { |
300 // "1. Let |stream| and |Content-Type| be the result of extracting | 327 // Perform the following steps: |
301 // |init|'s body member." | 328 // - "Let |stream| and |Content-Type| be the result of extracting |
302 // "2. Set |temporaryBody| to |stream|. | 329 // |init|'s body member." |
303 // "3. If |Content-Type| is non-null and |r|'s request's header list | 330 // - "Set |temporaryBody| to |stream|. |
304 // contains no header named `Content-Type`, append | 331 // - "If |Content-Type| is non-null and |r|'s request's header list |
305 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any | 332 // contains no header named `Content-Type`, append |
306 // exception." | 333 // `Content-Type`/|Content-Type| to |r|'s Headers object. Rethrow any |
| 334 // exception." |
307 temporaryBody = new BodyStreamBuffer(init.body.release()); | 335 temporaryBody = new BodyStreamBuffer(init.body.release()); |
308 if (!init.contentType.isEmpty() && !r->headers()->has("Content-Type", ex
ceptionState)) { | 336 if (!init.contentType.isEmpty() && !r->headers()->has("Content-Type", ex
ceptionState)) { |
309 r->headers()->append("Content-Type", init.contentType, exceptionStat
e); | 337 r->headers()->append("Content-Type", init.contentType, exceptionStat
e); |
310 } | 338 } |
311 if (exceptionState.hadException()) | 339 if (exceptionState.hadException()) |
312 return nullptr; | 340 return nullptr; |
313 } | 341 } |
314 | 342 |
315 // "33. Set |r|'s body to |temporaryBody|. | 343 // "Set |r|'s request's body to |temporaryBody|. |
316 if (temporaryBody) | 344 if (temporaryBody) |
317 r->m_request->setBuffer(temporaryBody); | 345 r->m_request->setBuffer(temporaryBody); |
318 | 346 |
319 // https://w3c.github.io/webappsec-credential-management/#monkey-patching-fe
tch-3 | 347 // https://w3c.github.io/webappsec-credential-management/#monkey-patching-fe
tch-3 |
320 // "If |init|'s body member is a 'Credential' object:" | 348 // "If |init|'s body member is a 'Credential' object:" |
321 if (init.isCredentialRequest) { | 349 if (init.isCredentialRequest) { |
322 // "1. If |r|'s url is not the same as |r|'s client’s origin, throw a Ty
peError." | 350 // "1. If |r|'s url is not the same as |r|'s client’s origin, throw a Ty
peError." |
323 if (!origin->canRequest(r->url())) { | 351 if (!origin->canRequest(r->url())) { |
324 exceptionState.throwTypeError("Credentials may only be submitted to
same-origin endpoints."); | 352 exceptionState.throwTypeError("Credentials may only be submitted to
same-origin endpoints."); |
325 return nullptr; | 353 return nullptr; |
326 } | 354 } |
327 // "2. Set |r|'s redirect mode to "error"." | 355 // "2. Set |r|'s redirect mode to "error"." |
328 r->m_request->setRedirect(WebURLRequest::FetchRedirectModeError); | 356 r->m_request->setRedirect(WebURLRequest::FetchRedirectModeError); |
329 // "3. Set |r|'s skip-service-worker flag." | 357 // "3. Set |r|'s skip-service-worker flag." |
330 // TODO(mkwst): Set this flag. | 358 // TODO(mkwst): Set this flag. |
331 // "4. Set |r|'s opaque flag." | 359 // "4. Set |r|'s opaque flag." |
332 r->setOpaque(); | 360 r->setOpaque(); |
333 } | 361 } |
334 | 362 |
335 // "34. Set |r|'s MIME type to the result of extracting a MIME type from | 363 // "Set |r|'s MIME type to the result of extracting a MIME type from |r|'s |
336 // |r|'s request's header list." | 364 // request's header list." |
337 r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType()); | 365 r->m_request->setMIMEType(r->m_request->headerList()->extractMIMEType()); |
338 | 366 |
339 // "35. If |input| is a Request object and |input|'s body is non-null, run | 367 // "If |input| is a Request object and |input|'s request's body is |
340 // these substeps:" | 368 // non-null, run these substeps:" |
| 369 // |
341 // We set bodyUsed even when the body is null in spite of the | 370 // We set bodyUsed even when the body is null in spite of the |
342 // spec. See https://github.com/whatwg/fetch/issues/61 for details. | 371 // spec. See https://github.com/whatwg/fetch/issues/61 for details. |
343 if (inputRequest) { | 372 if (inputRequest) { |
344 // "1. Set |input|'s body to null." | 373 // "Set |input|'s body to an empty byte stream." |
345 inputRequest->m_request->setBuffer(nullptr); | 374 inputRequest->m_request->setBuffer(nullptr); |
346 // "2. Set |input|'s used flag." | 375 // "Set |input|'s disturbed flag." |
347 inputRequest->setBodyPassed(); | 376 inputRequest->setBodyPassed(); |
348 } | 377 } |
349 | 378 |
350 // "36. Return |r|." | 379 // "Return |r|." |
351 return r; | 380 return r; |
352 } | 381 } |
353 | 382 |
354 Request* Request::create(ScriptState* scriptState, const RequestInfo& input, con
st Dictionary& init, ExceptionState& exceptionState) | 383 Request* Request::create(ScriptState* scriptState, const RequestInfo& input, con
st Dictionary& init, ExceptionState& exceptionState) |
355 { | 384 { |
356 ASSERT(!input.isNull()); | 385 ASSERT(!input.isNull()); |
357 if (input.isUSVString()) | 386 if (input.isUSVString()) |
358 return create(scriptState, input.getAsUSVString(), init, exceptionState)
; | 387 return create(scriptState, input.getAsUSVString(), init, exceptionState)
; |
359 return create(scriptState, input.getAsRequest(), init, exceptionState); | 388 return create(scriptState, input.getAsRequest(), init, exceptionState); |
360 } | 389 } |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 } | 648 } |
620 | 649 |
621 DEFINE_TRACE(Request) | 650 DEFINE_TRACE(Request) |
622 { | 651 { |
623 Body::trace(visitor); | 652 Body::trace(visitor); |
624 visitor->trace(m_request); | 653 visitor->trace(m_request); |
625 visitor->trace(m_headers); | 654 visitor->trace(m_headers); |
626 } | 655 } |
627 | 656 |
628 } // namespace blink | 657 } // namespace blink |
OLD | NEW |