Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(264)

Side by Side Diff: Source/modules/fetch/FetchManager.cpp

Issue 1280733002: [3/3 blink] Support redirect option of Request and "opaqueredirect" response type. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@Redirect1
Patch Set: rebase Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698