Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "net/test/embedded_test_server/http_response.h" | 26 #include "net/test/embedded_test_server/http_response.h" |
| 27 #include "testing/gmock/include/gmock/gmock.h" | 27 #include "testing/gmock/include/gmock/gmock.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 28 #include "testing/gtest/include/gtest/gtest.h" |
| 29 | 29 |
| 30 namespace predictors { | 30 namespace predictors { |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 const char kFooHost[] = "foo.com"; | 34 const char kFooHost[] = "foo.com"; |
| 35 const char kBarHost[] = "bar.com"; | 35 const char kBarHost[] = "bar.com"; |
| 36 const char kBazHost[] = "baz.com"; | |
| 36 | 37 |
| 37 const char kImageMime[] = "image/png"; | 38 const char kImageMime[] = "image/png"; |
| 38 const char kStyleMime[] = "text/css"; | 39 const char kStyleMime[] = "text/css"; |
| 39 const char kJavascriptMime[] = "application/javascript"; | 40 const char kJavascriptMime[] = "application/javascript"; |
| 40 | 41 |
| 41 // Paths to resources handled by a custom request handler. They return empty | 42 // Paths to resources handled by a custom request handler. They return empty |
| 42 // responses with controllable response headers. | 43 // responses with controllable response headers. |
| 43 const char kImagePath[] = "/handled-by-test/image.png"; | 44 const char kImagePath[] = "/handled-by-test/image.png"; |
| 44 const char kImagePath2[] = "/handled-by-test/image2.png"; | 45 const char kImagePath2[] = "/handled-by-test/image2.png"; |
| 45 const char kStylePath[] = "/handled-by-test/style.css"; | 46 const char kStylePath[] = "/handled-by-test/style.css"; |
| 46 const char kStylePath2[] = "/handled-by-test/style2.css"; | 47 const char kStylePath2[] = "/handled-by-test/style2.css"; |
| 47 const char kScriptPath[] = "/handled-by-test/script.js"; | 48 const char kScriptPath[] = "/handled-by-test/script.js"; |
| 48 const char kScriptPath2[] = "/handled-by-test/script2.js"; | 49 const char kScriptPath2[] = "/handled-by-test/script2.js"; |
| 49 const char kFontPath[] = "/handled-by-test/font.ttf"; | 50 const char kFontPath[] = "/handled-by-test/font.ttf"; |
| 50 const char kRedirectPath[] = "/handled-by-test/redirect.html"; | 51 const char kRedirectPath[] = "/handled-by-test/redirect.html"; |
| 51 const char kRedirectPath2[] = "/handled-by-test/redirect2.html"; | 52 const char kRedirectPath2[] = "/handled-by-test/redirect2.html"; |
| 52 const char kRedirectPath3[] = "/handled-by-test/redirect3.html"; | 53 const char kRedirectPath3[] = "/handled-by-test/redirect3.html"; |
| 53 | 54 |
| 54 // These are loaded from a file by the test server. | 55 // These are loaded from a file by the test server. |
| 55 const char kHtmlSubresourcesPath[] = "/predictors/html_subresources.html"; | 56 const char kHtmlSubresourcesPath[] = "/predictors/html_subresources.html"; |
| 56 const char kHtmlDocumentWritePath[] = "/predictors/document_write.html"; | 57 const char kHtmlDocumentWritePath[] = "/predictors/document_write.html"; |
| 57 const char kScriptDocumentWritePath[] = "/predictors/document_write.js"; | 58 const char kScriptDocumentWritePath[] = "/predictors/document_write.js"; |
| 58 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; | 59 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; |
| 59 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; | 60 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; |
| 60 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; | 61 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; |
| 61 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; | 62 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; |
| 62 const char kHtmlXHRPath[] = "/predictors/xhr.html"; | 63 const char kHtmlXHRPath[] = "/predictors/xhr.html"; |
| 63 const char kScriptXHRPath[] = "/predictors/xhr.js"; | 64 const char kScriptXHRPath[] = "/predictors/xhr.js"; |
| 64 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; | 65 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; |
| 66 const char kHtmlJavascriptRedirectPath[] = | |
| 67 "/predictors/javascript_redirect.html"; | |
| 65 | 68 |
| 66 struct ResourceSummary { | 69 struct ResourceSummary { |
| 67 ResourceSummary() | 70 ResourceSummary() |
| 68 : version(0), | 71 : version(0), |
| 69 is_no_store(false), | 72 is_no_store(false), |
| 70 is_external(false), | 73 is_external(false), |
| 71 is_observable(true), | 74 is_observable(true), |
| 72 is_prohibited(false) {} | 75 is_prohibited(false) {} |
| 73 | 76 |
| 74 ResourcePrefetchPredictor::URLRequestSummary request; | 77 ResourcePrefetchPredictor::URLRequestSummary request; |
| 75 std::string content; | 78 std::string content; |
| 76 // Allows to update HTTP ETag. | 79 // Allows to update HTTP ETag. |
| 77 size_t version; | 80 size_t version; |
| 78 // True iff "Cache-control: no-store" header is present. | 81 // True iff "Cache-control: no-store" header is present. |
| 79 bool is_no_store; | 82 bool is_no_store; |
| 80 // True iff a request for this resource must be ignored by the custom handler. | 83 // True iff a request for this resource must be ignored by the custom handler. |
| 81 bool is_external; | 84 bool is_external; |
| 82 // True iff the LearningObserver must observe this resource. | 85 // True iff the LearningObserver must observe this resource. |
| 83 bool is_observable; | 86 bool is_observable; |
| 84 // A request with |is_prohibited| set to true makes the test that originates | 87 // A request with |is_prohibited| set to true makes the test that originates |
| 85 // the request fail. | 88 // the request fail. |
| 86 bool is_prohibited; | 89 bool is_prohibited; |
| 87 }; | 90 }; |
| 88 | 91 |
| 89 struct RedirectEdge { | 92 struct RedirectEdge { |
| 90 // This response code should be returned by previous url in the chain. | 93 // This response code should be returned by previous url in the chain. |
| 91 net::HttpStatusCode code; | 94 net::HttpStatusCode code; |
| 92 GURL url; | 95 GURL url; |
| 96 bool is_client_side; | |
| 93 }; | 97 }; |
| 94 | 98 |
| 95 // Helper class to track and allow waiting for ResourcePrefetchPredictor | 99 // Helper class to track and allow waiting for ResourcePrefetchPredictor |
| 96 // initialization. WARNING: OnPredictorInitialized event will not be fired if | 100 // initialization. WARNING: OnPredictorInitialized event will not be fired if |
| 97 // ResourcePrefetchPredictor is initialized before the observer creation. | 101 // ResourcePrefetchPredictor is initialized before the observer creation. |
| 98 class InitializationObserver : public TestObserver { | 102 class InitializationObserver : public TestObserver { |
| 99 public: | 103 public: |
| 100 explicit InitializationObserver(ResourcePrefetchPredictor* predictor) | 104 explicit InitializationObserver(ResourcePrefetchPredictor* predictor) |
| 101 : TestObserver(predictor) {} | 105 : TestObserver(predictor) {} |
| 102 | 106 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 ModifySubresourceForComparison(&subresource, match_navigation_id); | 184 ModifySubresourceForComparison(&subresource, match_navigation_id); |
| 181 | 185 |
| 182 EXPECT_THAT(actual_subresources, | 186 EXPECT_THAT(actual_subresources, |
| 183 testing::UnorderedElementsAreArray(expected_subresources)); | 187 testing::UnorderedElementsAreArray(expected_subresources)); |
| 184 } | 188 } |
| 185 | 189 |
| 186 std::string CreateVersionedETag(size_t version, const std::string& path) { | 190 std::string CreateVersionedETag(size_t version, const std::string& path) { |
| 187 return base::StringPrintf("'%zu%s'", version, path.c_str()); | 191 return base::StringPrintf("'%zu%s'", version, path.c_str()); |
| 188 } | 192 } |
| 189 | 193 |
| 194 GURL GetRequestURL(const net::test_server::HttpRequest& request) { | |
|
alexilin
2017/01/05 17:11:46
Extracted from HandleResourceRequest
| |
| 195 GURL resource_url = request.GetURL(); | |
| 196 // Retrieve the host that was used in the request because | |
| 197 // resource_url contains a resolved host (e.g. 127.0.0.1). | |
| 198 if (request.headers.find("Host") != request.headers.end()) { | |
| 199 auto host_port_pair = | |
| 200 net::HostPortPair::FromString(request.headers.at("Host")); | |
| 201 GURL::Replacements replace_host; | |
| 202 replace_host.SetHostStr(host_port_pair.host()); | |
| 203 resource_url = resource_url.ReplaceComponents(replace_host); | |
| 204 } else { | |
| 205 ADD_FAILURE() << "Host header was not found in a HttpRequest to url: " | |
| 206 << resource_url.spec(); | |
| 207 } | |
| 208 | |
| 209 return resource_url; | |
| 210 } | |
| 211 | |
| 190 } // namespace | 212 } // namespace |
| 191 | 213 |
| 192 // Helper class to track and allow waiting for a single OnNavigationLearned | 214 // Helper class to track and allow waiting for a single OnNavigationLearned |
| 193 // event. The information provided by this event is also used to verify that | 215 // event. The information provided by this event is also used to verify that |
| 194 // ResourcePrefetchPredictor works as expected. | 216 // ResourcePrefetchPredictor works as expected. |
| 195 class LearningObserver : public TestObserver { | 217 class LearningObserver : public TestObserver { |
| 196 public: | 218 public: |
| 197 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 219 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
| 198 | 220 |
| 199 LearningObserver(ResourcePrefetchPredictor* predictor, | 221 LearningObserver(ResourcePrefetchPredictor* predictor, |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 297 NavigateToURLAndCheckSubresources(main_frame_url); | 319 NavigateToURLAndCheckSubresources(main_frame_url); |
| 298 ClearCache(); | 320 ClearCache(); |
| 299 // It is needed to have at least two resource hits to trigger prefetch. | 321 // It is needed to have at least two resource hits to trigger prefetch. |
| 300 NavigateToURLAndCheckSubresources(main_frame_url); | 322 NavigateToURLAndCheckSubresources(main_frame_url); |
| 301 ClearCache(); | 323 ClearCache(); |
| 302 // Prefetch all needed resources and change expectations so that all | 324 // Prefetch all needed resources and change expectations so that all |
| 303 // cacheable resources should be served from cache next navigation. | 325 // cacheable resources should be served from cache next navigation. |
| 304 PrefetchURL(main_frame_url); | 326 PrefetchURL(main_frame_url); |
| 305 // To be sure that the browser send no requests to the server after | 327 // To be sure that the browser send no requests to the server after |
| 306 // prefetching. | 328 // prefetching. |
| 329 NavigateToURLAndCheckSubresourcesAllCached(main_frame_url); | |
| 330 } | |
| 331 | |
| 332 void NavigateToURLAndCheckSubresourcesAllCached(const GURL& navigation_url) { | |
| 307 for (auto& kv : resources_) { | 333 for (auto& kv : resources_) { |
| 308 if (kv.second.is_observable) | 334 if (kv.second.is_observable) |
| 309 kv.second.is_prohibited = true; | 335 kv.second.is_prohibited = true; |
| 310 } | 336 } |
| 311 NavigateToURLAndCheckSubresources(main_frame_url); | 337 NavigateToURLAndCheckSubresources(navigation_url); |
| 312 for (auto& kv : resources_) { | 338 for (auto& kv : resources_) { |
| 313 if (kv.second.is_observable) | 339 if (kv.second.is_observable) |
| 314 kv.second.is_prohibited = false; | 340 kv.second.is_prohibited = false; |
| 315 } | 341 } |
| 316 } | 342 } |
| 317 | 343 |
| 318 void NavigateToURLAndCheckSubresources( | 344 void NavigateToURLAndCheckSubresources( |
| 319 const GURL& main_frame_url, | 345 const GURL& navigation_url, |
| 320 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { | 346 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { |
| 321 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); | 347 GURL initial_url = GetLastClientSideRedirectEndpoint(navigation_url); |
| 348 GURL main_frame_url = GetRedirectEndpoint(navigation_url); | |
| 322 std::vector<URLRequestSummary> url_request_summaries; | 349 std::vector<URLRequestSummary> url_request_summaries; |
| 323 for (const auto& kv : resources_) { | 350 for (const auto& kv : resources_) { |
| 324 if (kv.second.is_observable) { | 351 if (kv.second.is_observable) { |
| 325 url_request_summaries.push_back( | 352 url_request_summaries.push_back( |
| 326 GetURLRequestSummaryForResource(endpoint_url, kv.second)); | 353 GetURLRequestSummaryForResource(main_frame_url, kv.second)); |
| 327 } | 354 } |
| 328 } | 355 } |
| 329 | 356 |
| 330 bool match_navigation_id = | 357 bool match_navigation_id = |
| 331 disposition == WindowOpenDisposition::CURRENT_TAB; | 358 disposition == WindowOpenDisposition::CURRENT_TAB; |
| 332 | 359 |
| 333 LearningObserver observer( | 360 LearningObserver observer( |
| 334 predictor_, UpdateAndGetVisitCount(main_frame_url), | 361 predictor_, UpdateAndGetVisitCount(initial_url), |
| 335 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), | 362 CreatePageRequestSummary(main_frame_url.spec(), initial_url.spec(), |
| 336 url_request_summaries), | 363 url_request_summaries), |
| 337 match_navigation_id); | 364 match_navigation_id); |
| 338 ui_test_utils::NavigateToURLWithDisposition( | 365 ui_test_utils::NavigateToURLWithDisposition( |
| 339 browser(), main_frame_url, disposition, | 366 browser(), navigation_url, disposition, |
| 340 ui_test_utils::BROWSER_TEST_NONE); | 367 ui_test_utils::BROWSER_TEST_NONE); |
| 341 observer.Wait(); | 368 observer.Wait(); |
| 369 | |
| 342 for (auto& kv : resources_) { | 370 for (auto& kv : resources_) { |
| 343 if (kv.second.is_observable) | 371 if (kv.second.is_observable) |
| 344 kv.second.request.was_cached = true; | 372 kv.second.request.was_cached = true; |
| 345 } | 373 } |
| 346 for (const auto& nav : observer.current_navigation_ids()) | 374 for (const auto& nav : observer.current_navigation_ids()) |
| 347 navigation_id_history_.insert(nav); | 375 navigation_id_history_.insert(nav); |
| 348 } | 376 } |
| 349 | 377 |
| 350 void PrefetchURL(const GURL& main_frame_url) { | 378 void PrefetchURL(const GURL& main_frame_url) { |
| 351 PrefetchingObserver observer(predictor_, main_frame_url); | 379 PrefetchingObserver observer(predictor_, main_frame_url); |
| 352 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL); | 380 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL); |
| 353 observer.Wait(); | 381 observer.Wait(); |
| 354 for (auto& kv : resources_) { | 382 for (auto& kv : resources_) { |
| 355 if (kv.second.is_observable) | 383 if (kv.second.is_observable) |
| 356 kv.second.request.was_cached = true; | 384 kv.second.request.was_cached = true; |
| 357 } | 385 } |
| 358 } | 386 } |
| 359 | 387 |
| 388 void TryToPrefetchURL(const GURL& main_frame_url) { | |
| 389 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL); | |
|
Benoit L
2017/01/09 14:31:47
Isn't this function only used in one place?
If so,
alexilin
2017/01/09 15:08:15
Well, the problem is that |predictor_| is private.
Benoit L
2017/01/09 15:21:03
Acknowledged.
| |
| 390 } | |
| 391 | |
| 360 ResourceSummary* AddResource(const GURL& resource_url, | 392 ResourceSummary* AddResource(const GURL& resource_url, |
| 361 content::ResourceType resource_type, | 393 content::ResourceType resource_type, |
| 362 net::RequestPriority priority) { | 394 net::RequestPriority priority) { |
| 363 auto pair_and_whether_inserted = | 395 auto pair_and_whether_inserted = |
| 364 resources_.insert(std::make_pair(resource_url, ResourceSummary())); | 396 resources_.insert(std::make_pair(resource_url, ResourceSummary())); |
| 365 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url | 397 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url |
| 366 << " was inserted twice"; | 398 << " was inserted twice"; |
| 367 ResourceSummary* resource = &pair_and_whether_inserted.first->second; | 399 ResourceSummary* resource = &pair_and_whether_inserted.first->second; |
| 368 resource->request.resource_url = resource_url; | 400 resource->request.resource_url = resource_url; |
| 369 resource->request.resource_type = resource_type; | 401 resource->request.resource_type = resource_type; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 483 while (true) { | 515 while (true) { |
| 484 std::map<GURL, RedirectEdge>::const_iterator it = | 516 std::map<GURL, RedirectEdge>::const_iterator it = |
| 485 redirects_.find(current); | 517 redirects_.find(current); |
| 486 if (it == redirects_.end()) | 518 if (it == redirects_.end()) |
| 487 break; | 519 break; |
| 488 current = it->second.url; | 520 current = it->second.url; |
| 489 } | 521 } |
| 490 return current; | 522 return current; |
| 491 } | 523 } |
| 492 | 524 |
| 525 GURL GetLastClientSideRedirectEndpoint(const GURL& initial_url) const { | |
| 526 GURL last_client_side_redirect_url = initial_url; | |
| 527 GURL current = initial_url; | |
| 528 while (true) { | |
| 529 std::map<GURL, RedirectEdge>::const_iterator it = | |
| 530 redirects_.find(current); | |
| 531 if (it == redirects_.end()) | |
| 532 break; | |
| 533 current = it->second.url; | |
| 534 if (it->second.is_client_side) | |
| 535 last_client_side_redirect_url = current; | |
| 536 } | |
| 537 return last_client_side_redirect_url; | |
| 538 } | |
| 539 | |
| 493 void MonitorResourceRequest( | 540 void MonitorResourceRequest( |
| 494 const net::test_server::HttpRequest& request) const { | 541 const net::test_server::HttpRequest& request) const { |
| 495 std::map<GURL, ResourceSummary>::const_iterator resource_it = | 542 std::map<GURL, ResourceSummary>::const_iterator resource_it = |
| 496 resources_.find(request.GetURL()); | 543 resources_.find(request.GetURL()); |
| 497 if (resource_it == resources_.end()) | 544 if (resource_it == resources_.end()) |
| 498 return; | 545 return; |
| 499 | 546 |
| 500 const ResourceSummary& summary = resource_it->second; | 547 const ResourceSummary& summary = resource_it->second; |
| 501 EXPECT_FALSE(summary.is_prohibited) << request.GetURL() << "\n" | 548 EXPECT_FALSE(summary.is_prohibited) << request.GetURL() << "\n" |
| 502 << request.all_headers; | 549 << request.all_headers; |
| 503 } | 550 } |
| 504 | 551 |
| 505 // The custom handler for resource requests from the browser to an | 552 // The custom handler for resource requests from the browser to an |
| 506 // EmbeddedTestServer. Runs on the EmbeddedTestServer IO thread. | 553 // EmbeddedTestServer. Runs on the EmbeddedTestServer IO thread. |
| 507 // Finds the data to serve requests in |resources_| map keyed by a request | 554 // Finds the data to serve requests in |resources_| map keyed by a request |
| 508 // URL. | 555 // URL. |
| 509 // Uses also the following headers from the |request|: | 556 // Uses also the following headers from the |request|: |
| 510 // - "Host" to retrieve the host that actually was issued by the browser. | 557 // - "Host" to retrieve the host that actually was issued by the browser. |
| 511 // - "If-None-Match" to determine if the resource is still valid. If the | 558 // - "If-None-Match" to determine if the resource is still valid. If the |
| 512 // ETag values match, the handler responds with a HTTP 304 status. | 559 // ETag values match, the handler responds with a HTTP 304 status. |
| 513 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( | 560 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( |
| 514 const net::test_server::HttpRequest& request) const { | 561 const net::test_server::HttpRequest& request) const { |
| 515 GURL resource_url = request.GetURL(); | |
| 516 // Retrieve the host that was used in the request because | |
| 517 // resource_url contains a resolved host (e.g. 127.0.0.1). | |
| 518 if (request.headers.find("Host") != request.headers.end()) { | |
| 519 auto host_port_pair = | |
| 520 net::HostPortPair::FromString(request.headers.at("Host")); | |
| 521 GURL::Replacements replace_host; | |
| 522 replace_host.SetHostStr(host_port_pair.host()); | |
| 523 resource_url = resource_url.ReplaceComponents(replace_host); | |
| 524 } else { | |
| 525 ADD_FAILURE() << "Host header was not found in a HttpRequest to url: " | |
| 526 << resource_url.spec(); | |
| 527 } | |
| 528 | |
| 529 std::map<GURL, ResourceSummary>::const_iterator resource_it = | 562 std::map<GURL, ResourceSummary>::const_iterator resource_it = |
| 530 resources_.find(resource_url); | 563 resources_.find(GetRequestURL(request)); |
| 531 if (resource_it == resources_.end()) | 564 if (resource_it == resources_.end()) |
| 532 return nullptr; | 565 return nullptr; |
| 533 | 566 |
| 534 const ResourceSummary& summary = resource_it->second; | 567 const ResourceSummary& summary = resource_it->second; |
| 535 if (summary.is_external) | 568 if (summary.is_external) |
| 536 return nullptr; | 569 return nullptr; |
| 537 | 570 |
| 538 auto http_response = | 571 auto http_response = |
| 539 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 572 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 540 | 573 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 553 if (summary.is_no_store) | 586 if (summary.is_no_store) |
| 554 http_response->AddCustomHeader("Cache-Control", "no-store"); | 587 http_response->AddCustomHeader("Cache-Control", "no-store"); |
| 555 if (summary.request.has_validators) { | 588 if (summary.request.has_validators) { |
| 556 http_response->AddCustomHeader( | 589 http_response->AddCustomHeader( |
| 557 "ETag", CreateVersionedETag(summary.version, request.relative_url)); | 590 "ETag", CreateVersionedETag(summary.version, request.relative_url)); |
| 558 } | 591 } |
| 559 if (summary.request.always_revalidate) | 592 if (summary.request.always_revalidate) |
| 560 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 593 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 561 else | 594 else |
| 562 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 595 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 596 | |
| 563 return std::move(http_response); | 597 return std::move(http_response); |
| 564 } | 598 } |
| 565 | 599 |
| 566 // The custom handler for redirect requests from the browser to an | 600 // The custom handler for redirect requests from the browser to an |
| 567 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. | 601 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. |
| 568 // Finds the data to serve requests in |redirects_| map keyed by a request | 602 // Finds the data to serve requests in |redirects_| map keyed by a request |
| 569 // URL. | 603 // URL. |
| 570 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( | 604 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 571 const net::test_server::HttpRequest& request) const { | 605 const net::test_server::HttpRequest& request) const { |
| 572 std::map<GURL, RedirectEdge>::const_iterator redirect_it = | 606 std::map<GURL, RedirectEdge>::const_iterator redirect_it = |
| 573 redirects_.find(request.GetURL()); | 607 redirects_.find(GetRequestURL(request)); |
| 574 if (redirect_it == redirects_.end()) | 608 if (redirect_it == redirects_.end() || redirect_it->second.is_client_side) |
| 575 return nullptr; | 609 return nullptr; |
| 576 | 610 |
| 577 auto http_response = | 611 auto http_response = |
| 578 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 612 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 579 http_response->set_code(redirect_it->second.code); | 613 http_response->set_code(redirect_it->second.code); |
| 580 http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); | 614 http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); |
| 581 return std::move(http_response); | 615 return std::move(http_response); |
| 582 } | 616 } |
| 583 | 617 |
| 584 size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { | 618 size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 599 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 633 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 600 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 634 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 601 net::HIGHEST); | 635 net::HIGHEST); |
| 602 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 636 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 603 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | 637 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 604 net::HIGHEST); | 638 net::HIGHEST); |
| 605 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); | 639 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); |
| 606 } | 640 } |
| 607 | 641 |
| 608 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) { | 642 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Redirect) { |
| 609 AddRedirectChain(GetURL(kRedirectPath), {{net::HTTP_MOVED_PERMANENTLY, | 643 GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath); |
| 610 GetURL(kHtmlSubresourcesPath)}}); | 644 AddRedirectChain(initial_url, {{net::HTTP_MOVED_PERMANENTLY, |
| 645 GetURL(kHtmlSubresourcesPath)}}); | |
| 611 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 646 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 612 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 647 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 613 net::HIGHEST); | 648 net::HIGHEST); |
| 614 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 649 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 615 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | 650 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 616 net::HIGHEST); | 651 net::HIGHEST); |
| 617 TestLearningAndPrefetching(GetURL(kRedirectPath)); | 652 TestLearningAndPrefetching(initial_url); |
| 618 } | 653 } |
| 619 | 654 |
| 620 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, RedirectChain) { | 655 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, RedirectChain) { |
| 621 AddRedirectChain(GetURL(kRedirectPath), | 656 GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath); |
| 622 {{net::HTTP_FOUND, GetURL(kRedirectPath2)}, | 657 AddRedirectChain(initial_url, |
| 623 {net::HTTP_MOVED_PERMANENTLY, GetURL(kRedirectPath3)}, | 658 {{net::HTTP_FOUND, |
| 659 embedded_test_server()->GetURL(kBarHost, kRedirectPath2)}, | |
| 660 {net::HTTP_MOVED_PERMANENTLY, | |
| 661 embedded_test_server()->GetURL(kBazHost, kRedirectPath3)}, | |
| 624 {net::HTTP_FOUND, GetURL(kHtmlSubresourcesPath)}}); | 662 {net::HTTP_FOUND, GetURL(kHtmlSubresourcesPath)}}); |
| 625 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 663 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 626 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 664 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 627 net::HIGHEST); | 665 net::HIGHEST); |
| 628 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 666 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 629 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | 667 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 630 net::HIGHEST); | 668 net::HIGHEST); |
| 631 TestLearningAndPrefetching(GetURL(kRedirectPath)); | 669 TestLearningAndPrefetching(initial_url); |
| 632 } | 670 } |
| 633 | 671 |
| 634 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | 672 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 635 HttpToHttpsRedirect) { | 673 HttpToHttpsRedirect) { |
| 636 EnableHttpsServer(); | 674 EnableHttpsServer(); |
| 637 AddRedirectChain(GetURL(kRedirectPath), | 675 GURL initial_url = embedded_test_server()->GetURL(kFooHost, kRedirectPath); |
| 676 AddRedirectChain(initial_url, | |
| 638 {{net::HTTP_MOVED_PERMANENTLY, | 677 {{net::HTTP_MOVED_PERMANENTLY, |
| 639 https_server()->GetURL(kHtmlSubresourcesPath)}}); | 678 https_server()->GetURL(kHtmlSubresourcesPath)}}); |
| 640 AddResource(https_server()->GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, | 679 AddResource(https_server()->GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, |
| 641 net::LOWEST); | 680 net::LOWEST); |
| 642 AddResource(https_server()->GetURL(kStylePath), | 681 AddResource(https_server()->GetURL(kStylePath), |
| 643 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | 682 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); |
| 644 AddResource(https_server()->GetURL(kScriptPath), | 683 AddResource(https_server()->GetURL(kScriptPath), |
| 645 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 684 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 646 AddResource(https_server()->GetURL(kFontPath), | 685 AddResource(https_server()->GetURL(kFontPath), |
| 647 content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); | 686 content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); |
| 648 TestLearningAndPrefetching(GetURL(kRedirectPath)); | 687 TestLearningAndPrefetching(initial_url); |
| 649 } | 688 } |
| 650 | 689 |
| 651 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | 690 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 652 JavascriptDocumentWrite) { | 691 JavascriptDocumentWrite) { |
| 653 auto externalScript = | 692 auto externalScript = |
| 654 AddExternalResource(GetURL(kScriptDocumentWritePath), | 693 AddExternalResource(GetURL(kScriptDocumentWritePath), |
| 655 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 694 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 656 externalScript->request.mime_type = kJavascriptMime; | 695 externalScript->request.mime_type = kJavascriptMime; |
| 657 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 696 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 658 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 697 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 790 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, | 829 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, |
| 791 net::MEDIUM), | 830 net::MEDIUM), |
| 792 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | 831 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 793 net::HIGHEST), | 832 net::HIGHEST), |
| 794 }; | 833 }; |
| 795 for (auto& resource : resources) | 834 for (auto& resource : resources) |
| 796 resource->request.always_revalidate = true; | 835 resource->request.always_revalidate = true; |
| 797 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); | 836 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); |
| 798 } | 837 } |
| 799 | 838 |
| 839 // Client-side redirects currently aren't tracked by ResourcePrefetchPredictor. | |
| 840 // Client-side redirect initiates a new navigation to the redirect destination | |
|
Benoit L
2017/01/09 14:31:47
nit: A client-side redirect... so that the OnLoad
alexilin
2017/01/09 15:08:16
Done.
| |
| 841 // URL and aborts the current navigation so that OnLoad event is not fired. | |
| 842 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | |
| 843 JavascriptRedirect) { | |
|
Benoit L
2017/01/09 14:31:47
nit: JavascriptRedirectsAreNotHandled?
alexilin
2017/01/09 15:08:15
Done.
| |
| 844 std::string redirect_path_with_query = | |
| 845 std::string(kHtmlJavascriptRedirectPath) + "?url=" + | |
| 846 GetURL(kHtmlSubresourcesPath).spec(); | |
| 847 GURL initial_url = | |
| 848 embedded_test_server()->GetURL(kBarHost, redirect_path_with_query); | |
| 849 AddRedirectChain(initial_url, {{net::HTTP_TEMPORARY_REDIRECT, | |
| 850 GetURL(kHtmlSubresourcesPath), true}}); | |
| 851 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | |
| 852 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 853 net::HIGHEST); | |
| 854 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | |
| 855 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 856 net::HIGHEST); | |
| 857 | |
| 858 // Two navigations will occur. LearningObserver will get event only for the | |
|
Benoit L
2017/01/09 14:31:47
nit: events
alexilin
2017/01/09 15:08:15
Done.
| |
| 859 // second navigation because the first one will be aborted. | |
| 860 NavigateToURLAndCheckSubresources(initial_url); | |
| 861 ClearCache(); | |
| 862 // It is needed to have at least two resource hits to trigger prefetch. | |
| 863 NavigateToURLAndCheckSubresources(initial_url); | |
| 864 ClearCache(); | |
| 865 // Prefetching of |initial_url| has no effect because there is no entry in | |
| 866 // the predictor database corresponding the client-side redirect. | |
| 867 TryToPrefetchURL(initial_url); | |
| 868 NavigateToURLAndCheckSubresources(initial_url); | |
| 869 ClearCache(); | |
| 870 // But the predictor database contains all subresources for the endpoint url | |
| 871 // so this prefetch works. | |
| 872 PrefetchURL(GetURL(kHtmlSubresourcesPath)); | |
| 873 NavigateToURLAndCheckSubresourcesAllCached(GetURL(kHtmlSubresourcesPath)); | |
| 874 } | |
| 875 | |
| 800 } // namespace predictors | 876 } // namespace predictors |
| OLD | NEW |