Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013, Google Inc. All rights reserved. | 2 * Copyright (c) 2013, Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 #include "core/fetch/ResourceFetcher.h" | 31 #include "core/fetch/ResourceFetcher.h" |
| 32 | 32 |
| 33 #include "core/fetch/FetchInitiatorInfo.h" | 33 #include "core/fetch/FetchInitiatorInfo.h" |
| 34 #include "core/fetch/FetchInitiatorTypeNames.h" | 34 #include "core/fetch/FetchInitiatorTypeNames.h" |
| 35 #include "core/fetch/FetchRequest.h" | 35 #include "core/fetch/FetchRequest.h" |
| 36 #include "core/fetch/MemoryCache.h" | 36 #include "core/fetch/MemoryCache.h" |
| 37 #include "core/fetch/RawResource.h" | 37 #include "core/fetch/RawResource.h" |
| 38 #include "core/fetch/ResourceLoader.h" | 38 #include "core/fetch/ResourceLoader.h" |
| 39 #include "platform/exported/WrappedResourceResponse.h" | 39 #include "platform/exported/WrappedResourceResponse.h" |
| 40 #include "platform/heap/Handle.h" | 40 #include "platform/heap/Handle.h" |
| 41 #include "platform/heap/HeapAllocator.h" | |
| 42 #include "platform/heap/Member.h" | |
| 41 #include "platform/network/ResourceRequest.h" | 43 #include "platform/network/ResourceRequest.h" |
| 44 #include "platform/network/ResourceTimingInfo.h" | |
| 42 #include "platform/testing/URLTestHelpers.h" | 45 #include "platform/testing/URLTestHelpers.h" |
| 43 #include "platform/weborigin/KURL.h" | 46 #include "platform/weborigin/KURL.h" |
| 44 #include "public/platform/Platform.h" | 47 #include "public/platform/Platform.h" |
| 45 #include "public/platform/WebTaskRunner.h" | 48 #include "public/platform/WebTaskRunner.h" |
| 46 #include "public/platform/WebURLLoaderMockFactory.h" | 49 #include "public/platform/WebURLLoaderMockFactory.h" |
| 47 #include "public/platform/WebURLResponse.h" | 50 #include "public/platform/WebURLResponse.h" |
| 48 #include "testing/gtest/include/gtest/gtest.h" | 51 #include "testing/gtest/include/gtest/gtest.h" |
| 52 #include "wtf/Allocator.h" | |
| 49 #include "wtf/PtrUtil.h" | 53 #include "wtf/PtrUtil.h" |
| 54 #include "wtf/Vector.h" | |
| 50 #include <memory> | 55 #include <memory> |
| 51 | 56 |
| 52 namespace blink { | 57 namespace blink { |
| 53 | 58 |
| 54 namespace { | 59 namespace { |
| 55 | 60 |
| 61 const char testImageFilename[] = "white-1x1.png"; | |
| 62 const int testImageSize = 103; // size of web/tests/data/white-1x1.png | |
| 63 | |
| 56 class MockTaskRunner : public blink::WebTaskRunner { | 64 class MockTaskRunner : public blink::WebTaskRunner { |
| 57 void postTask(const WebTraceLocation&, Task*) override { } | 65 void postTask(const WebTraceLocation&, Task*) override { } |
| 58 void postDelayedTask(const WebTraceLocation&, Task*, double) override { } | 66 void postDelayedTask(const WebTraceLocation&, Task*, double) override { } |
| 59 WebTaskRunner* clone() override { return nullptr; } | 67 WebTaskRunner* clone() override { return nullptr; } |
| 60 double virtualTimeSeconds() const override { return 0.0; } | 68 double virtualTimeSeconds() const override { return 0.0; } |
| 61 double monotonicallyIncreasingVirtualTimeSeconds() const override { return 0 .0; } | 69 double monotonicallyIncreasingVirtualTimeSeconds() const override { return 0 .0; } |
| 62 }; | 70 }; |
| 63 | 71 |
| 64 } | 72 } |
| 65 | 73 |
| 66 class ResourceFetcherTestMockFetchContext : public FetchContext { | 74 class ResourceFetcherTestMockFetchContext : public FetchContext { |
| 67 public: | 75 public: |
| 68 static ResourceFetcherTestMockFetchContext* create() | 76 static ResourceFetcherTestMockFetchContext* create() |
| 69 { | 77 { |
| 70 return new ResourceFetcherTestMockFetchContext; | 78 return new ResourceFetcherTestMockFetchContext; |
| 71 } | 79 } |
| 72 | 80 |
| 73 virtual ~ResourceFetcherTestMockFetchContext() { } | 81 virtual ~ResourceFetcherTestMockFetchContext() { } |
| 74 | 82 |
| 75 bool allowImage(bool imagesEnabled, const KURL&) const override { return tru e; } | 83 bool allowImage(bool imagesEnabled, const KURL&) const override { return tru e; } |
| 76 bool canRequest(Resource::Type, const ResourceRequest&, const KURL&, const R esourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction) const o verride { return true; } | 84 bool canRequest(Resource::Type, const ResourceRequest&, const KURL&, const R esourceLoaderOptions&, bool forPreload, FetchRequest::OriginRestriction) const o verride { return true; } |
| 77 bool shouldLoadNewResource(Resource::Type) const override { return true; } | 85 bool shouldLoadNewResource(Resource::Type) const override { return true; } |
| 78 WebTaskRunner* loadingTaskRunner() const override { return m_runner.get(); } | 86 WebTaskRunner* loadingTaskRunner() const override { return m_runner.get(); } |
| 79 | 87 |
| 80 void setCachePolicy(CachePolicy policy) { m_policy = policy; } | 88 void setCachePolicy(CachePolicy policy) { m_policy = policy; } |
| 81 CachePolicy getCachePolicy() const override { return m_policy; } | 89 CachePolicy getCachePolicy() const override { return m_policy; } |
| 82 void setLoadComplete(bool complete) { m_complete = complete; } | 90 void setLoadComplete(bool complete) { m_complete = complete; } |
| 83 bool isLoadComplete() const override { return m_complete; } | 91 bool isLoadComplete() const override { return m_complete; } |
| 84 | 92 |
| 93 void addResourceTiming(const ResourceTimingInfo& resourceTimingInfo) overrid e { m_transferSize = resourceTimingInfo.transferSize(); } | |
| 94 long long getTransferSize() const { return m_transferSize; } | |
| 95 | |
| 85 private: | 96 private: |
| 86 ResourceFetcherTestMockFetchContext() | 97 ResourceFetcherTestMockFetchContext() |
| 87 : m_policy(CachePolicyVerify) | 98 : m_policy(CachePolicyVerify) |
| 88 , m_runner(wrapUnique(new MockTaskRunner)) | 99 , m_runner(wrapUnique(new MockTaskRunner)) |
| 89 , m_complete(false) | 100 , m_complete(false) |
| 101 , m_transferSize(-1) | |
| 90 { } | 102 { } |
| 91 | 103 |
| 92 CachePolicy m_policy; | 104 CachePolicy m_policy; |
| 93 std::unique_ptr<MockTaskRunner> m_runner; | 105 std::unique_ptr<MockTaskRunner> m_runner; |
| 94 bool m_complete; | 106 bool m_complete; |
| 107 long long m_transferSize; | |
| 95 }; | 108 }; |
| 96 | 109 |
| 97 class ResourceFetcherTest : public ::testing::Test { | 110 class ResourceFetcherTest : public ::testing::Test { |
| 98 }; | 111 }; |
| 99 | 112 |
| 100 class TestResourceFactory : public ResourceFactory { | 113 class TestResourceFactory : public ResourceFactory { |
| 101 public: | 114 public: |
| 102 TestResourceFactory(Resource::Type type = Resource::Raw) | 115 TestResourceFactory(Resource::Type type = Resource::Raw) |
| 103 : ResourceFactory(type) { } | 116 : ResourceFactory(type) { } |
| 104 | 117 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 TEST_F(ResourceFetcherTest, VaryImage) | 211 TEST_F(ResourceFetcherTest, VaryImage) |
| 199 { | 212 { |
| 200 ResourceFetcher* fetcher = ResourceFetcher::create(ResourceFetcherTestMockFe tchContext::create()); | 213 ResourceFetcher* fetcher = ResourceFetcher::create(ResourceFetcherTestMockFe tchContext::create()); |
| 201 | 214 |
| 202 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html"); | 215 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html"); |
| 203 ResourceResponse response; | 216 ResourceResponse response; |
| 204 response.setURL(url); | 217 response.setURL(url); |
| 205 response.setHTTPStatusCode(200); | 218 response.setHTTPStatusCode(200); |
| 206 response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=3600"); | 219 response.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=3600"); |
| 207 response.setHTTPHeaderField(HTTPNames::Vary, "*"); | 220 response.setHTTPHeaderField(HTTPNames::Vary, "*"); |
| 208 URLTestHelpers::registerMockedURLLoadWithCustomResponse(url, "white-1x1.png" , WebString::fromUTF8(""), WrappedResourceResponse(response)); | 221 URLTestHelpers::registerMockedURLLoadWithCustomResponse(url, testImageFilena me, WebString::fromUTF8(""), WrappedResourceResponse(response)); |
| 209 | 222 |
| 210 FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo()); | 223 FetchRequest fetchRequestOriginal = FetchRequest(url, FetchInitiatorInfo()); |
| 211 Resource* resource = fetcher->requestResource(fetchRequestOriginal, TestReso urceFactory(Resource::Image)); | 224 Resource* resource = fetcher->requestResource(fetchRequestOriginal, TestReso urceFactory(Resource::Image)); |
| 212 ASSERT_TRUE(resource); | 225 ASSERT_TRUE(resource); |
| 213 Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); | 226 Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests(); |
| 214 ASSERT_TRUE(resource->hasVaryHeader()); | 227 ASSERT_TRUE(resource->hasVaryHeader()); |
| 215 | 228 |
| 216 FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo()); | 229 FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo()); |
| 217 Resource* newResource = fetcher->requestResource(fetchRequest, TestResourceF actory(Resource::Image)); | 230 Resource* newResource = fetcher->requestResource(fetchRequest, TestResourceF actory(Resource::Image)); |
| 218 EXPECT_EQ(resource, newResource); | 231 EXPECT_EQ(resource, newResource); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 372 // This emulates a modal dialog triggering a nested run loop inside | 385 // This emulates a modal dialog triggering a nested run loop inside |
| 373 // ResourceLoader::cancel(). If the ResourceLoader doesn't promptly cancel its | 386 // ResourceLoader::cancel(). If the ResourceLoader doesn't promptly cancel its |
| 374 // WebURLLoader before notifying its clients, a nested run loop may send a | 387 // WebURLLoader before notifying its clients, a nested run loop may send a |
| 375 // network response, leading to an invalid state transition in ResourceLoader. | 388 // network response, leading to an invalid state transition in ResourceLoader. |
| 376 TEST_F(ResourceFetcherTest, ResponseOnCancel) | 389 TEST_F(ResourceFetcherTest, ResponseOnCancel) |
| 377 { | 390 { |
| 378 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html"); | 391 KURL url(ParsedURLString, "http://127.0.0.1:8000/foo.html"); |
| 379 ResourceResponse response; | 392 ResourceResponse response; |
| 380 response.setURL(url); | 393 response.setURL(url); |
| 381 response.setHTTPStatusCode(200); | 394 response.setHTTPStatusCode(200); |
| 382 URLTestHelpers::registerMockedURLLoadWithCustomResponse(url, "white-1x1.png" , WebString::fromUTF8(""), WrappedResourceResponse(response)); | 395 URLTestHelpers::registerMockedURLLoadWithCustomResponse(url, testImageFilena me, WebString::fromUTF8(""), WrappedResourceResponse(response)); |
| 383 | 396 |
| 384 ResourceFetcher* fetcher = ResourceFetcher::create(ResourceFetcherTestMockFe tchContext::create()); | 397 ResourceFetcher* fetcher = ResourceFetcher::create(ResourceFetcherTestMockFe tchContext::create()); |
| 385 FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo()); | 398 FetchRequest fetchRequest = FetchRequest(url, FetchInitiatorInfo()); |
| 386 Resource* resource = fetcher->requestResource(fetchRequest, TestResourceFact ory(Resource::Raw)); | 399 Resource* resource = fetcher->requestResource(fetchRequest, TestResourceFact ory(Resource::Raw)); |
| 387 Persistent<ServeRequestsOnCompleteClient> client = new ServeRequestsOnComple teClient(); | 400 Persistent<ServeRequestsOnCompleteClient> client = new ServeRequestsOnComple teClient(); |
| 388 resource->addClient(client); | 401 resource->addClient(client); |
| 389 resource->loader()->cancel(); | 402 resource->loader()->cancel(); |
| 390 resource->removeClient(client); | 403 resource->removeClient(client); |
| 391 Platform::current()->getURLLoaderMockFactory()->unregisterURL(url); | 404 Platform::current()->getURLLoaderMockFactory()->unregisterURL(url); |
| 392 } | 405 } |
| 393 | 406 |
| 407 class ScopedMockRedirectRequester { | |
| 408 STACK_ALLOCATED(); | |
| 409 WTF_MAKE_NONCOPYABLE(ScopedMockRedirectRequester); | |
| 410 | |
| 411 public: | |
| 412 ScopedMockRedirectRequester() | |
| 413 : m_context(nullptr) | |
| 414 { | |
| 415 } | |
| 416 | |
| 417 ~ScopedMockRedirectRequester() | |
| 418 { | |
| 419 cleanUp(); | |
| 420 } | |
| 421 | |
| 422 void registerRedirect(const WebString& fromURL, const WebString& toURL) | |
| 423 { | |
| 424 KURL redirectURL(ParsedURLString, fromURL); | |
| 425 WebURLResponse redirectResponse; | |
| 426 redirectResponse.initialize(); | |
| 427 redirectResponse.setURL(redirectURL); | |
| 428 redirectResponse.setHTTPStatusCode(301); | |
| 429 redirectResponse.setHTTPHeaderField(HTTPNames::Location, toURL); | |
| 430 Platform::current()->getURLLoaderMockFactory()->registerURL(redirectURL, redirectResponse, ""); | |
| 431 m_registeredURLs.append(redirectURL); | |
| 432 } | |
| 433 | |
| 434 void registerFinalResource(const WebString& url) | |
| 435 { | |
| 436 KURL finalURL(ParsedURLString, url); | |
| 437 WebURLResponse finalResponse; | |
| 438 finalResponse.initialize(); | |
| 439 finalResponse.setURL(finalURL); | |
| 440 finalResponse.setHTTPStatusCode(200); | |
| 441 URLTestHelpers::registerMockedURLLoadWithCustomResponse(finalURL, testIm ageFilename, "", finalResponse); | |
| 442 m_registeredURLs.append(finalURL); | |
| 443 } | |
| 444 | |
| 445 void request(const WebString& url) | |
| 446 { | |
| 447 DCHECK(!m_context); | |
| 448 m_context = ResourceFetcherTestMockFetchContext::create(); | |
| 449 ResourceFetcher* fetcher = ResourceFetcher::create(m_context); | |
| 450 FetchRequest fetchRequest = FetchRequest(ResourceRequest(url), FetchInit iatorInfo()); | |
| 451 Resource* resource = fetcher->requestResource(fetchRequest, TestResource Factory()); | |
| 452 m_cachedResources.append(resource); | |
| 453 Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequest s(); | |
| 454 } | |
| 455 | |
| 456 void cleanUp() | |
| 457 { | |
| 458 for (const KURL& url : m_registeredURLs) { | |
| 459 Platform::current()->getURLLoaderMockFactory()->unregisterURL(url); | |
| 460 } | |
| 461 m_registeredURLs.clear(); | |
| 462 for (const auto& resource : m_cachedResources) { | |
| 463 memoryCache()->remove(resource); | |
| 464 } | |
| 465 m_cachedResources.clear(); | |
| 466 } | |
| 467 | |
| 468 ResourceFetcherTestMockFetchContext* context() const { return m_context; } | |
| 469 | |
| 470 private: | |
| 471 Vector<KURL> m_registeredURLs; | |
| 472 HeapVector<Member<Resource>> m_cachedResources; | |
| 473 Member<ResourceFetcherTestMockFetchContext> m_context; | |
| 474 }; | |
| 475 | |
| 476 TEST_F(ResourceFetcherTest, SameOriginRedirect) | |
| 477 { | |
| 478 const char redirectURL[] = "http://127.0.0.1:8000/redirect.html"; | |
| 479 const char finalURL[] = "http://127.0.0.1:8000/final.html"; | |
| 480 ScopedMockRedirectRequester requester; | |
| 481 requester.registerRedirect(redirectURL, finalURL); | |
| 482 requester.registerFinalResource(finalURL); | |
| 483 requester.request(redirectURL); | |
| 484 | |
| 485 // The magic number "300" is specified as the redirect overhead in | |
|
Kunihiko Sakamoto
2016/07/01 10:12:35
Can you define this magic number as a constant?
Adam Rice
2016/07/04 02:44:18
Done.
| |
| 486 // WebURLLoaderMock::ServeRedirect | |
| 487 EXPECT_EQ(300 + testImageSize, requester.context()->getTransferSize()); | |
| 488 } | |
| 489 | |
| 490 TEST_F(ResourceFetcherTest, CrossOriginRedirect) | |
| 491 { | |
| 492 const char redirectURL[] = "http://otherorigin.test/redirect.html"; | |
| 493 const char finalURL[] = "http://127.0.0.1:8000/final.html"; | |
| 494 ScopedMockRedirectRequester requester; | |
| 495 requester.registerRedirect(redirectURL, finalURL); | |
| 496 requester.registerFinalResource(finalURL); | |
| 497 requester.request(redirectURL); | |
| 498 | |
| 499 EXPECT_EQ(testImageSize, requester.context()->getTransferSize()); | |
| 500 } | |
| 501 | |
| 502 TEST_F(ResourceFetcherTest, ComplexCrossOriginRedirect) | |
| 503 { | |
| 504 const char redirectURL1[] = "http://127.0.0.1:8000/redirect1.html"; | |
| 505 const char redirectURL2[] = "http://otherorigin.test/redirect2.html"; | |
| 506 const char redirectURL3[] = "http://127.0.0.1:8000/redirect3.html"; | |
| 507 const char finalURL[] = "http://127.0.0.1:8000/final.html"; | |
| 508 ScopedMockRedirectRequester requester; | |
| 509 requester.registerRedirect(redirectURL1, redirectURL2); | |
| 510 requester.registerRedirect(redirectURL2, redirectURL3); | |
| 511 requester.registerRedirect(redirectURL3, finalURL); | |
| 512 requester.registerFinalResource(finalURL); | |
| 513 requester.request(redirectURL1); | |
| 514 | |
| 515 EXPECT_EQ(testImageSize, requester.context()->getTransferSize()); | |
| 516 } | |
| 517 | |
| 394 } // namespace blink | 518 } // namespace blink |
| OLD | NEW |