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 "modules/fetch/FetchManager.h" | 5 #include "modules/fetch/FetchManager.h" |
6 | 6 |
7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
8 #include "bindings/core/v8/ScriptPromiseResolver.h" | 8 #include "bindings/core/v8/ScriptPromiseResolver.h" |
9 #include "bindings/core/v8/ScriptState.h" | 9 #include "bindings/core/v8/ScriptState.h" |
10 #include "bindings/core/v8/V8ThrowException.h" | 10 #include "bindings/core/v8/V8ThrowException.h" |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 performNetworkError("Blob not found."); | 216 performNetworkError("Blob not found."); |
217 return; | 217 return; |
218 } | 218 } |
219 | 219 |
220 if (response.url().protocolIs("blob") && response.httpStatusCode() == 405) { | 220 if (response.url().protocolIs("blob") && response.httpStatusCode() == 405) { |
221 performNetworkError("Only 'GET' method is allowed for blob URLs."); | 221 performNetworkError("Only 'GET' method is allowed for blob URLs."); |
222 return; | 222 return; |
223 } | 223 } |
224 | 224 |
225 m_responseHttpStatusCode = response.httpStatusCode(); | 225 m_responseHttpStatusCode = response.httpStatusCode(); |
226 FetchRequestData::Tainting tainting = m_request->responseTainting(); | |
226 | 227 |
227 if (response.url().protocolIsData()) { | 228 if (response.url().protocolIsData()) { |
228 if (m_request->url() == response.url()) { | 229 if (m_request->url() == response.url()) { |
229 // A direct request to data. | 230 // A direct request to data. |
230 m_request->setResponseTainting(FetchRequestData::BasicTainting); | 231 tainting = FetchRequestData::BasicTainting; |
231 } else { | 232 } else { |
232 // A redirect to data: scheme occured. | 233 // A redirect to data: scheme occured. |
233 // Redirects to data URLs are rejected by the spec because | 234 // Redirects to data URLs are rejected by the spec because |
234 // same-origin data-URL flag is unset, except for no-cors mode. | 235 // same-origin data-URL flag is unset, except for no-cors mode. |
235 // TODO(hiroshige): currently redirects to data URLs in no-cors | 236 // TODO(hiroshige): currently redirects to data URLs in no-cors |
236 // mode is also rejected by Chromium side. | 237 // mode is also rejected by Chromium side. |
237 switch (m_request->mode()) { | 238 switch (m_request->mode()) { |
238 case WebURLRequest::FetchRequestModeNoCORS: | 239 case WebURLRequest::FetchRequestModeNoCORS: |
239 m_request->setResponseTainting(FetchRequestData::OpaqueTainting) ; | 240 tainting = FetchRequestData::OpaqueTainting; |
240 break; | 241 break; |
241 case WebURLRequest::FetchRequestModeSameOrigin: | 242 case WebURLRequest::FetchRequestModeSameOrigin: |
242 case WebURLRequest::FetchRequestModeCORS: | 243 case WebURLRequest::FetchRequestModeCORS: |
243 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: | 244 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: |
244 case WebURLRequest::FetchRequestModeNavigate: | 245 case WebURLRequest::FetchRequestModeNavigate: |
245 performNetworkError("Fetch API cannot load " + m_request->url(). getString() + ". Redirects to data: URL are allowed only when mode is \"no-cors\ "."); | 246 performNetworkError("Fetch API cannot load " + m_request->url(). getString() + ". Redirects to data: URL are allowed only when mode is \"no-cors\ "."); |
246 return; | 247 return; |
247 } | 248 } |
248 } | 249 } |
249 } else if (!SecurityOrigin::create(response.url())->isSameSchemeHostPort(m_r equest->origin().get())) { | 250 } else if (!SecurityOrigin::create(response.url())->isSameSchemeHostPort(m_r equest->origin().get())) { |
250 // Recompute the tainting if the request was redirected to a different | 251 // Recompute the tainting if the request was redirected to a different |
251 // origin. | 252 // origin. |
252 switch (m_request->mode()) { | 253 switch (m_request->mode()) { |
253 case WebURLRequest::FetchRequestModeSameOrigin: | 254 case WebURLRequest::FetchRequestModeSameOrigin: |
254 ASSERT_NOT_REACHED(); | 255 ASSERT_NOT_REACHED(); |
255 break; | 256 break; |
256 case WebURLRequest::FetchRequestModeNoCORS: | 257 case WebURLRequest::FetchRequestModeNoCORS: |
257 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); | 258 tainting = FetchRequestData::OpaqueTainting; |
258 break; | 259 break; |
259 case WebURLRequest::FetchRequestModeCORS: | 260 case WebURLRequest::FetchRequestModeCORS: |
260 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: | 261 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: |
261 m_request->setResponseTainting(FetchRequestData::CORSTainting); | 262 tainting = FetchRequestData::CORSTainting; |
262 break; | 263 break; |
263 case WebURLRequest::FetchRequestModeNavigate: | 264 case WebURLRequest::FetchRequestModeNavigate: |
264 RELEASE_ASSERT_NOT_REACHED(); | 265 RELEASE_ASSERT_NOT_REACHED(); |
265 break; | 266 break; |
266 } | 267 } |
267 } | 268 } |
269 if (response.wasFetchedViaServiceWorker()) { | |
270 switch (response.serviceWorkerResponseType()) { | |
tyoshino (SeeGerritForStatus)
2016/03/07 14:48:22
it looks good to just honor the tainting of the re
horo
2016/03/08 03:11:02
+CC:mek@
According to https://github.com/slightly
tyoshino (SeeGerritForStatus)
2016/03/08 05:30:05
Great! Thanks for the explanation.
| |
271 case WebServiceWorkerResponseTypeBasic: | |
272 case WebServiceWorkerResponseTypeDefault: | |
273 tainting = FetchRequestData::BasicTainting; | |
274 break; | |
275 case WebServiceWorkerResponseTypeCORS: | |
276 tainting = FetchRequestData::CORSTainting; | |
277 break; | |
278 case WebServiceWorkerResponseTypeOpaque: | |
279 tainting = FetchRequestData::OpaqueTainting; | |
280 break; | |
281 case WebServiceWorkerResponseTypeOpaqueRedirect: | |
282 // ServiceWorker can't respond to the request from fetch() with an o paque redirect response. | |
tyoshino (SeeGerritForStatus)
2016/03/07 14:48:22
let's wrap comments to fit 80 col
horo
2016/03/08 03:11:02
Done.
| |
283 case WebServiceWorkerResponseTypeError: | |
284 // When ServiceWorker respond to the request from fetch() with an er ror response, FetchManager::Loader::didFail() must be called instead. | |
tyoshino (SeeGerritForStatus)
2016/03/07 14:48:22
let's wrap comments to fit 80 col
horo
2016/03/08 03:11:02
Done.
| |
285 RELEASE_ASSERT_NOT_REACHED(); | |
286 break; | |
287 } | |
288 } | |
268 | 289 |
269 FetchResponseData* responseData = nullptr; | 290 FetchResponseData* responseData = nullptr; |
270 CompositeDataConsumerHandle::Updater* updater = nullptr; | 291 CompositeDataConsumerHandle::Updater* updater = nullptr; |
271 if (m_request->integrity().isEmpty()) | 292 if (m_request->integrity().isEmpty()) |
272 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( createFetchDataConsumerHandleFromWebHandle(handle))); | 293 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( createFetchDataConsumerHandleFromWebHandle(handle))); |
273 else | 294 else |
274 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( createFetchDataConsumerHandleFromWebHandle(CompositeDataConsumerHandle::create(c reateWaitingDataConsumerHandle(), &updater)))); | 295 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( createFetchDataConsumerHandleFromWebHandle(CompositeDataConsumerHandle::create(c reateWaitingDataConsumerHandle(), &updater)))); |
275 responseData->setStatus(response.httpStatusCode()); | 296 responseData->setStatus(response.httpStatusCode()); |
276 responseData->setStatusMessage(response.httpStatusText()); | 297 responseData->setStatusMessage(response.httpStatusText()); |
277 for (auto& it : response.httpHeaderFields()) | 298 for (auto& it : response.httpHeaderFields()) |
(...skipping 17 matching lines...) Expand all Loading... | |
295 performNetworkError("Invalid Location header."); | 316 performNetworkError("Invalid Location header."); |
296 return; | 317 return; |
297 } | 318 } |
298 ASSERT(m_request->redirect() == WebURLRequest::FetchRedirectModeManu al); | 319 ASSERT(m_request->redirect() == WebURLRequest::FetchRedirectModeManu al); |
299 taintedResponse = responseData->createOpaqueRedirectFilteredResponse (); | 320 taintedResponse = responseData->createOpaqueRedirectFilteredResponse (); |
300 } | 321 } |
301 // When the location header doesn't exist, we don't treat the response | 322 // When the location header doesn't exist, we don't treat the response |
302 // as a redirect response, and execute tainting. | 323 // as a redirect response, and execute tainting. |
303 } | 324 } |
304 if (!taintedResponse) { | 325 if (!taintedResponse) { |
305 switch (m_request->responseTainting()) { | 326 switch (tainting) { |
306 case FetchRequestData::BasicTainting: | 327 case FetchRequestData::BasicTainting: |
307 taintedResponse = responseData->createBasicFilteredResponse(); | 328 taintedResponse = responseData->createBasicFilteredResponse(); |
308 break; | 329 break; |
309 case FetchRequestData::CORSTainting: | 330 case FetchRequestData::CORSTainting: |
310 taintedResponse = responseData->createCORSFilteredResponse(); | 331 taintedResponse = responseData->createCORSFilteredResponse(); |
311 break; | 332 break; |
312 case FetchRequestData::OpaqueTainting: | 333 case FetchRequestData::OpaqueTainting: |
313 taintedResponse = responseData->createOpaqueFilteredResponse(); | 334 taintedResponse = responseData->createOpaqueFilteredResponse(); |
314 break; | 335 break; |
315 } | 336 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
525 ASSERT(SchemeRegistry::shouldTreatURLSchemeAsSupportingFetchAPI(m_request->u rl().protocol()) || (m_request->url().protocolIs("blob") && !corsFlag && !corsPr eflightFlag)); | 546 ASSERT(SchemeRegistry::shouldTreatURLSchemeAsSupportingFetchAPI(m_request->u rl().protocol()) || (m_request->url().protocolIs("blob") && !corsFlag && !corsPr eflightFlag)); |
526 // CORS preflight fetch procedure is implemented inside DocumentThreadableLo ader. | 547 // CORS preflight fetch procedure is implemented inside DocumentThreadableLo ader. |
527 | 548 |
528 // "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s | 549 // "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s |
529 // body is a tee of |request|'s body." | 550 // body is a tee of |request|'s body." |
530 // We use ResourceRequest class for HTTPRequest. | 551 // We use ResourceRequest class for HTTPRequest. |
531 // FIXME: Support body. | 552 // FIXME: Support body. |
532 ResourceRequest request(m_request->url()); | 553 ResourceRequest request(m_request->url()); |
533 request.setRequestContext(m_request->context()); | 554 request.setRequestContext(m_request->context()); |
534 request.setHTTPMethod(m_request->method()); | 555 request.setHTTPMethod(m_request->method()); |
556 request.setFetchRequestMode(m_request->mode()); | |
557 request.setFetchCredentialsMode(m_request->credentials()); | |
535 const Vector<OwnPtr<FetchHeaderList::Header>>& list = m_request->headerList( )->list(); | 558 const Vector<OwnPtr<FetchHeaderList::Header>>& list = m_request->headerList( )->list(); |
536 for (size_t i = 0; i < list.size(); ++i) { | 559 for (size_t i = 0; i < list.size(); ++i) { |
537 request.addHTTPHeaderField(AtomicString(list[i]->first), AtomicString(li st[i]->second)); | 560 request.addHTTPHeaderField(AtomicString(list[i]->first), AtomicString(li st[i]->second)); |
538 } | 561 } |
539 | 562 |
540 if (m_request->method() != HTTPNames::GET && m_request->method() != HTTPName s::HEAD) { | 563 if (m_request->method() != HTTPNames::GET && m_request->method() != HTTPName s::HEAD) { |
541 if (m_request->buffer()) { | 564 if (m_request->buffer()) { |
542 request.setHTTPBody(m_request->buffer()->drainAsFormData()); | 565 request.setHTTPBody(m_request->buffer()->drainAsFormData()); |
543 } | 566 } |
544 } | 567 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 loader->dispose(); | 744 loader->dispose(); |
722 } | 745 } |
723 | 746 |
724 DEFINE_TRACE(FetchManager) | 747 DEFINE_TRACE(FetchManager) |
725 { | 748 { |
726 visitor->trace(m_loaders); | 749 visitor->trace(m_loaders); |
727 ContextLifecycleObserver::trace(visitor); | 750 ContextLifecycleObserver::trace(visitor); |
728 } | 751 } |
729 | 752 |
730 } // namespace blink | 753 } // namespace blink |
OLD | NEW |