| 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()) { |
| 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 |
| 283 // opaque redirect response. |
| 284 case WebServiceWorkerResponseTypeError: |
| 285 // When ServiceWorker respond to the request from fetch() with an |
| 286 // error response, FetchManager::Loader::didFail() must be called |
| 287 // instead. |
| 288 RELEASE_ASSERT_NOT_REACHED(); |
| 289 break; |
| 290 } |
| 291 } |
| 268 | 292 |
| 269 FetchResponseData* responseData = nullptr; | 293 FetchResponseData* responseData = nullptr; |
| 270 CompositeDataConsumerHandle::Updater* updater = nullptr; | 294 CompositeDataConsumerHandle::Updater* updater = nullptr; |
| 271 if (m_request->integrity().isEmpty()) | 295 if (m_request->integrity().isEmpty()) |
| 272 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
createFetchDataConsumerHandleFromWebHandle(handle))); | 296 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
createFetchDataConsumerHandleFromWebHandle(handle))); |
| 273 else | 297 else |
| 274 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
createFetchDataConsumerHandleFromWebHandle(CompositeDataConsumerHandle::create(c
reateWaitingDataConsumerHandle(), &updater)))); | 298 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer(
createFetchDataConsumerHandleFromWebHandle(CompositeDataConsumerHandle::create(c
reateWaitingDataConsumerHandle(), &updater)))); |
| 275 responseData->setStatus(response.httpStatusCode()); | 299 responseData->setStatus(response.httpStatusCode()); |
| 276 responseData->setStatusMessage(response.httpStatusText()); | 300 responseData->setStatusMessage(response.httpStatusText()); |
| 277 for (auto& it : response.httpHeaderFields()) | 301 for (auto& it : response.httpHeaderFields()) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 295 performNetworkError("Invalid Location header."); | 319 performNetworkError("Invalid Location header."); |
| 296 return; | 320 return; |
| 297 } | 321 } |
| 298 ASSERT(m_request->redirect() == WebURLRequest::FetchRedirectModeManu
al); | 322 ASSERT(m_request->redirect() == WebURLRequest::FetchRedirectModeManu
al); |
| 299 taintedResponse = responseData->createOpaqueRedirectFilteredResponse
(); | 323 taintedResponse = responseData->createOpaqueRedirectFilteredResponse
(); |
| 300 } | 324 } |
| 301 // When the location header doesn't exist, we don't treat the response | 325 // When the location header doesn't exist, we don't treat the response |
| 302 // as a redirect response, and execute tainting. | 326 // as a redirect response, and execute tainting. |
| 303 } | 327 } |
| 304 if (!taintedResponse) { | 328 if (!taintedResponse) { |
| 305 switch (m_request->responseTainting()) { | 329 switch (tainting) { |
| 306 case FetchRequestData::BasicTainting: | 330 case FetchRequestData::BasicTainting: |
| 307 taintedResponse = responseData->createBasicFilteredResponse(); | 331 taintedResponse = responseData->createBasicFilteredResponse(); |
| 308 break; | 332 break; |
| 309 case FetchRequestData::CORSTainting: | 333 case FetchRequestData::CORSTainting: |
| 310 taintedResponse = responseData->createCORSFilteredResponse(); | 334 taintedResponse = responseData->createCORSFilteredResponse(); |
| 311 break; | 335 break; |
| 312 case FetchRequestData::OpaqueTainting: | 336 case FetchRequestData::OpaqueTainting: |
| 313 taintedResponse = responseData->createOpaqueFilteredResponse(); | 337 taintedResponse = responseData->createOpaqueFilteredResponse(); |
| 314 break; | 338 break; |
| 315 } | 339 } |
| (...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)); | 549 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. | 550 // CORS preflight fetch procedure is implemented inside DocumentThreadableLo
ader. |
| 527 | 551 |
| 528 // "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s | 552 // "1. Let |HTTPRequest| be a copy of |request|, except that |HTTPRequest|'s |
| 529 // body is a tee of |request|'s body." | 553 // body is a tee of |request|'s body." |
| 530 // We use ResourceRequest class for HTTPRequest. | 554 // We use ResourceRequest class for HTTPRequest. |
| 531 // FIXME: Support body. | 555 // FIXME: Support body. |
| 532 ResourceRequest request(m_request->url()); | 556 ResourceRequest request(m_request->url()); |
| 533 request.setRequestContext(m_request->context()); | 557 request.setRequestContext(m_request->context()); |
| 534 request.setHTTPMethod(m_request->method()); | 558 request.setHTTPMethod(m_request->method()); |
| 559 request.setFetchRequestMode(m_request->mode()); |
| 560 request.setFetchCredentialsMode(m_request->credentials()); |
| 535 const Vector<OwnPtr<FetchHeaderList::Header>>& list = m_request->headerList(
)->list(); | 561 const Vector<OwnPtr<FetchHeaderList::Header>>& list = m_request->headerList(
)->list(); |
| 536 for (size_t i = 0; i < list.size(); ++i) { | 562 for (size_t i = 0; i < list.size(); ++i) { |
| 537 request.addHTTPHeaderField(AtomicString(list[i]->first), AtomicString(li
st[i]->second)); | 563 request.addHTTPHeaderField(AtomicString(list[i]->first), AtomicString(li
st[i]->second)); |
| 538 } | 564 } |
| 539 | 565 |
| 540 if (m_request->method() != HTTPNames::GET && m_request->method() != HTTPName
s::HEAD) { | 566 if (m_request->method() != HTTPNames::GET && m_request->method() != HTTPName
s::HEAD) { |
| 541 if (m_request->buffer()) { | 567 if (m_request->buffer()) { |
| 542 request.setHTTPBody(m_request->buffer()->drainAsFormData()); | 568 request.setHTTPBody(m_request->buffer()->drainAsFormData()); |
| 543 } | 569 } |
| 544 } | 570 } |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 loader->dispose(); | 747 loader->dispose(); |
| 722 } | 748 } |
| 723 | 749 |
| 724 DEFINE_TRACE(FetchManager) | 750 DEFINE_TRACE(FetchManager) |
| 725 { | 751 { |
| 726 visitor->trace(m_loaders); | 752 visitor->trace(m_loaders); |
| 727 ContextLifecycleObserver::trace(visitor); | 753 ContextLifecycleObserver::trace(visitor); |
| 728 } | 754 } |
| 729 | 755 |
| 730 } // namespace blink | 756 } // namespace blink |
| OLD | NEW |