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

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

Issue 2584423002: Loading: move core/fetch to platform/loader/fetch (Closed)
Patch Set: another try Created 3 years, 10 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) 2013, 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "core/fetch/RawResource.h"
32
33 #include "core/fetch/MemoryCache.h"
34 #include "core/fetch/ResourceFetcher.h"
35 #include "platform/SharedBuffer.h"
36 #include "platform/heap/Handle.h"
37 #include "platform/network/ResourceTimingInfo.h"
38 #include "platform/testing/UnitTestHelpers.h"
39 #include "public/platform/Platform.h"
40 #include "public/platform/WebScheduler.h"
41 #include "public/platform/WebThread.h"
42 #include "public/platform/WebURL.h"
43 #include "public/platform/WebURLResponse.h"
44 #include "testing/gmock/include/gmock/gmock.h"
45 #include "testing/gtest/include/gtest/gtest.h"
46
47 namespace blink {
48
49 using ::testing::InSequence;
50 using ::testing::_;
51 using Checkpoint = ::testing::StrictMock<::testing::MockFunction<void(int)>>;
52
53 class MockRawResourceClient
54 : public GarbageCollectedFinalized<MockRawResourceClient>,
55 public RawResourceClient {
56 USING_GARBAGE_COLLECTED_MIXIN(MockRawResourceClient);
57
58 public:
59 static MockRawResourceClient* create() {
60 return new ::testing::StrictMock<MockRawResourceClient>;
61 }
62
63 MOCK_METHOD3(dataSent,
64 void(Resource*, unsigned long long, unsigned long long));
65 MOCK_METHOD3(responseReceivedInternal,
66 void(Resource*,
67 const ResourceResponse&,
68 WebDataConsumerHandle*));
69 MOCK_METHOD3(setSerializedCachedMetadata,
70 void(Resource*, const char*, size_t));
71 MOCK_METHOD3(dataReceived, void(Resource*, const char*, size_t));
72 MOCK_METHOD3(redirectReceived,
73 bool(Resource*,
74 const ResourceRequest&,
75 const ResourceResponse&));
76 MOCK_METHOD0(redirectBlocked, void());
77 MOCK_METHOD2(dataDownloaded, void(Resource*, int));
78 MOCK_METHOD2(didReceiveResourceTiming,
79 void(Resource*, const ResourceTimingInfo&));
80
81 void responseReceived(
82 Resource* resource,
83 const ResourceResponse& response,
84 std::unique_ptr<WebDataConsumerHandle> handle) override {
85 responseReceivedInternal(resource, response, handle.get());
86 }
87
88 String debugName() const override { return "MockRawResourceClient"; }
89
90 DEFINE_INLINE_VIRTUAL_TRACE() { RawResourceClient::trace(visitor); }
91
92 protected:
93 MockRawResourceClient() = default;
94 };
95
96 TEST(RawResourceTest, DontIgnoreAcceptForCacheReuse) {
97 ResourceRequest jpegRequest;
98 jpegRequest.setHTTPAccept("image/jpeg");
99
100 RawResource* jpegResource(RawResource::create(jpegRequest, Resource::Raw));
101
102 ResourceRequest pngRequest;
103 pngRequest.setHTTPAccept("image/png");
104
105 EXPECT_FALSE(jpegResource->canReuse(pngRequest));
106 }
107
108 class DummyClient final : public GarbageCollectedFinalized<DummyClient>,
109 public RawResourceClient {
110 USING_GARBAGE_COLLECTED_MIXIN(DummyClient);
111
112 public:
113 DummyClient() : m_called(false), m_numberOfRedirectsReceived(0) {}
114 ~DummyClient() override {}
115
116 // ResourceClient implementation.
117 void notifyFinished(Resource* resource) override { m_called = true; }
118 String debugName() const override { return "DummyClient"; }
119
120 void dataReceived(Resource*, const char* data, size_t length) override {
121 m_data.append(data, length);
122 }
123
124 bool redirectReceived(Resource*,
125 const ResourceRequest&,
126 const ResourceResponse&) override {
127 ++m_numberOfRedirectsReceived;
128 return true;
129 }
130
131 bool called() { return m_called; }
132 int numberOfRedirectsReceived() const { return m_numberOfRedirectsReceived; }
133 const Vector<char>& data() { return m_data; }
134 DEFINE_INLINE_TRACE() { RawResourceClient::trace(visitor); }
135
136 private:
137 bool m_called;
138 int m_numberOfRedirectsReceived;
139 Vector<char> m_data;
140 };
141
142 // This client adds another client when notified.
143 class AddingClient final : public GarbageCollectedFinalized<AddingClient>,
144 public RawResourceClient {
145 USING_GARBAGE_COLLECTED_MIXIN(AddingClient);
146
147 public:
148 AddingClient(DummyClient* client, Resource* resource)
149 : m_dummyClient(client), m_resource(resource) {}
150
151 ~AddingClient() override {}
152
153 // ResourceClient implementation.
154 void notifyFinished(Resource* resource) override {
155 // First schedule an asynchronous task to remove the client.
156 // We do not expect a client to be called if the client is removed before
157 // a callback invocation task queued inside addClient() is scheduled.
158 Platform::current()
159 ->currentThread()
160 ->scheduler()
161 ->loadingTaskRunner()
162 ->postTask(BLINK_FROM_HERE, WTF::bind(&AddingClient::removeClient,
163 wrapPersistent(this)));
164 resource->addClient(m_dummyClient);
165 }
166 String debugName() const override { return "AddingClient"; }
167
168 void removeClient() { m_resource->removeClient(m_dummyClient); }
169
170 DEFINE_INLINE_VIRTUAL_TRACE() {
171 visitor->trace(m_dummyClient);
172 visitor->trace(m_resource);
173 RawResourceClient::trace(visitor);
174 }
175
176 private:
177 Member<DummyClient> m_dummyClient;
178 Member<Resource> m_resource;
179 };
180
181 TEST(RawResourceTest, RevalidationSucceeded) {
182 Resource* resource =
183 RawResource::create(ResourceRequest("data:text/html,"), Resource::Raw);
184 ResourceResponse response;
185 response.setHTTPStatusCode(200);
186 resource->responseReceived(response, nullptr);
187 const char data[5] = "abcd";
188 resource->appendData(data, 4);
189 resource->finish();
190 memoryCache()->add(resource);
191
192 // Simulate a successful revalidation.
193 resource->setRevalidatingRequest(ResourceRequest("data:text/html,"));
194
195 Persistent<DummyClient> client = new DummyClient;
196 resource->addClient(client);
197
198 ResourceResponse revalidatingResponse;
199 revalidatingResponse.setHTTPStatusCode(304);
200 resource->responseReceived(revalidatingResponse, nullptr);
201 EXPECT_FALSE(resource->isCacheValidator());
202 EXPECT_EQ(200, resource->response().httpStatusCode());
203 EXPECT_EQ(4u, resource->resourceBuffer()->size());
204 EXPECT_EQ(resource, memoryCache()->resourceForURL(
205 KURL(ParsedURLString, "data:text/html,")));
206 memoryCache()->remove(resource);
207
208 resource->removeClient(client);
209 EXPECT_FALSE(resource->isAlive());
210 EXPECT_FALSE(client->called());
211 EXPECT_EQ("abcd", String(client->data().data(), client->data().size()));
212 }
213
214 TEST(RawResourceTest, RevalidationSucceededForResourceWithoutBody) {
215 Resource* resource =
216 RawResource::create(ResourceRequest("data:text/html,"), Resource::Raw);
217 ResourceResponse response;
218 response.setHTTPStatusCode(200);
219 resource->responseReceived(response, nullptr);
220 resource->finish();
221 memoryCache()->add(resource);
222
223 // Simulate a successful revalidation.
224 resource->setRevalidatingRequest(ResourceRequest("data:text/html,"));
225
226 Persistent<DummyClient> client = new DummyClient;
227 resource->addClient(client);
228
229 ResourceResponse revalidatingResponse;
230 revalidatingResponse.setHTTPStatusCode(304);
231 resource->responseReceived(revalidatingResponse, nullptr);
232 EXPECT_FALSE(resource->isCacheValidator());
233 EXPECT_EQ(200, resource->response().httpStatusCode());
234 EXPECT_FALSE(resource->resourceBuffer());
235 EXPECT_EQ(resource, memoryCache()->resourceForURL(
236 KURL(ParsedURLString, "data:text/html,")));
237 memoryCache()->remove(resource);
238
239 resource->removeClient(client);
240 EXPECT_FALSE(resource->isAlive());
241 EXPECT_FALSE(client->called());
242 EXPECT_EQ(0u, client->data().size());
243 }
244
245 TEST(RawResourceTest, RevalidationSucceededUpdateHeaders) {
246 Resource* resource =
247 RawResource::create(ResourceRequest("data:text/html,"), Resource::Raw);
248 ResourceResponse response;
249 response.setHTTPStatusCode(200);
250 response.addHTTPHeaderField("keep-alive", "keep-alive value");
251 response.addHTTPHeaderField("expires", "expires value");
252 response.addHTTPHeaderField("last-modified", "last-modified value");
253 response.addHTTPHeaderField("proxy-authenticate", "proxy-authenticate value");
254 response.addHTTPHeaderField("proxy-connection", "proxy-connection value");
255 response.addHTTPHeaderField("x-custom", "custom value");
256 resource->responseReceived(response, nullptr);
257 resource->finish();
258 memoryCache()->add(resource);
259
260 // Simulate a successful revalidation.
261 resource->setRevalidatingRequest(ResourceRequest("data:text/html,"));
262
263 // Validate that these headers pre-update.
264 EXPECT_EQ("keep-alive value",
265 resource->response().httpHeaderField("keep-alive"));
266 EXPECT_EQ("expires value", resource->response().httpHeaderField("expires"));
267 EXPECT_EQ("last-modified value",
268 resource->response().httpHeaderField("last-modified"));
269 EXPECT_EQ("proxy-authenticate value",
270 resource->response().httpHeaderField("proxy-authenticate"));
271 EXPECT_EQ("proxy-authenticate value",
272 resource->response().httpHeaderField("proxy-authenticate"));
273 EXPECT_EQ("proxy-connection value",
274 resource->response().httpHeaderField("proxy-connection"));
275 EXPECT_EQ("custom value", resource->response().httpHeaderField("x-custom"));
276
277 Persistent<DummyClient> client = new DummyClient;
278 resource->addClient(client.get());
279
280 // Perform a revalidation step.
281 ResourceResponse revalidatingResponse;
282 revalidatingResponse.setHTTPStatusCode(304);
283 // Headers that aren't copied with an 304 code.
284 revalidatingResponse.addHTTPHeaderField("keep-alive", "garbage");
285 revalidatingResponse.addHTTPHeaderField("expires", "garbage");
286 revalidatingResponse.addHTTPHeaderField("last-modified", "garbage");
287 revalidatingResponse.addHTTPHeaderField("proxy-authenticate", "garbage");
288 revalidatingResponse.addHTTPHeaderField("proxy-connection", "garbage");
289 // Header that is updated with 304 code.
290 revalidatingResponse.addHTTPHeaderField("x-custom", "updated");
291 resource->responseReceived(revalidatingResponse, nullptr);
292
293 // Validate the original response.
294 EXPECT_EQ(200, resource->response().httpStatusCode());
295
296 // Validate that these headers are not updated.
297 EXPECT_EQ("keep-alive value",
298 resource->response().httpHeaderField("keep-alive"));
299 EXPECT_EQ("expires value", resource->response().httpHeaderField("expires"));
300 EXPECT_EQ("last-modified value",
301 resource->response().httpHeaderField("last-modified"));
302 EXPECT_EQ("proxy-authenticate value",
303 resource->response().httpHeaderField("proxy-authenticate"));
304 EXPECT_EQ("proxy-authenticate value",
305 resource->response().httpHeaderField("proxy-authenticate"));
306 EXPECT_EQ("proxy-connection value",
307 resource->response().httpHeaderField("proxy-connection"));
308 EXPECT_EQ("updated", resource->response().httpHeaderField("x-custom"));
309
310 memoryCache()->remove(resource);
311
312 resource->removeClient(client);
313 EXPECT_FALSE(resource->isAlive());
314 EXPECT_FALSE(client->called());
315 EXPECT_EQ(0u, client->data().size());
316 }
317
318 TEST(RawResourceTest, RedirectDuringRevalidation) {
319 Resource* resource = RawResource::create(
320 ResourceRequest("https://example.com/1"), Resource::Raw);
321 ResourceResponse response;
322 response.setURL(KURL(ParsedURLString, "https://example.com/1"));
323 response.setHTTPStatusCode(200);
324 resource->responseReceived(response, nullptr);
325 const char data[5] = "abcd";
326 resource->appendData(data, 4);
327 resource->finish();
328 memoryCache()->add(resource);
329
330 EXPECT_FALSE(resource->isCacheValidator());
331 EXPECT_EQ("https://example.com/1",
332 resource->resourceRequest().url().getString());
333 EXPECT_EQ("https://example.com/1",
334 resource->lastResourceRequest().url().getString());
335
336 // Simulate a revalidation.
337 resource->setRevalidatingRequest(ResourceRequest("https://example.com/1"));
338 EXPECT_TRUE(resource->isCacheValidator());
339 EXPECT_EQ("https://example.com/1",
340 resource->resourceRequest().url().getString());
341 EXPECT_EQ("https://example.com/1",
342 resource->lastResourceRequest().url().getString());
343
344 Persistent<DummyClient> client = new DummyClient;
345 resource->addClient(client);
346
347 // The revalidating request is redirected.
348 ResourceResponse redirectResponse;
349 redirectResponse.setURL(KURL(ParsedURLString, "https://example.com/1"));
350 redirectResponse.setHTTPHeaderField("location", "https://example.com/2");
351 redirectResponse.setHTTPStatusCode(308);
352 ResourceRequest redirectedRevalidatingRequest("https://example.com/2");
353 resource->willFollowRedirect(redirectedRevalidatingRequest, redirectResponse);
354 EXPECT_FALSE(resource->isCacheValidator());
355 EXPECT_EQ("https://example.com/1",
356 resource->resourceRequest().url().getString());
357 EXPECT_EQ("https://example.com/2",
358 resource->lastResourceRequest().url().getString());
359
360 // The final response is received.
361 ResourceResponse revalidatingResponse;
362 revalidatingResponse.setURL(KURL(ParsedURLString, "https://example.com/2"));
363 revalidatingResponse.setHTTPStatusCode(200);
364 resource->responseReceived(revalidatingResponse, nullptr);
365 const char data2[4] = "xyz";
366 resource->appendData(data2, 3);
367 resource->finish();
368 EXPECT_FALSE(resource->isCacheValidator());
369 EXPECT_EQ("https://example.com/1",
370 resource->resourceRequest().url().getString());
371 EXPECT_EQ("https://example.com/2",
372 resource->lastResourceRequest().url().getString());
373 EXPECT_FALSE(resource->isCacheValidator());
374 EXPECT_EQ(200, resource->response().httpStatusCode());
375 EXPECT_EQ(3u, resource->resourceBuffer()->size());
376 EXPECT_EQ(resource, memoryCache()->resourceForURL(
377 KURL(ParsedURLString, "https://example.com/1")));
378
379 EXPECT_TRUE(client->called());
380 EXPECT_EQ(1, client->numberOfRedirectsReceived());
381 EXPECT_EQ("xyz", String(client->data().data(), client->data().size()));
382
383 // Test the case where a client is added after revalidation is completed.
384 Persistent<DummyClient> client2 = new DummyClient;
385 resource->addClient(client2);
386
387 // Because RawResourceClient is added asynchronously,
388 // |runPendingTasks()| is called to make |client2| to be notified.
389 testing::runPendingTasks();
390
391 EXPECT_TRUE(client2->called());
392 EXPECT_EQ(1, client2->numberOfRedirectsReceived());
393 EXPECT_EQ("xyz", String(client2->data().data(), client2->data().size()));
394
395 memoryCache()->remove(resource);
396
397 resource->removeClient(client);
398 resource->removeClient(client2);
399 EXPECT_FALSE(resource->isAlive());
400 }
401
402 TEST(RawResourceTest, AddClientDuringCallback) {
403 Resource* raw =
404 RawResource::create(ResourceRequest("data:text/html,"), Resource::Raw);
405
406 // Create a non-null response.
407 ResourceResponse response = raw->response();
408 response.setURL(KURL(ParsedURLString, "http://600.613/"));
409 raw->setResponse(response);
410 raw->finish();
411 EXPECT_FALSE(raw->response().isNull());
412
413 Persistent<DummyClient> dummyClient = new DummyClient();
414 Persistent<AddingClient> addingClient =
415 new AddingClient(dummyClient.get(), raw);
416 raw->addClient(addingClient);
417 testing::runPendingTasks();
418 raw->removeClient(addingClient);
419 EXPECT_FALSE(dummyClient->called());
420 EXPECT_FALSE(raw->isAlive());
421 }
422
423 // This client removes another client when notified.
424 class RemovingClient : public GarbageCollectedFinalized<RemovingClient>,
425 public RawResourceClient {
426 USING_GARBAGE_COLLECTED_MIXIN(RemovingClient);
427
428 public:
429 explicit RemovingClient(DummyClient* client) : m_dummyClient(client) {}
430
431 ~RemovingClient() override {}
432
433 // ResourceClient implementation.
434 void notifyFinished(Resource* resource) override {
435 resource->removeClient(m_dummyClient);
436 resource->removeClient(this);
437 }
438 String debugName() const override { return "RemovingClient"; }
439 DEFINE_INLINE_TRACE() {
440 visitor->trace(m_dummyClient);
441 RawResourceClient::trace(visitor);
442 }
443
444 private:
445 Member<DummyClient> m_dummyClient;
446 };
447
448 TEST(RawResourceTest, RemoveClientDuringCallback) {
449 Resource* raw =
450 RawResource::create(ResourceRequest("data:text/html,"), Resource::Raw);
451
452 // Create a non-null response.
453 ResourceResponse response = raw->response();
454 response.setURL(KURL(ParsedURLString, "http://600.613/"));
455 raw->setResponse(response);
456 raw->finish();
457 EXPECT_FALSE(raw->response().isNull());
458
459 Persistent<DummyClient> dummyClient = new DummyClient();
460 Persistent<RemovingClient> removingClient =
461 new RemovingClient(dummyClient.get());
462 raw->addClient(dummyClient);
463 raw->addClient(removingClient);
464 testing::runPendingTasks();
465 EXPECT_FALSE(raw->isAlive());
466 }
467
468 // ResourceClient can be added to |m_clients| asynchronously via
469 // ResourceCallback. When revalidation is started after ResourceCallback is
470 // scheduled and before it is dispatched, ResourceClient's callbacks should be
471 // called appropriately.
472 TEST(RawResourceTest, StartFailedRevalidationWhileResourceCallback) {
473 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html");
474
475 ResourceResponse response;
476 response.setURL(url);
477 response.setHTTPStatusCode(200);
478
479 ResourceResponse newResponse;
480 newResponse.setURL(url);
481 newResponse.setHTTPStatusCode(201);
482
483 Resource* resource =
484 RawResource::create(ResourceRequest("data:text/html,"), Resource::Raw);
485 resource->responseReceived(response, nullptr);
486 resource->appendData("oldData", 8);
487 resource->finish();
488
489 InSequence s;
490 Checkpoint checkpoint;
491
492 MockRawResourceClient* client = MockRawResourceClient::create();
493
494 EXPECT_CALL(checkpoint, Call(1));
495 EXPECT_CALL(*client, responseReceivedInternal(resource, newResponse, _));
496 EXPECT_CALL(*client, dataReceived(resource, ::testing::StrEq("newData"), 8));
497
498 // Add a client. No callbacks are made here because ResourceCallback is
499 // scheduled asynchronously.
500 resource->addClient(client);
501 EXPECT_FALSE(resource->isCacheValidator());
502
503 // Start revalidation.
504 resource->setRevalidatingRequest(ResourceRequest(url));
505 EXPECT_TRUE(resource->isCacheValidator());
506
507 // Make the ResourceCallback to be dispatched.
508 testing::runPendingTasks();
509
510 checkpoint.Call(1);
511
512 resource->responseReceived(newResponse, nullptr);
513 resource->appendData("newData", 8);
514 }
515
516 TEST(RawResourceTest, StartSuccessfulRevalidationWhileResourceCallback) {
517 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html");
518
519 ResourceResponse response;
520 response.setURL(url);
521 response.setHTTPStatusCode(200);
522
523 ResourceResponse newResponse;
524 newResponse.setURL(url);
525 newResponse.setHTTPStatusCode(304);
526
527 Resource* resource =
528 RawResource::create(ResourceRequest("data:text/html,"), Resource::Raw);
529 resource->responseReceived(response, nullptr);
530 resource->appendData("oldData", 8);
531 resource->finish();
532
533 InSequence s;
534 Checkpoint checkpoint;
535
536 MockRawResourceClient* client = MockRawResourceClient::create();
537
538 EXPECT_CALL(checkpoint, Call(1));
539 EXPECT_CALL(*client, responseReceivedInternal(resource, response, _));
540 EXPECT_CALL(*client, dataReceived(resource, ::testing::StrEq("oldData"), 8));
541
542 // Add a client. No callbacks are made here because ResourceCallback is
543 // scheduled asynchronously.
544 resource->addClient(client);
545 EXPECT_FALSE(resource->isCacheValidator());
546
547 // Start revalidation.
548 resource->setRevalidatingRequest(ResourceRequest(url));
549 EXPECT_TRUE(resource->isCacheValidator());
550
551 // Make the ResourceCallback to be dispatched.
552 testing::runPendingTasks();
553
554 checkpoint.Call(1);
555
556 resource->responseReceived(newResponse, nullptr);
557 }
558
559 TEST(RawResourceTest, CanReuseDevToolsEmulateNetworkConditionsClientIdHeader) {
560 ResourceRequest request("data:text/html,");
561 request.setHTTPHeaderField(
562 HTTPNames::X_DevTools_Emulate_Network_Conditions_Client_Id, "Foo");
563 Resource* raw = RawResource::create(request, Resource::Raw);
564 EXPECT_TRUE(raw->canReuse(ResourceRequest("data:text/html,")));
565 }
566
567 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fetch/RawResource.cpp ('k') | third_party/WebKit/Source/core/fetch/Resource.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698