Chromium Code Reviews| 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/FetchManager.h" | 6 #include "modules/fetch/FetchManager.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/ExceptionState.h" | 8 #include "bindings/core/v8/ExceptionState.h" |
| 9 #include "bindings/core/v8/ScriptPromiseResolver.h" | 9 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 10 #include "bindings/core/v8/ScriptState.h" | 10 #include "bindings/core/v8/ScriptState.h" |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 30 #include "modules/fetch/ResponseInit.h" | 30 #include "modules/fetch/ResponseInit.h" |
| 31 #include "platform/network/ResourceError.h" | 31 #include "platform/network/ResourceError.h" |
| 32 #include "platform/network/ResourceRequest.h" | 32 #include "platform/network/ResourceRequest.h" |
| 33 #include "platform/network/ResourceResponse.h" | 33 #include "platform/network/ResourceResponse.h" |
| 34 #include "platform/weborigin/SecurityOrigin.h" | 34 #include "platform/weborigin/SecurityOrigin.h" |
| 35 #include "public/platform/WebURLRequest.h" | 35 #include "public/platform/WebURLRequest.h" |
| 36 #include "wtf/HashSet.h" | 36 #include "wtf/HashSet.h" |
| 37 | 37 |
| 38 namespace blink { | 38 namespace blink { |
| 39 | 39 |
| 40 namespace { | |
| 41 | |
| 42 bool IsRedirectStatusCode(int statusCode) | |
| 43 { | |
| 44 return (statusCode == 301 || statusCode == 302 || statusCode == 303 || statu sCode == 307 || statusCode == 308); | |
| 45 } | |
| 46 | |
| 47 } // namespace | |
| 48 | |
| 49 class FetchManager::Loader final : public NoBaseWillBeGarbageCollectedFinalized< FetchManager::Loader>, public ThreadableLoaderClient, public ContextLifecycleObs erver { | 40 class FetchManager::Loader final : public NoBaseWillBeGarbageCollectedFinalized< FetchManager::Loader>, public ThreadableLoaderClient, public ContextLifecycleObs erver { |
| 50 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FetchManager::Loader); | 41 WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(FetchManager::Loader); |
| 51 public: | 42 public: |
| 52 static PassOwnPtrWillBeRawPtr<Loader> create(ExecutionContext* executionCont ext, FetchManager* fetchManager, ScriptPromiseResolver* resolver, FetchRequestDa ta* request) | 43 static PassOwnPtrWillBeRawPtr<Loader> create(ExecutionContext* executionCont ext, FetchManager* fetchManager, ScriptPromiseResolver* resolver, FetchRequestDa ta* request) |
| 53 { | 44 { |
| 54 return adoptPtrWillBeNoop(new Loader(executionContext, fetchManager, res olver, request)); | 45 return adoptPtrWillBeNoop(new Loader(executionContext, fetchManager, res olver, request)); |
| 55 } | 46 } |
| 56 | 47 |
| 57 ~Loader() override; | 48 ~Loader() override; |
| 58 DECLARE_VIRTUAL_TRACE(); | 49 DECLARE_VIRTUAL_TRACE(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 DEFINE_TRACE(FetchManager::Loader) | 95 DEFINE_TRACE(FetchManager::Loader) |
| 105 { | 96 { |
| 106 visitor->trace(m_fetchManager); | 97 visitor->trace(m_fetchManager); |
| 107 visitor->trace(m_resolver); | 98 visitor->trace(m_resolver); |
| 108 visitor->trace(m_request); | 99 visitor->trace(m_request); |
| 109 ContextLifecycleObserver::trace(visitor); | 100 ContextLifecycleObserver::trace(visitor); |
| 110 } | 101 } |
| 111 | 102 |
| 112 void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceRespo nse& response, PassOwnPtr<WebDataConsumerHandle> handle) | 103 void FetchManager::Loader::didReceiveResponse(unsigned long, const ResourceRespo nse& response, PassOwnPtr<WebDataConsumerHandle> handle) |
| 113 { | 104 { |
| 114 ASSERT(handle); | |
| 115 | |
| 116 m_responseHttpStatusCode = response.httpStatusCode(); | 105 m_responseHttpStatusCode = response.httpStatusCode(); |
|
yhirano
2015/08/18 07:56:49
Please keep the assertion.
horo
2015/08/19 07:36:12
Done.
| |
| 117 | 106 |
| 118 // Recompute the tainting if the request was redirected to a different | 107 // Recompute the tainting if the request was redirected to a different |
| 119 // origin. | 108 // origin. |
| 120 if (!SecurityOrigin::create(response.url())->isSameSchemeHostPort(m_request- >origin().get())) { | 109 if (!SecurityOrigin::create(response.url())->isSameSchemeHostPort(m_request- >origin().get())) { |
| 121 switch (m_request->mode()) { | 110 switch (m_request->mode()) { |
| 122 case WebURLRequest::FetchRequestModeSameOrigin: | 111 case WebURLRequest::FetchRequestModeSameOrigin: |
| 123 ASSERT_NOT_REACHED(); | 112 ASSERT_NOT_REACHED(); |
| 124 break; | 113 break; |
| 125 case WebURLRequest::FetchRequestModeNoCORS: | 114 case WebURLRequest::FetchRequestModeNoCORS: |
| 126 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); | 115 m_request->setResponseTainting(FetchRequestData::OpaqueTainting); |
| 127 break; | 116 break; |
| 128 case WebURLRequest::FetchRequestModeCORS: | 117 case WebURLRequest::FetchRequestModeCORS: |
| 129 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: | 118 case WebURLRequest::FetchRequestModeCORSWithForcedPreflight: |
| 130 m_request->setResponseTainting(FetchRequestData::CORSTainting); | 119 m_request->setResponseTainting(FetchRequestData::CORSTainting); |
| 131 break; | 120 break; |
| 132 } | 121 } |
| 133 } | 122 } |
| 134 FetchResponseData* responseData = FetchResponseData::createWithBuffer(new Bo dyStreamBuffer(createFetchDataConsumerHandleFromWebHandle(handle))); | 123 |
| 124 bool isRedirectResponse = false; | |
| 125 FetchResponseData* responseData = nullptr; | |
| 126 if (!handle) { | |
| 127 ASSERT(m_request->redirect() == WebURLRequest::FetchRedirectModeManual); | |
| 128 isRedirectResponse = true; | |
| 129 responseData = FetchResponseData::create(); | |
| 130 } else { | |
| 131 responseData = FetchResponseData::createWithBuffer(new BodyStreamBuffer( createFetchDataConsumerHandleFromWebHandle(handle))); | |
| 132 } | |
| 135 responseData->setStatus(response.httpStatusCode()); | 133 responseData->setStatus(response.httpStatusCode()); |
| 136 responseData->setStatusMessage(response.httpStatusText()); | 134 responseData->setStatusMessage(response.httpStatusText()); |
| 137 for (auto& it : response.httpHeaderFields()) | 135 for (auto& it : response.httpHeaderFields()) |
| 138 responseData->headerList()->append(it.key, it.value); | 136 responseData->headerList()->append(it.key, it.value); |
| 139 responseData->setURL(response.url()); | 137 responseData->setURL(response.url()); |
| 140 responseData->setMIMEType(response.mimeType()); | 138 responseData->setMIMEType(response.mimeType()); |
| 141 | 139 |
| 142 FetchResponseData* taintedResponse = nullptr; | 140 FetchResponseData* taintedResponse = nullptr; |
| 143 | 141 |
| 144 if (IsRedirectStatusCode(m_responseHttpStatusCode)) { | 142 if (isRedirectResponse) { |
| 145 Vector<String> locations; | 143 taintedResponse = responseData->createOpaqueRedirectFilteredResponse(); |
| 146 responseData->headerList()->getAll("location", locations); | 144 } else { |
| 147 if (locations.size() > 1) { | |
| 148 performNetworkError("Multiple Location header."); | |
| 149 return; | |
| 150 } | |
| 151 if (locations.size() == 1) { | |
| 152 KURL locationURL(m_request->url(), locations[0]); | |
| 153 if (!locationURL.isValid()) { | |
| 154 performNetworkError("Invalid Location header."); | |
| 155 return; | |
| 156 } | |
| 157 ASSERT(m_request->redirect() == WebURLRequest::FetchRedirectModeManu al); | |
| 158 taintedResponse = responseData->createOpaqueRedirectFilteredResponse (); | |
| 159 } | |
| 160 // When the location header doesn't exist, we don't treat the response | |
| 161 // as a redirect response, and execute tainting. | |
| 162 } | |
| 163 if (!taintedResponse) { | |
| 164 switch (m_request->tainting()) { | 145 switch (m_request->tainting()) { |
| 165 case FetchRequestData::BasicTainting: | 146 case FetchRequestData::BasicTainting: |
| 166 taintedResponse = responseData->createBasicFilteredResponse(); | 147 taintedResponse = responseData->createBasicFilteredResponse(); |
| 167 break; | 148 break; |
| 168 case FetchRequestData::CORSTainting: | 149 case FetchRequestData::CORSTainting: |
| 169 taintedResponse = responseData->createCORSFilteredResponse(); | 150 taintedResponse = responseData->createCORSFilteredResponse(); |
| 170 break; | 151 break; |
| 171 case FetchRequestData::OpaqueTainting: | 152 case FetchRequestData::OpaqueTainting: |
| 172 taintedResponse = responseData->createOpaqueFilteredResponse(); | 153 taintedResponse = responseData->createOpaqueFilteredResponse(); |
| 173 break; | 154 break; |
| 174 } | 155 } |
| 175 } | 156 } |
| 176 Response* r = Response::create(m_resolver->executionContext(), taintedRespon se); | 157 Response* r = Response::create(m_resolver->executionContext(), taintedRespon se); |
| 177 r->headers()->setGuard(Headers::ImmutableGuard); | 158 r->headers()->setGuard(Headers::ImmutableGuard); |
| 178 m_resolver->resolve(r); | 159 m_resolver->resolve(r); |
| 179 m_resolver.clear(); | 160 m_resolver.clear(); |
| 161 | |
| 162 if (isRedirectResponse) { | |
| 163 // There is no need to read the body of redirect response because there | |
| 164 // is no way to read the body of opaque-redirect filtered response's | |
| 165 // internal response. | |
| 166 // TODO(horo): If we support any API which expose the internal body, we | |
| 167 // will have to read the body. And also HTTPCache changes will be needed | |
| 168 // because it doesn't store the body of redirect responses. | |
| 169 notifyFinished(); | |
| 170 } | |
| 180 } | 171 } |
| 181 | 172 |
| 182 void FetchManager::Loader::didFinishLoading(unsigned long, double) | 173 void FetchManager::Loader::didFinishLoading(unsigned long, double) |
| 183 { | 174 { |
| 184 ASSERT(!m_failed); | 175 ASSERT(!m_failed); |
| 185 m_finished = true; | 176 m_finished = true; |
| 186 | 177 |
| 187 if (document() && document()->frame() && document()->frame()->page() | 178 if (document() && document()->frame() && document()->frame()->page() |
| 188 && m_responseHttpStatusCode >= 200 && m_responseHttpStatusCode < 300) { | 179 && m_responseHttpStatusCode >= 200 && m_responseHttpStatusCode < 300) { |
| 189 document()->frame()->page()->chromeClient().ajaxSucceeded(document()->fr ame()); | 180 document()->frame()->page()->chromeClient().ajaxSucceeded(document()->fr ame()); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 488 | 479 |
| 489 DEFINE_TRACE(FetchManager) | 480 DEFINE_TRACE(FetchManager) |
| 490 { | 481 { |
| 491 #if ENABLE(OILPAN) | 482 #if ENABLE(OILPAN) |
| 492 visitor->trace(m_executionContext); | 483 visitor->trace(m_executionContext); |
| 493 visitor->trace(m_loaders); | 484 visitor->trace(m_loaders); |
| 494 #endif | 485 #endif |
| 495 } | 486 } |
| 496 | 487 |
| 497 } // namespace blink | 488 } // namespace blink |
| OLD | NEW |