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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 58 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; | 58 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; |
| 59 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; | 59 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; |
| 60 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; | 60 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; |
| 61 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; | 61 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; |
| 62 const char kHtmlXHRPath[] = "/predictors/xhr.html"; | 62 const char kHtmlXHRPath[] = "/predictors/xhr.html"; |
| 63 const char kScriptXHRPath[] = "/predictors/xhr.js"; | 63 const char kScriptXHRPath[] = "/predictors/xhr.js"; |
| 64 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; | 64 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; |
| 65 | 65 |
| 66 struct ResourceSummary { | 66 struct ResourceSummary { |
| 67 ResourceSummary() | 67 ResourceSummary() |
| 68 : is_no_store(false), | 68 : version(0), |
| 69 version(0), | 69 is_no_store(false), |
| 70 is_external(false), | 70 is_external(false), |
| 71 should_be_recorded(true) {} | 71 is_observable(true), |
| 72 is_prohibited(false) {} | |
| 72 | 73 |
| 73 ResourcePrefetchPredictor::URLRequestSummary request; | 74 ResourcePrefetchPredictor::URLRequestSummary request; |
| 74 std::string content; | 75 std::string content; |
| 76 // Allows to update HTTP ETag. | |
| 77 size_t version; | |
| 78 // True iff "Cache-control: no-store" header is present. | |
| 75 bool is_no_store; | 79 bool is_no_store; |
| 76 size_t version; | 80 // True iff a request for this resource must be ignored by the custom handler. |
| 77 bool is_external; | 81 bool is_external; |
| 78 bool should_be_recorded; | 82 // True iff the LearningObserver must observe this resource. |
| 83 bool is_observable; | |
| 84 // A request with |is_prohibited| set to true makes the test that originates | |
| 85 // the request fail. | |
| 86 bool is_prohibited; | |
| 79 }; | 87 }; |
| 80 | 88 |
| 81 struct RedirectEdge { | 89 struct RedirectEdge { |
| 82 // This response code should be returned by previous url in the chain. | 90 // This response code should be returned by previous url in the chain. |
| 83 net::HttpStatusCode code; | 91 net::HttpStatusCode code; |
| 84 GURL url; | 92 GURL url; |
| 85 }; | 93 }; |
| 86 | 94 |
| 87 // Helper class to track and allow waiting for ResourcePrefetchPredictor | 95 // Helper class to track and allow waiting for ResourcePrefetchPredictor |
| 88 // initialization. WARNING: OnPredictorInitialized event will not be fired if | 96 // initialization. WARNING: OnPredictorInitialized event will not be fired if |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 | 176 |
| 169 for (auto& subresource : actual_subresources) | 177 for (auto& subresource : actual_subresources) |
| 170 ModifySubresourceForComparison(&subresource, match_navigation_id); | 178 ModifySubresourceForComparison(&subresource, match_navigation_id); |
| 171 for (auto& subresource : expected_subresources) | 179 for (auto& subresource : expected_subresources) |
| 172 ModifySubresourceForComparison(&subresource, match_navigation_id); | 180 ModifySubresourceForComparison(&subresource, match_navigation_id); |
| 173 | 181 |
| 174 EXPECT_THAT(actual_subresources, | 182 EXPECT_THAT(actual_subresources, |
| 175 testing::UnorderedElementsAreArray(expected_subresources)); | 183 testing::UnorderedElementsAreArray(expected_subresources)); |
| 176 } | 184 } |
| 177 | 185 |
| 186 std::string CreateVersionnedETag(size_t version, const std::string& path) { | |
| 187 return base::StringPrintf("'%zu%s'", version, path.c_str()); | |
| 188 } | |
| 189 | |
| 178 } // namespace | 190 } // namespace |
| 179 | 191 |
| 180 // Helper class to track and allow waiting for a single OnNavigationLearned | 192 // Helper class to track and allow waiting for a single OnNavigationLearned |
| 181 // event. The information provided by this event is also used to verify that | 193 // event. The information provided by this event is also used to verify that |
| 182 // ResourcePrefetchPredictor works as expected. | 194 // ResourcePrefetchPredictor works as expected. |
| 183 class LearningObserver : public TestObserver { | 195 class LearningObserver : public TestObserver { |
| 184 public: | 196 public: |
| 185 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 197 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
| 186 | 198 |
| 187 LearningObserver(ResourcePrefetchPredictor* predictor, | 199 LearningObserver(ResourcePrefetchPredictor* predictor, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 263 void SetUpOnMainThread() override { | 275 void SetUpOnMainThread() override { |
| 264 // Resolving all hosts to local allows us to have | 276 // Resolving all hosts to local allows us to have |
| 265 // cross domains navigations (matching url_visit_count_, etc). | 277 // cross domains navigations (matching url_visit_count_, etc). |
| 266 host_resolver()->AddRule("*", "127.0.0.1"); | 278 host_resolver()->AddRule("*", "127.0.0.1"); |
| 267 embedded_test_server()->RegisterRequestHandler( | 279 embedded_test_server()->RegisterRequestHandler( |
| 268 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, | 280 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| 269 base::Unretained(this))); | 281 base::Unretained(this))); |
| 270 embedded_test_server()->RegisterRequestHandler( | 282 embedded_test_server()->RegisterRequestHandler( |
| 271 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | 283 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| 272 base::Unretained(this))); | 284 base::Unretained(this))); |
| 285 embedded_test_server()->RegisterRequestMonitor(base::Bind( | |
| 286 &ResourcePrefetchPredictorBrowserTest::MonitorResourceRequest, | |
| 287 base::Unretained(this))); | |
| 273 ASSERT_TRUE(embedded_test_server()->Start()); | 288 ASSERT_TRUE(embedded_test_server()->Start()); |
| 274 predictor_ = | 289 predictor_ = |
| 275 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); | 290 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); |
| 276 ASSERT_TRUE(predictor_); | 291 ASSERT_TRUE(predictor_); |
| 277 EnsurePredictorInitialized(); | 292 EnsurePredictorInitialized(); |
| 278 } | 293 } |
| 279 | 294 |
| 280 void TestLearningAndPrefetching(const GURL& main_frame_url) { | 295 void TestLearningAndPrefetching(const GURL& main_frame_url) { |
| 281 // Navigate to |main_frame_url| and check all the expectations. | 296 // Navigate to |main_frame_url| and check all the expectations. |
| 282 NavigateToURLAndCheckSubresources(main_frame_url); | 297 NavigateToURLAndCheckSubresources(main_frame_url); |
| 283 ClearCache(); | 298 ClearCache(); |
| 284 // It is needed to have at least two resource hits to trigger prefetch. | 299 // It is needed to have at least two resource hits to trigger prefetch. |
| 285 NavigateToURLAndCheckSubresources(main_frame_url); | 300 NavigateToURLAndCheckSubresources(main_frame_url); |
| 286 ClearCache(); | 301 ClearCache(); |
| 287 // Prefetch all needed resources and change expectations so that all | 302 // Prefetch all needed resources and change expectations so that all |
| 288 // cacheable resources should be served from cache next navigation. | 303 // cacheable resources should be served from cache next navigation. |
| 289 PrefetchURL(main_frame_url); | 304 PrefetchURL(main_frame_url); |
| 305 // To be sure that the browser send no requests to the server after | |
| 306 // prefetching. | |
| 307 for (auto& kv : resources_) { | |
| 308 if (kv.second.is_observable) | |
| 309 kv.second.is_prohibited = true; | |
| 310 } | |
| 290 NavigateToURLAndCheckSubresources(main_frame_url); | 311 NavigateToURLAndCheckSubresources(main_frame_url); |
| 312 for (auto& kv : resources_) { | |
| 313 if (kv.second.is_observable) | |
| 314 kv.second.is_prohibited = false; | |
| 315 } | |
| 291 } | 316 } |
| 292 | 317 |
| 293 void NavigateToURLAndCheckSubresources( | 318 void NavigateToURLAndCheckSubresources( |
| 294 const GURL& main_frame_url, | 319 const GURL& main_frame_url, |
| 295 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { | 320 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { |
| 296 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); | 321 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); |
| 297 std::vector<URLRequestSummary> url_request_summaries; | 322 std::vector<URLRequestSummary> url_request_summaries; |
| 298 for (const auto& kv : resources_) { | 323 for (const auto& kv : resources_) { |
| 299 if (kv.second.is_no_store || !kv.second.should_be_recorded) | 324 if (kv.second.is_observable) { |
| 300 continue; | 325 url_request_summaries.push_back( |
| 301 url_request_summaries.push_back( | 326 GetURLRequestSummaryForResource(endpoint_url, kv.second)); |
| 302 GetURLRequestSummaryForResource(endpoint_url, kv.second)); | 327 } |
| 303 } | 328 } |
| 304 | 329 |
| 305 bool match_navigation_id = | 330 bool match_navigation_id = |
| 306 disposition == WindowOpenDisposition::CURRENT_TAB; | 331 disposition == WindowOpenDisposition::CURRENT_TAB; |
| 307 | 332 |
| 308 LearningObserver observer( | 333 LearningObserver observer( |
| 309 predictor_, UpdateAndGetVisitCount(main_frame_url), | 334 predictor_, UpdateAndGetVisitCount(main_frame_url), |
| 310 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), | 335 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), |
| 311 url_request_summaries), | 336 url_request_summaries), |
| 312 match_navigation_id); | 337 match_navigation_id); |
| 313 ui_test_utils::NavigateToURLWithDisposition( | 338 ui_test_utils::NavigateToURLWithDisposition( |
| 314 browser(), main_frame_url, disposition, | 339 browser(), main_frame_url, disposition, |
| 315 ui_test_utils::BROWSER_TEST_NONE); | 340 ui_test_utils::BROWSER_TEST_NONE); |
| 316 observer.Wait(); | 341 observer.Wait(); |
| 317 for (auto& kv : resources_) { | 342 for (auto& kv : resources_) { |
| 318 if (!kv.second.is_no_store && kv.second.should_be_recorded) | 343 if (kv.second.is_observable) |
| 319 kv.second.request.was_cached = true; | 344 kv.second.request.was_cached = true; |
| 320 } | 345 } |
| 321 for (const auto& nav : observer.current_navigation_ids()) | 346 for (const auto& nav : observer.current_navigation_ids()) |
| 322 navigation_id_history_.insert(nav); | 347 navigation_id_history_.insert(nav); |
| 323 } | 348 } |
| 324 | 349 |
| 325 void PrefetchURL(const GURL& main_frame_url) { | 350 void PrefetchURL(const GURL& main_frame_url) { |
| 326 PrefetchingObserver observer(predictor_, main_frame_url); | 351 PrefetchingObserver observer(predictor_, main_frame_url); |
| 327 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL); | 352 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL); |
| 328 observer.Wait(); | 353 observer.Wait(); |
| 329 for (auto& kv : resources_) { | 354 for (auto& kv : resources_) { |
| 330 if (!kv.second.is_no_store && kv.second.should_be_recorded) | 355 if (kv.second.is_observable) |
| 331 kv.second.request.was_cached = true; | 356 kv.second.request.was_cached = true; |
| 332 } | 357 } |
| 333 } | 358 } |
| 334 | 359 |
| 335 ResourceSummary* AddResource(const GURL& resource_url, | 360 ResourceSummary* AddResource(const GURL& resource_url, |
| 336 content::ResourceType resource_type, | 361 content::ResourceType resource_type, |
| 337 net::RequestPriority priority) { | 362 net::RequestPriority priority) { |
| 338 auto pair_and_whether_inserted = | 363 auto pair_and_whether_inserted = |
| 339 resources_.insert(std::make_pair(resource_url, ResourceSummary())); | 364 resources_.insert(std::make_pair(resource_url, ResourceSummary())); |
| 340 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url | 365 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url |
| 341 << " was inserted twice"; | 366 << " was inserted twice"; |
| 342 ResourceSummary* resource = &pair_and_whether_inserted.first->second; | 367 ResourceSummary* resource = &pair_and_whether_inserted.first->second; |
| 343 resource->request.resource_url = resource_url; | 368 resource->request.resource_url = resource_url; |
| 344 resource->request.resource_type = resource_type; | 369 resource->request.resource_type = resource_type; |
| 345 resource->request.priority = priority; | 370 resource->request.priority = priority; |
| 346 resource->request.has_validators = true; | 371 resource->request.has_validators = true; |
| 347 return resource; | 372 return resource; |
| 348 } | 373 } |
| 349 | 374 |
| 350 ResourceSummary* AddExternalResource(const GURL& resource_url, | 375 ResourceSummary* AddExternalResource(const GURL& resource_url, |
| 351 content::ResourceType resource_type, | 376 content::ResourceType resource_type, |
| 352 net::RequestPriority priority) { | 377 net::RequestPriority priority) { |
| 353 auto resource = AddResource(resource_url, resource_type, priority); | 378 auto resource = AddResource(resource_url, resource_type, priority); |
| 354 resource->is_external = true; | 379 resource->is_external = true; |
| 355 return resource; | 380 return resource; |
| 356 } | 381 } |
| 357 | 382 |
| 358 void AddUnrecordedResources(const std::vector<GURL>& resource_urls) { | 383 void AddUnobservableResources(const std::vector<GURL>& resource_urls) { |
| 359 for (const GURL& resource_url : resource_urls) { | 384 for (const GURL& resource_url : resource_urls) { |
| 360 auto resource = | 385 auto resource = |
| 361 AddResource(resource_url, content::RESOURCE_TYPE_SUB_RESOURCE, | 386 AddResource(resource_url, content::RESOURCE_TYPE_SUB_RESOURCE, |
| 362 net::DEFAULT_PRIORITY); | 387 net::DEFAULT_PRIORITY); |
| 363 resource->should_be_recorded = false; | 388 resource->is_observable = false; |
| 364 } | 389 } |
| 365 } | 390 } |
| 366 | 391 |
| 367 void AddRedirectChain(const GURL& initial_url, | 392 void AddRedirectChain(const GURL& initial_url, |
| 368 const std::vector<RedirectEdge>& redirect_chain) { | 393 const std::vector<RedirectEdge>& redirect_chain) { |
| 369 ASSERT_FALSE(redirect_chain.empty()); | 394 ASSERT_FALSE(redirect_chain.empty()); |
| 370 GURL current = initial_url; | 395 GURL current = initial_url; |
| 371 for (const auto& edge : redirect_chain) { | 396 for (const auto& edge : redirect_chain) { |
| 372 auto result = redirects_.insert(std::make_pair(current, edge)); | 397 auto result = redirects_.insert(std::make_pair(current, edge)); |
| 373 EXPECT_TRUE(result.second) << current << " already has a redirect."; | 398 EXPECT_TRUE(result.second) << current << " already has a redirect."; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 400 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( | 425 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( |
| 401 net::EmbeddedTestServer::TYPE_HTTPS); | 426 net::EmbeddedTestServer::TYPE_HTTPS); |
| 402 https_server()->AddDefaultHandlers( | 427 https_server()->AddDefaultHandlers( |
| 403 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | 428 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); |
| 404 https_server()->RegisterRequestHandler( | 429 https_server()->RegisterRequestHandler( |
| 405 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, | 430 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| 406 base::Unretained(this))); | 431 base::Unretained(this))); |
| 407 https_server()->RegisterRequestHandler( | 432 https_server()->RegisterRequestHandler( |
| 408 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | 433 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| 409 base::Unretained(this))); | 434 base::Unretained(this))); |
| 435 https_server()->RegisterRequestMonitor(base::Bind( | |
| 436 &ResourcePrefetchPredictorBrowserTest::MonitorResourceRequest, | |
| 437 base::Unretained(this))); | |
| 410 ASSERT_TRUE(https_server()->Start()); | 438 ASSERT_TRUE(https_server()->Start()); |
| 411 } | 439 } |
| 412 | 440 |
| 413 // Returns the embedded test server working over HTTPS. Must be enabled by | 441 // Returns the embedded test server working over HTTPS. Must be enabled by |
| 414 // calling EnableHttpsServer() before use. | 442 // calling EnableHttpsServer() before use. |
| 415 const net::EmbeddedTestServer* https_server() const { | 443 const net::EmbeddedTestServer* https_server() const { |
| 416 return https_server_.get(); | 444 return https_server_.get(); |
| 417 } | 445 } |
| 418 | 446 |
| 419 net::EmbeddedTestServer* https_server() { return https_server_.get(); } | 447 net::EmbeddedTestServer* https_server() { return https_server_.get(); } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 446 content::WebContents* web_contents = | 474 content::WebContents* web_contents = |
| 447 browser()->tab_strip_model()->GetActiveWebContents(); | 475 browser()->tab_strip_model()->GetActiveWebContents(); |
| 448 summary.navigation_id = | 476 summary.navigation_id = |
| 449 NavigationID(web_contents, main_frame_url, base::TimeTicks::Now()); | 477 NavigationID(web_contents, main_frame_url, base::TimeTicks::Now()); |
| 450 return summary; | 478 return summary; |
| 451 } | 479 } |
| 452 | 480 |
| 453 GURL GetRedirectEndpoint(const GURL& initial_url) const { | 481 GURL GetRedirectEndpoint(const GURL& initial_url) const { |
| 454 GURL current = initial_url; | 482 GURL current = initial_url; |
| 455 while (true) { | 483 while (true) { |
| 456 auto it = redirects_.find(current); | 484 RedirectMap::const_iterator it = redirects_.find(current); |
| 457 if (it == redirects_.end()) | 485 if (it == redirects_.end()) |
| 458 break; | 486 break; |
| 459 current = it->second.url; | 487 current = it->second.url; |
| 460 } | 488 } |
| 461 return current; | 489 return current; |
| 462 } | 490 } |
| 463 | 491 |
| 492 void MonitorResourceRequest( | |
| 493 const net::test_server::HttpRequest& request) const { | |
| 494 ResourceMap::const_iterator resource_it = resources_.find(request.GetURL()); | |
| 495 if (resource_it == resources_.end()) | |
| 496 return; | |
| 497 | |
| 498 const ResourceSummary& summary = resource_it->second; | |
| 499 EXPECT_FALSE(summary.is_prohibited) << request.GetURL() << "\n" | |
| 500 << request.all_headers; | |
| 501 } | |
| 502 | |
| 503 // The custom handler for resource requests from the browser to an | |
| 504 // EmbeddedTestServer. Runs on the EmbeddedTestServer IO thread. | |
| 505 // Finds the data to serve requests in |resources_| map keyed by a request | |
| 506 // URL. | |
| 507 // Uses also the following headers from the |request|: | |
| 508 // - "Host" to retrieve the host that actually was issued by the browser. | |
| 509 // - "If-None-Match" to determine if the resource is still valid. If the | |
| 510 // ETag values match, the handler responds with a HTTP 304 status. | |
|
pasko
2016/12/26 17:56:49
nit: please add two spaces before "ETag"
alexilin
2016/12/26 18:27:08
Done.
| |
| 464 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( | 511 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( |
| 465 const net::test_server::HttpRequest& request) const { | 512 const net::test_server::HttpRequest& request) const { |
| 466 GURL resource_url = request.GetURL(); | 513 GURL resource_url = request.GetURL(); |
| 467 // Retrieve the host that was used in the request because | 514 // Retrieve the host that was used in the request because |
| 468 // resource_url contains a resolved host (e.g. 127.0.0.1). | 515 // resource_url contains a resolved host (e.g. 127.0.0.1). |
| 469 if (request.headers.find("Host") != request.headers.end()) { | 516 if (request.headers.find("Host") != request.headers.end()) { |
| 470 auto host_port_pair = | 517 auto host_port_pair = |
| 471 net::HostPortPair::FromString(request.headers.at("Host")); | 518 net::HostPortPair::FromString(request.headers.at("Host")); |
| 472 GURL::Replacements replace_host; | 519 GURL::Replacements replace_host; |
| 473 replace_host.SetHostStr(host_port_pair.host()); | 520 replace_host.SetHostStr(host_port_pair.host()); |
| 474 resource_url = resource_url.ReplaceComponents(replace_host); | 521 resource_url = resource_url.ReplaceComponents(replace_host); |
| 475 } else { | 522 } else { |
| 476 ADD_FAILURE() << "Host header was not found in a HttpRequest to url: " | 523 ADD_FAILURE() << "Host header was not found in a HttpRequest to url: " |
| 477 << resource_url.spec(); | 524 << resource_url.spec(); |
| 478 } | 525 } |
| 479 | 526 |
| 480 auto resource_it = resources_.find(resource_url); | 527 ResourceMap::const_iterator resource_it = resources_.find(resource_url); |
| 481 if (resource_it == resources_.end()) | 528 if (resource_it == resources_.end()) |
| 482 return nullptr; | 529 return nullptr; |
| 483 | 530 |
| 484 const ResourceSummary& summary = resource_it->second; | 531 const ResourceSummary& summary = resource_it->second; |
| 485 if (summary.is_external) | 532 if (summary.is_external) |
| 486 return nullptr; | 533 return nullptr; |
| 487 | 534 |
| 488 auto http_response = | 535 auto http_response = |
| 489 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 536 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 490 http_response->set_code(net::HTTP_OK); | 537 |
| 538 if (request.headers.find("If-None-Match") != request.headers.end() && | |
| 539 request.headers.at("If-None-Match") == | |
| 540 CreateVersionnedETag(summary.version, request.relative_url)) { | |
| 541 http_response->set_code(net::HTTP_NOT_MODIFIED); | |
| 542 } else { | |
| 543 http_response->set_code(net::HTTP_OK); | |
| 544 } | |
| 545 | |
| 491 if (!summary.request.mime_type.empty()) | 546 if (!summary.request.mime_type.empty()) |
| 492 http_response->set_content_type(summary.request.mime_type); | 547 http_response->set_content_type(summary.request.mime_type); |
| 493 if (!summary.content.empty()) | 548 if (!summary.content.empty()) |
| 494 http_response->set_content(summary.content); | 549 http_response->set_content(summary.content); |
| 495 if (summary.is_no_store) | 550 if (summary.is_no_store) |
| 496 http_response->AddCustomHeader("Cache-Control", "no-store"); | 551 http_response->AddCustomHeader("Cache-Control", "no-store"); |
| 497 if (summary.request.has_validators) { | 552 if (summary.request.has_validators) { |
| 498 http_response->AddCustomHeader( | 553 http_response->AddCustomHeader( |
| 499 "ETag", base::StringPrintf("'%zu%s'", summary.version, | 554 "ETag", CreateVersionnedETag(summary.version, request.relative_url)); |
| 500 request.relative_url.c_str())); | |
| 501 } | 555 } |
| 502 if (summary.request.always_revalidate) | 556 if (summary.request.always_revalidate) |
| 503 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 557 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 504 else | 558 else |
| 505 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 559 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 506 return std::move(http_response); | 560 return std::move(http_response); |
| 507 } | 561 } |
| 508 | 562 |
| 563 // The custom handler for redirect requests from the browser to an | |
| 564 // EmbeddedTestServer. Running on the EmbeddedTestServer IO thread. | |
| 565 // Finds the data to serve requests in |redirects_| map keyed by a request | |
| 566 // URL. | |
| 509 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( | 567 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 510 const net::test_server::HttpRequest& request) const { | 568 const net::test_server::HttpRequest& request) const { |
| 511 auto redirect_it = redirects_.find(request.GetURL()); | 569 RedirectMap::const_iterator redirect_it = redirects_.find(request.GetURL()); |
| 512 if (redirect_it == redirects_.end()) | 570 if (redirect_it == redirects_.end()) |
| 513 return nullptr; | 571 return nullptr; |
| 514 | 572 |
| 515 auto http_response = | 573 auto http_response = |
| 516 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 574 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 517 http_response->set_code(redirect_it->second.code); | 575 http_response->set_code(redirect_it->second.code); |
| 518 http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); | 576 http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); |
| 519 return std::move(http_response); | 577 return std::move(http_response); |
| 520 } | 578 } |
| 521 | 579 |
| 522 size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { | 580 size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { |
| 523 return ++visit_count_[main_frame_url]; | 581 return ++visit_count_[main_frame_url]; |
| 524 } | 582 } |
| 525 | 583 |
| 584 typedef std::map<GURL, ResourceSummary> ResourceMap; | |
|
pasko
2016/12/26 17:56:49
Use type aliases instead of typedef:
https://group
alexilin
2016/12/26 18:27:08
Thanks for pointing me at this thread. We have a m
pasko
2016/12/26 18:50:56
That's basically where I found this thread :)
| |
| 585 typedef std::map<GURL, RedirectEdge> RedirectMap; | |
| 586 | |
| 526 ResourcePrefetchPredictor* predictor_; | 587 ResourcePrefetchPredictor* predictor_; |
| 527 std::unique_ptr<net::EmbeddedTestServer> https_server_; | 588 std::unique_ptr<net::EmbeddedTestServer> https_server_; |
| 528 std::map<GURL, ResourceSummary> resources_; | 589 ResourceMap resources_; |
| 529 std::map<GURL, RedirectEdge> redirects_; | 590 RedirectMap redirects_; |
| 530 std::map<GURL, size_t> visit_count_; | 591 std::map<GURL, size_t> visit_count_; |
| 531 std::set<NavigationID> navigation_id_history_; | 592 std::set<NavigationID> navigation_id_history_; |
| 532 }; | 593 }; |
| 533 | 594 |
| 534 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Simple) { | 595 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, Simple) { |
| 535 // These resources have default priorities that correspond to | 596 // These resources have default priorities that correspond to |
| 536 // blink::typeToPriority function. | 597 // blink::typeToPriority function. |
| 537 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 598 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 538 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 599 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 539 net::HIGHEST); | 600 net::HIGHEST); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | 677 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 617 JavascriptInnerHtml) { | 678 JavascriptInnerHtml) { |
| 618 auto externalScript = AddExternalResource( | 679 auto externalScript = AddExternalResource( |
| 619 GetURL(kScriptInnerHtmlPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 680 GetURL(kScriptInnerHtmlPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 620 externalScript->request.mime_type = kJavascriptMime; | 681 externalScript->request.mime_type = kJavascriptMime; |
| 621 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 682 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 622 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 683 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 623 net::HIGHEST); | 684 net::HIGHEST); |
| 624 // https://www.w3.org/TR/2014/REC-html5-20141028/scripting-1.html#the-script-e lement | 685 // https://www.w3.org/TR/2014/REC-html5-20141028/scripting-1.html#the-script-e lement |
| 625 // Script elements don't execute when inserted using innerHTML attribute. | 686 // Script elements don't execute when inserted using innerHTML attribute. |
| 626 AddUnrecordedResources({GetURL(kScriptPath)}); | 687 AddUnobservableResources({GetURL(kScriptPath)}); |
| 627 TestLearningAndPrefetching(GetURL(kHtmlInnerHtmlPath)); | 688 TestLearningAndPrefetching(GetURL(kHtmlInnerHtmlPath)); |
| 628 } | 689 } |
| 629 | 690 |
| 630 // Requests originated by XMLHttpRequest have content::RESOURCE_TYPE_XHR. | 691 // Requests originated by XMLHttpRequest have content::RESOURCE_TYPE_XHR. |
| 631 // Actual resource type is inferred from the mime-type. | 692 // Actual resource type is inferred from the mime-type. |
| 632 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, JavascriptXHR) { | 693 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, JavascriptXHR) { |
| 633 auto externalScript = AddExternalResource( | 694 auto externalScript = AddExternalResource( |
| 634 GetURL(kScriptXHRPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 695 GetURL(kScriptXHRPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 635 externalScript->request.mime_type = kJavascriptMime; | 696 externalScript->request.mime_type = kJavascriptMime; |
| 636 auto image = AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, | 697 auto image = AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, |
| 637 net::HIGHEST); | 698 net::HIGHEST); |
| 638 image->request.mime_type = kImageMime; | 699 image->request.mime_type = kImageMime; |
| 639 auto style = AddResource(GetURL(kStylePath), | 700 auto style = AddResource(GetURL(kStylePath), |
| 640 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | 701 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); |
| 641 style->request.mime_type = kStyleMime; | 702 style->request.mime_type = kStyleMime; |
| 642 auto script = AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, | 703 auto script = AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, |
| 643 net::HIGHEST); | 704 net::HIGHEST); |
| 644 script->request.mime_type = kJavascriptMime; | 705 script->request.mime_type = kJavascriptMime; |
| 645 TestLearningAndPrefetching(GetURL(kHtmlXHRPath)); | 706 TestLearningAndPrefetching(GetURL(kHtmlXHRPath)); |
| 646 } | 707 } |
| 647 | 708 |
| 648 // ResourcePrefetchPredictor ignores all resources requested from subframes. | 709 // ResourcePrefetchPredictor ignores all resources requested from subframes. |
| 649 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | 710 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 650 IframeShouldBeIgnored) { | 711 IframeShouldBeIgnored) { |
| 651 // Included from html_iframe.html. | 712 // Included from html_iframe.html. |
| 652 AddResource(GetURL(kImagePath2), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 713 AddResource(GetURL(kImagePath2), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 653 AddResource(GetURL(kStylePath2), content::RESOURCE_TYPE_STYLESHEET, | 714 AddResource(GetURL(kStylePath2), content::RESOURCE_TYPE_STYLESHEET, |
| 654 net::HIGHEST); | 715 net::HIGHEST); |
| 655 AddResource(GetURL(kScriptPath2), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 716 AddResource(GetURL(kScriptPath2), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 656 // Included from <iframe src="html_subresources.html"> and not recored. | 717 // Included from <iframe src="html_subresources.html"> and shouldn't be |
| 657 AddUnrecordedResources({GetURL(kImagePath), GetURL(kStylePath), | 718 // observed. |
| 658 GetURL(kScriptPath), GetURL(kFontPath)}); | 719 AddUnobservableResources({GetURL(kImagePath), GetURL(kStylePath), |
| 720 GetURL(kScriptPath), GetURL(kFontPath)}); | |
| 659 TestLearningAndPrefetching(GetURL(kHtmlIframePath)); | 721 TestLearningAndPrefetching(GetURL(kHtmlIframePath)); |
| 660 } | 722 } |
| 661 | 723 |
| 662 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | 724 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 663 CrossSiteNavigation) { | 725 CrossSiteNavigation) { |
| 664 AddResource(embedded_test_server()->GetURL(kFooHost, kImagePath), | 726 AddResource(embedded_test_server()->GetURL(kFooHost, kImagePath), |
| 665 content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 727 content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 666 AddResource(embedded_test_server()->GetURL(kFooHost, kStylePath), | 728 AddResource(embedded_test_server()->GetURL(kFooHost, kStylePath), |
| 667 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | 729 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); |
| 668 AddResource(embedded_test_server()->GetURL(kFooHost, kScriptPath), | 730 AddResource(embedded_test_server()->GetURL(kFooHost, kScriptPath), |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 711 ClearCache(); | 773 ClearCache(); |
| 712 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath), | 774 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath), |
| 713 WindowOpenDisposition::NEW_WINDOW); | 775 WindowOpenDisposition::NEW_WINDOW); |
| 714 EXPECT_EQ(navigation_ids_history_size(), 3U); | 776 EXPECT_EQ(navigation_ids_history_size(), 3U); |
| 715 ClearCache(); | 777 ClearCache(); |
| 716 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath), | 778 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath), |
| 717 WindowOpenDisposition::NEW_POPUP); | 779 WindowOpenDisposition::NEW_POPUP); |
| 718 EXPECT_EQ(navigation_ids_history_size(), 4U); | 780 EXPECT_EQ(navigation_ids_history_size(), 4U); |
| 719 } | 781 } |
| 720 | 782 |
| 783 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, AlwaysRevalidate) { | |
| 784 std::vector<ResourceSummary*> resources = { | |
| 785 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, | |
| 786 net::LOWEST), | |
| 787 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 788 net::HIGHEST), | |
| 789 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, | |
| 790 net::MEDIUM), | |
| 791 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 792 net::HIGHEST), | |
| 793 }; | |
| 794 for (auto& resource : resources) | |
| 795 resource->request.always_revalidate = true; | |
| 796 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); | |
| 797 } | |
| 798 | |
| 721 } // namespace predictors | 799 } // namespace predictors |
| OLD | NEW |