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

Side by Side Diff: third_party/WebKit/Source/core/fetch/RawResource.cpp

Issue 2584423002: Loading: move core/fetch to platform/loader/fetch (Closed)
Patch Set: rebase Created 3 years, 11 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
(Empty)
1 /*
2 * Copyright (C) 2011 Google Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26 #include "core/fetch/RawResource.h"
27
28 #include "core/fetch/FetchRequest.h"
29 #include "core/fetch/MemoryCache.h"
30 #include "core/fetch/ResourceClientWalker.h"
31 #include "core/fetch/ResourceFetcher.h"
32 #include "core/fetch/ResourceLoader.h"
33 #include "platform/HTTPNames.h"
34 #include <memory>
35
36 namespace blink {
37
38 Resource* RawResource::fetchSynchronously(FetchRequest& request,
39 ResourceFetcher* fetcher) {
40 request.makeSynchronous();
41 return fetcher->requestResource(request, RawResourceFactory(Resource::Raw));
42 }
43
44 RawResource* RawResource::fetchImport(FetchRequest& request,
45 ResourceFetcher* fetcher) {
46 DCHECK_EQ(request.resourceRequest().frameType(),
47 WebURLRequest::FrameTypeNone);
48 request.mutableResourceRequest().setRequestContext(
49 WebURLRequest::RequestContextImport);
50 return toRawResource(fetcher->requestResource(
51 request, RawResourceFactory(Resource::ImportResource)));
52 }
53
54 RawResource* RawResource::fetch(FetchRequest& request,
55 ResourceFetcher* fetcher) {
56 DCHECK_EQ(request.resourceRequest().frameType(),
57 WebURLRequest::FrameTypeNone);
58 DCHECK_NE(request.resourceRequest().requestContext(),
59 WebURLRequest::RequestContextUnspecified);
60 return toRawResource(
61 fetcher->requestResource(request, RawResourceFactory(Resource::Raw)));
62 }
63
64 RawResource* RawResource::fetchMainResource(
65 FetchRequest& request,
66 ResourceFetcher* fetcher,
67 const SubstituteData& substituteData) {
68 DCHECK_NE(request.resourceRequest().frameType(),
69 WebURLRequest::FrameTypeNone);
70 DCHECK(request.resourceRequest().requestContext() ==
71 WebURLRequest::RequestContextForm ||
72 request.resourceRequest().requestContext() ==
73 WebURLRequest::RequestContextFrame ||
74 request.resourceRequest().requestContext() ==
75 WebURLRequest::RequestContextHyperlink ||
76 request.resourceRequest().requestContext() ==
77 WebURLRequest::RequestContextIframe ||
78 request.resourceRequest().requestContext() ==
79 WebURLRequest::RequestContextInternal ||
80 request.resourceRequest().requestContext() ==
81 WebURLRequest::RequestContextLocation);
82
83 return toRawResource(fetcher->requestResource(
84 request, RawResourceFactory(Resource::MainResource), substituteData));
85 }
86
87 RawResource* RawResource::fetchMedia(FetchRequest& request,
88 ResourceFetcher* fetcher) {
89 DCHECK_EQ(request.resourceRequest().frameType(),
90 WebURLRequest::FrameTypeNone);
91 DCHECK(request.resourceRequest().requestContext() ==
92 WebURLRequest::RequestContextAudio ||
93 request.resourceRequest().requestContext() ==
94 WebURLRequest::RequestContextVideo);
95 return toRawResource(
96 fetcher->requestResource(request, RawResourceFactory(Resource::Media)));
97 }
98
99 RawResource* RawResource::fetchTextTrack(FetchRequest& request,
100 ResourceFetcher* fetcher) {
101 DCHECK_EQ(request.resourceRequest().frameType(),
102 WebURLRequest::FrameTypeNone);
103 request.mutableResourceRequest().setRequestContext(
104 WebURLRequest::RequestContextTrack);
105 return toRawResource(fetcher->requestResource(
106 request, RawResourceFactory(Resource::TextTrack)));
107 }
108
109 RawResource* RawResource::fetchManifest(FetchRequest& request,
110 ResourceFetcher* fetcher) {
111 DCHECK_EQ(request.resourceRequest().frameType(),
112 WebURLRequest::FrameTypeNone);
113 DCHECK_EQ(request.resourceRequest().requestContext(),
114 WebURLRequest::RequestContextManifest);
115 return toRawResource(fetcher->requestResource(
116 request, RawResourceFactory(Resource::Manifest)));
117 }
118
119 RawResource::RawResource(const ResourceRequest& resourceRequest,
120 Type type,
121 const ResourceLoaderOptions& options)
122 : Resource(resourceRequest, type, options) {}
123
124 void RawResource::appendData(const char* data, size_t length) {
125 Resource::appendData(data, length);
126
127 ResourceClientWalker<RawResourceClient> w(clients());
128 while (RawResourceClient* c = w.next())
129 c->dataReceived(this, data, length);
130 }
131
132 void RawResource::didAddClient(ResourceClient* c) {
133 // CHECK()/RevalidationStartForbiddenScope are for
134 // https://crbug.com/640960#c24.
135 CHECK(!isCacheValidator());
136 if (!hasClient(c))
137 return;
138 DCHECK(RawResourceClient::isExpectedType(c));
139 RevalidationStartForbiddenScope revalidationStartForbiddenScope(this);
140 RawResourceClient* client = static_cast<RawResourceClient*>(c);
141 for (const auto& redirect : redirectChain()) {
142 ResourceRequest request(redirect.m_request);
143 client->redirectReceived(this, request, redirect.m_redirectResponse);
144 if (!hasClient(c))
145 return;
146 }
147
148 if (!response().isNull())
149 client->responseReceived(this, response(), nullptr);
150 if (!hasClient(c))
151 return;
152 if (data())
153 client->dataReceived(this, data()->data(), data()->size());
154 if (!hasClient(c))
155 return;
156 Resource::didAddClient(client);
157 }
158
159 bool RawResource::willFollowRedirect(const ResourceRequest& newRequest,
160 const ResourceResponse& redirectResponse) {
161 bool follow = Resource::willFollowRedirect(newRequest, redirectResponse);
162 // The base class method takes a non const reference of a ResourceRequest
163 // and returns bool just for allowing RawResource to reject redirect. It
164 // must always return true.
165 DCHECK(follow);
166
167 DCHECK(!redirectResponse.isNull());
168 ResourceClientWalker<RawResourceClient> w(clients());
169 while (RawResourceClient* c = w.next()) {
170 if (!c->redirectReceived(this, newRequest, redirectResponse))
171 follow = false;
172 }
173
174 return follow;
175 }
176
177 void RawResource::willNotFollowRedirect() {
178 ResourceClientWalker<RawResourceClient> w(clients());
179 while (RawResourceClient* c = w.next())
180 c->redirectBlocked();
181 }
182
183 void RawResource::responseReceived(
184 const ResourceResponse& response,
185 std::unique_ptr<WebDataConsumerHandle> handle) {
186 bool isSuccessfulRevalidation =
187 isCacheValidator() && response.httpStatusCode() == 304;
188 Resource::responseReceived(response, nullptr);
189
190 ResourceClientWalker<RawResourceClient> w(clients());
191 DCHECK(clients().size() <= 1 || !handle);
192 while (RawResourceClient* c = w.next()) {
193 // |handle| is cleared when passed, but it's not a problem because |handle|
194 // is null when there are two or more clients, as asserted.
195 c->responseReceived(this, this->response(), std::move(handle));
196 }
197
198 // If we successfully revalidated, we won't get appendData() calls. Forward
199 // the data to clients now instead. Note: |m_data| can be null when no data is
200 // appended to the original resource.
201 if (isSuccessfulRevalidation && data()) {
202 ResourceClientWalker<RawResourceClient> w(clients());
203 while (RawResourceClient* c = w.next())
204 c->dataReceived(this, data()->data(), data()->size());
205 }
206 }
207
208 void RawResource::setSerializedCachedMetadata(const char* data, size_t size) {
209 Resource::setSerializedCachedMetadata(data, size);
210 ResourceClientWalker<RawResourceClient> w(clients());
211 while (RawResourceClient* c = w.next())
212 c->setSerializedCachedMetadata(this, data, size);
213 }
214
215 void RawResource::didSendData(unsigned long long bytesSent,
216 unsigned long long totalBytesToBeSent) {
217 ResourceClientWalker<RawResourceClient> w(clients());
218 while (RawResourceClient* c = w.next())
219 c->dataSent(this, bytesSent, totalBytesToBeSent);
220 }
221
222 void RawResource::didDownloadData(int dataLength) {
223 ResourceClientWalker<RawResourceClient> w(clients());
224 while (RawResourceClient* c = w.next())
225 c->dataDownloaded(this, dataLength);
226 }
227
228 void RawResource::reportResourceTimingToClients(
229 const ResourceTimingInfo& info) {
230 ResourceClientWalker<RawResourceClient> w(clients());
231 while (RawResourceClient* c = w.next())
232 c->didReceiveResourceTiming(this, info);
233 }
234
235 void RawResource::setDefersLoading(bool defers) {
236 if (loader())
237 loader()->setDefersLoading(defers);
238 }
239
240 static bool shouldIgnoreHeaderForCacheReuse(AtomicString headerName) {
241 // FIXME: This list of headers that don't affect cache policy almost certainly
242 // isn't complete.
243 DEFINE_STATIC_LOCAL(
244 HashSet<AtomicString>, headers,
245 ({
246 "Cache-Control", "If-Modified-Since", "If-None-Match", "Origin",
247 "Pragma", "Purpose", "Referer", "User-Agent",
248 HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id,
249 }));
250 return headers.contains(headerName);
251 }
252
253 static bool isCacheableHTTPMethod(const AtomicString& method) {
254 // Per http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.10,
255 // these methods always invalidate the cache entry.
256 return method != "POST" && method != "PUT" && method != "DELETE";
257 }
258
259 bool RawResource::canReuse(const ResourceRequest& newRequest) const {
260 if (getDataBufferingPolicy() == DoNotBufferData)
261 return false;
262
263 if (!isCacheableHTTPMethod(resourceRequest().httpMethod()))
264 return false;
265 if (resourceRequest().httpMethod() != newRequest.httpMethod())
266 return false;
267
268 if (resourceRequest().httpBody() != newRequest.httpBody())
269 return false;
270
271 if (resourceRequest().allowStoredCredentials() !=
272 newRequest.allowStoredCredentials())
273 return false;
274
275 // Ensure most headers match the existing headers before continuing. Note that
276 // the list of ignored headers includes some headers explicitly related to
277 // caching. A more detailed check of caching policy will be performed later,
278 // this is simply a list of headers that we might permit to be different and
279 // still reuse the existing Resource.
280 const HTTPHeaderMap& newHeaders = newRequest.httpHeaderFields();
281 const HTTPHeaderMap& oldHeaders = resourceRequest().httpHeaderFields();
282
283 for (const auto& header : newHeaders) {
284 AtomicString headerName = header.key;
285 if (!shouldIgnoreHeaderForCacheReuse(headerName) &&
286 header.value != oldHeaders.get(headerName))
287 return false;
288 }
289
290 for (const auto& header : oldHeaders) {
291 AtomicString headerName = header.key;
292 if (!shouldIgnoreHeaderForCacheReuse(headerName) &&
293 header.value != newHeaders.get(headerName))
294 return false;
295 }
296
297 return true;
298 }
299
300 RawResourceClientStateChecker::RawResourceClientStateChecker()
301 : m_state(NotAddedAsClient) {}
302
303 RawResourceClientStateChecker::~RawResourceClientStateChecker() {}
304
305 NEVER_INLINE void RawResourceClientStateChecker::willAddClient() {
306 SECURITY_CHECK(m_state == NotAddedAsClient);
307 m_state = Started;
308 }
309
310 NEVER_INLINE void RawResourceClientStateChecker::willRemoveClient() {
311 SECURITY_CHECK(m_state != NotAddedAsClient);
312 m_state = NotAddedAsClient;
313 }
314
315 NEVER_INLINE void RawResourceClientStateChecker::redirectReceived() {
316 SECURITY_CHECK(m_state == Started);
317 }
318
319 NEVER_INLINE void RawResourceClientStateChecker::redirectBlocked() {
320 SECURITY_CHECK(m_state == Started);
321 m_state = RedirectBlocked;
322 }
323
324 NEVER_INLINE void RawResourceClientStateChecker::dataSent() {
325 SECURITY_CHECK(m_state == Started);
326 }
327
328 NEVER_INLINE void RawResourceClientStateChecker::responseReceived() {
329 SECURITY_CHECK(m_state == Started);
330 m_state = ResponseReceived;
331 }
332
333 NEVER_INLINE void RawResourceClientStateChecker::setSerializedCachedMetadata() {
334 SECURITY_CHECK(m_state == ResponseReceived);
335 m_state = SetSerializedCachedMetadata;
336 }
337
338 NEVER_INLINE void RawResourceClientStateChecker::dataReceived() {
339 SECURITY_CHECK(m_state == ResponseReceived ||
340 m_state == SetSerializedCachedMetadata ||
341 m_state == DataReceived);
342 m_state = DataReceived;
343 }
344
345 NEVER_INLINE void RawResourceClientStateChecker::dataDownloaded() {
346 SECURITY_CHECK(m_state == ResponseReceived ||
347 m_state == SetSerializedCachedMetadata ||
348 m_state == DataDownloaded);
349 m_state = DataDownloaded;
350 }
351
352 NEVER_INLINE void RawResourceClientStateChecker::notifyFinished(
353 Resource* resource) {
354 SECURITY_CHECK(m_state != NotAddedAsClient);
355 SECURITY_CHECK(m_state != NotifyFinished);
356 SECURITY_CHECK(resource->errorOccurred() ||
357 (m_state == ResponseReceived ||
358 m_state == SetSerializedCachedMetadata ||
359 m_state == DataReceived || m_state == DataDownloaded));
360 m_state = NotifyFinished;
361 }
362
363 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698