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 "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "chrome/browser/browsing_data/browsing_data_helper.h" | 6 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
| 7 #include "chrome/browser/browsing_data/browsing_data_remover.h" | 7 #include "chrome/browser/browsing_data/browsing_data_remover.h" |
| 8 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h" | 8 #include "chrome/browser/browsing_data/browsing_data_remover_factory.h" |
| 9 #include "chrome/browser/predictors/resource_prefetch_predictor.h" | 9 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 10 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" | 10 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; | 50 const char kHtmlAppendChildPath[] = "/predictors/append_child.html"; |
| 51 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; | 51 const char kScriptAppendChildPath[] = "/predictors/append_child.js"; |
| 52 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; | 52 const char kHtmlInnerHtmlPath[] = "/predictors/inner_html.html"; |
| 53 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; | 53 const char kScriptInnerHtmlPath[] = "/predictors/inner_html.js"; |
| 54 const char kHtmlXHRPath[] = "/predictors/xhr.html"; | 54 const char kHtmlXHRPath[] = "/predictors/xhr.html"; |
| 55 const char kScriptXHRPath[] = "/predictors/xhr.js"; | 55 const char kScriptXHRPath[] = "/predictors/xhr.js"; |
| 56 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; | 56 const char kHtmlIframePath[] = "/predictors/html_iframe.html"; |
| 57 | 57 |
| 58 struct ResourceSummary { | 58 struct ResourceSummary { |
| 59 ResourceSummary() | 59 ResourceSummary() |
| 60 : is_no_store(false), | 60 : version(0), |
| 61 version(0), | 61 is_no_store(false), |
| 62 is_external(false), | 62 is_external(false), |
| 63 should_be_recorded(true) {} | 63 is_observable(true), |
| 64 is_request_prohibited(false) {} | |
| 64 | 65 |
| 65 ResourcePrefetchPredictor::URLRequestSummary request; | 66 ResourcePrefetchPredictor::URLRequestSummary request; |
| 66 std::string content; | 67 std::string content; |
| 68 // Allows to update HTTP ETag. | |
| 69 size_t version; | |
| 70 // True iff "Cache-control: no-store" header is present. | |
| 67 bool is_no_store; | 71 bool is_no_store; |
| 68 size_t version; | 72 // True iff a request for this resource must be ignored by the custom handler. |
| 69 bool is_external; | 73 bool is_external; |
| 70 bool should_be_recorded; | 74 // True iff the LearningObserver must observe this resource. |
| 75 bool is_observable; | |
| 76 // True iff a test must fail on request to this resource. | |
|
pasko
2016/12/26 14:12:16
nit: since we are in ResourceSummary, we could rem
pasko
2016/12/26 14:12:17
I'd rephrase slightly (because a test can fail for
alexilin
2016/12/26 17:33:22
Done.
| |
| 77 bool is_request_prohibited; | |
| 71 }; | 78 }; |
| 72 | 79 |
| 73 struct RedirectEdge { | 80 struct RedirectEdge { |
| 74 // This response code should be returned by previous url in the chain. | 81 // This response code should be returned by previous url in the chain. |
| 75 net::HttpStatusCode code; | 82 net::HttpStatusCode code; |
| 76 GURL url; | 83 GURL url; |
| 77 }; | 84 }; |
| 78 | 85 |
| 79 // Helper class to track and allow waiting for ResourcePrefetchPredictor | 86 // Helper class to track and allow waiting for ResourcePrefetchPredictor |
| 80 // initialization. WARNING: OnPredictorInitialized event will not be fired if | 87 // initialization. WARNING: OnPredictorInitialized event will not be fired if |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 | 168 |
| 162 for (auto& subresource : actual_subresources) | 169 for (auto& subresource : actual_subresources) |
| 163 ModifySubresourceForComparison(&subresource, match_navigation_id); | 170 ModifySubresourceForComparison(&subresource, match_navigation_id); |
| 164 for (auto& subresource : expected_subresources) | 171 for (auto& subresource : expected_subresources) |
| 165 ModifySubresourceForComparison(&subresource, match_navigation_id); | 172 ModifySubresourceForComparison(&subresource, match_navigation_id); |
| 166 | 173 |
| 167 EXPECT_THAT(actual_subresources, | 174 EXPECT_THAT(actual_subresources, |
| 168 testing::UnorderedElementsAreArray(expected_subresources)); | 175 testing::UnorderedElementsAreArray(expected_subresources)); |
| 169 } | 176 } |
| 170 | 177 |
| 178 std::string GetVersionnedETag(size_t version, const std::string& path) { | |
|
pasko
2016/12/26 14:12:17
s/GetVersionned/MakeVersioned/
(we are not lookin
alexilin
2016/12/26 17:33:22
I'd prefer to name it CreateVersionnedETag since i
pasko
2016/12/26 17:56:49
sgtm on the "Create" part, but s/Versionned/Versio
alexilin
2016/12/26 18:27:07
Done.
| |
| 179 return base::StringPrintf("'%zu%s'", version, path.c_str()); | |
| 180 } | |
| 181 | |
| 171 } // namespace | 182 } // namespace |
| 172 | 183 |
| 173 // Helper class to track and allow waiting for a single OnNavigationLearned | 184 // Helper class to track and allow waiting for a single OnNavigationLearned |
| 174 // event. The information provided by this event is also used to verify that | 185 // event. The information provided by this event is also used to verify that |
| 175 // ResourcePrefetchPredictor works as expected. | 186 // ResourcePrefetchPredictor works as expected. |
| 176 class LearningObserver : public TestObserver { | 187 class LearningObserver : public TestObserver { |
| 177 public: | 188 public: |
| 178 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; | 189 using PageRequestSummary = ResourcePrefetchPredictor::PageRequestSummary; |
| 179 | 190 |
| 180 LearningObserver(ResourcePrefetchPredictor* predictor, | 191 LearningObserver(ResourcePrefetchPredictor* predictor, |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 switches::kSpeculativeResourcePrefetchingEnabledExternal); | 257 switches::kSpeculativeResourcePrefetchingEnabledExternal); |
| 247 } | 258 } |
| 248 | 259 |
| 249 void SetUpOnMainThread() override { | 260 void SetUpOnMainThread() override { |
| 250 embedded_test_server()->RegisterRequestHandler( | 261 embedded_test_server()->RegisterRequestHandler( |
| 251 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, | 262 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| 252 base::Unretained(this))); | 263 base::Unretained(this))); |
| 253 embedded_test_server()->RegisterRequestHandler( | 264 embedded_test_server()->RegisterRequestHandler( |
| 254 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | 265 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| 255 base::Unretained(this))); | 266 base::Unretained(this))); |
| 267 embedded_test_server()->RegisterRequestMonitor(base::Bind( | |
| 268 &ResourcePrefetchPredictorBrowserTest::MonitorResourceRequest, | |
| 269 base::Unretained(this))); | |
| 256 ASSERT_TRUE(embedded_test_server()->Start()); | 270 ASSERT_TRUE(embedded_test_server()->Start()); |
| 257 predictor_ = | 271 predictor_ = |
| 258 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); | 272 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); |
| 259 ASSERT_TRUE(predictor_); | 273 ASSERT_TRUE(predictor_); |
| 260 EnsurePredictorInitialized(); | 274 EnsurePredictorInitialized(); |
| 261 } | 275 } |
| 262 | 276 |
| 263 void TestLearningAndPrefetching(const GURL& main_frame_url) { | 277 void TestLearningAndPrefetching(const GURL& main_frame_url) { |
| 264 // Navigate to |main_frame_url| and check all the expectations. | 278 // Navigate to |main_frame_url| and check all the expectations. |
| 265 NavigateToURLAndCheckSubresources(main_frame_url); | 279 NavigateToURLAndCheckSubresources(main_frame_url); |
| 266 ClearCache(); | 280 ClearCache(); |
| 267 // It is needed to have at least two resource hits to trigger prefetch. | 281 // It is needed to have at least two resource hits to trigger prefetch. |
| 268 NavigateToURLAndCheckSubresources(main_frame_url); | 282 NavigateToURLAndCheckSubresources(main_frame_url); |
| 269 ClearCache(); | 283 ClearCache(); |
| 270 // Prefetch all needed resources and change expectations so that all | 284 // Prefetch all needed resources and change expectations so that all |
| 271 // cacheable resources should be served from cache next navigation. | 285 // cacheable resources should be served from cache next navigation. |
| 272 PrefetchURL(main_frame_url); | 286 PrefetchURL(main_frame_url); |
| 287 // To be sure that the browser send no requests to the server after | |
| 288 // prefetching. | |
| 289 for (auto& kv : resources_) { | |
| 290 if (kv.second.is_observable) | |
| 291 kv.second.is_request_prohibited = true; | |
| 292 } | |
| 273 NavigateToURLAndCheckSubresources(main_frame_url); | 293 NavigateToURLAndCheckSubresources(main_frame_url); |
| 294 for (auto& kv : resources_) { | |
| 295 if (kv.second.is_observable) | |
| 296 kv.second.is_request_prohibited = false; | |
|
pasko
2016/12/26 14:12:17
why should this be returned back to false? Are we
alexilin
2016/12/26 17:33:22
Potentially yes. For example, we already have Cros
pasko
2016/12/26 17:56:49
OK, makes sense, agreed.
| |
| 297 } | |
| 274 } | 298 } |
| 275 | 299 |
| 276 void NavigateToURLAndCheckSubresources( | 300 void NavigateToURLAndCheckSubresources( |
| 277 const GURL& main_frame_url, | 301 const GURL& main_frame_url, |
| 278 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { | 302 WindowOpenDisposition disposition = WindowOpenDisposition::CURRENT_TAB) { |
| 279 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); | 303 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); |
| 280 std::vector<URLRequestSummary> url_request_summaries; | 304 std::vector<URLRequestSummary> url_request_summaries; |
| 281 for (const auto& kv : resources_) { | 305 for (const auto& kv : resources_) { |
| 282 if (kv.second.is_no_store || !kv.second.should_be_recorded) | 306 if (kv.second.is_observable) { |
| 283 continue; | 307 url_request_summaries.push_back( |
| 284 url_request_summaries.push_back( | 308 GetURLRequestSummaryForResource(endpoint_url, kv.second)); |
| 285 GetURLRequestSummaryForResource(endpoint_url, kv.second)); | 309 } |
| 286 } | 310 } |
| 311 | |
| 312 bool match_navigation_id = | |
|
pasko
2016/12/26 14:12:17
this part is already committed in crrev.com/62729f
alexilin
2016/12/26 17:33:23
Done.
| |
| 313 disposition == WindowOpenDisposition::CURRENT_TAB; | |
| 314 | |
| 287 LearningObserver observer( | 315 LearningObserver observer( |
| 288 predictor_, UpdateAndGetVisitCount(main_frame_url), | 316 predictor_, UpdateAndGetVisitCount(main_frame_url), |
| 289 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), | 317 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), |
| 290 url_request_summaries), | 318 url_request_summaries), |
| 291 true); // Matching navigation id by default | 319 match_navigation_id); |
| 292 ui_test_utils::NavigateToURLWithDisposition( | 320 ui_test_utils::NavigateToURLWithDisposition( |
| 293 browser(), main_frame_url, disposition, | 321 browser(), main_frame_url, disposition, |
| 294 ui_test_utils::BROWSER_TEST_NONE); | 322 ui_test_utils::BROWSER_TEST_NONE); |
| 295 observer.Wait(); | 323 observer.Wait(); |
| 296 for (auto& kv : resources_) { | 324 for (auto& kv : resources_) { |
| 297 if (!kv.second.is_no_store && kv.second.should_be_recorded) | 325 if (kv.second.is_observable) |
| 298 kv.second.request.was_cached = true; | 326 kv.second.request.was_cached = true; |
| 299 } | 327 } |
| 300 } | 328 } |
| 301 | 329 |
| 302 void PrefetchURL(const GURL& main_frame_url) { | 330 void PrefetchURL(const GURL& main_frame_url) { |
| 303 PrefetchingObserver observer(predictor_, main_frame_url); | 331 PrefetchingObserver observer(predictor_, main_frame_url); |
| 304 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL); | 332 predictor_->StartPrefetching(main_frame_url, PrefetchOrigin::EXTERNAL); |
| 305 observer.Wait(); | 333 observer.Wait(); |
| 306 for (auto& kv : resources_) { | 334 for (auto& kv : resources_) { |
| 307 if (!kv.second.is_no_store && kv.second.should_be_recorded) | 335 if (kv.second.is_observable) |
| 308 kv.second.request.was_cached = true; | 336 kv.second.request.was_cached = true; |
| 309 } | 337 } |
| 310 } | 338 } |
| 311 | 339 |
| 312 ResourceSummary* AddResource(const GURL& resource_url, | 340 ResourceSummary* AddResource(const GURL& resource_url, |
| 313 content::ResourceType resource_type, | 341 content::ResourceType resource_type, |
| 314 net::RequestPriority priority) { | 342 net::RequestPriority priority) { |
| 315 auto pair_and_whether_inserted = | 343 auto pair_and_whether_inserted = |
| 316 resources_.insert(std::make_pair(resource_url, ResourceSummary())); | 344 resources_.insert(std::make_pair(resource_url, ResourceSummary())); |
| 317 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url | 345 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url |
| 318 << " was inserted twice"; | 346 << " was inserted twice"; |
| 319 ResourceSummary* resource = &pair_and_whether_inserted.first->second; | 347 ResourceSummary* resource = &pair_and_whether_inserted.first->second; |
| 320 resource->request.resource_url = resource_url; | 348 resource->request.resource_url = resource_url; |
| 321 resource->request.resource_type = resource_type; | 349 resource->request.resource_type = resource_type; |
| 322 resource->request.priority = priority; | 350 resource->request.priority = priority; |
| 323 resource->request.has_validators = true; | 351 resource->request.has_validators = true; |
| 324 return resource; | 352 return resource; |
| 325 } | 353 } |
| 326 | 354 |
| 327 ResourceSummary* AddExternalResource(const GURL& resource_url, | 355 ResourceSummary* AddExternalResource(const GURL& resource_url, |
| 328 content::ResourceType resource_type, | 356 content::ResourceType resource_type, |
| 329 net::RequestPriority priority) { | 357 net::RequestPriority priority) { |
| 330 auto resource = AddResource(resource_url, resource_type, priority); | 358 auto resource = AddResource(resource_url, resource_type, priority); |
| 331 resource->is_external = true; | 359 resource->is_external = true; |
| 332 return resource; | 360 return resource; |
| 333 } | 361 } |
| 334 | 362 |
| 335 void AddUnrecordedResources(const std::vector<GURL>& resource_urls) { | 363 void AddUnobservableResources(const std::vector<GURL>& resource_urls) { |
| 336 for (const GURL& resource_url : resource_urls) { | 364 for (const GURL& resource_url : resource_urls) { |
| 337 auto resource = | 365 auto resource = |
| 338 AddResource(resource_url, content::RESOURCE_TYPE_SUB_RESOURCE, | 366 AddResource(resource_url, content::RESOURCE_TYPE_SUB_RESOURCE, |
| 339 net::DEFAULT_PRIORITY); | 367 net::DEFAULT_PRIORITY); |
| 340 resource->should_be_recorded = false; | 368 resource->is_observable = false; |
| 341 } | 369 } |
| 342 } | 370 } |
| 343 | 371 |
| 344 void AddRedirectChain(const GURL& initial_url, | 372 void AddRedirectChain(const GURL& initial_url, |
| 345 const std::vector<RedirectEdge>& redirect_chain) { | 373 const std::vector<RedirectEdge>& redirect_chain) { |
| 346 ASSERT_FALSE(redirect_chain.empty()); | 374 ASSERT_FALSE(redirect_chain.empty()); |
| 347 GURL current = initial_url; | 375 GURL current = initial_url; |
| 348 for (const auto& edge : redirect_chain) { | 376 for (const auto& edge : redirect_chain) { |
| 349 auto result = redirects_.insert(std::make_pair(current, edge)); | 377 auto result = redirects_.insert(std::make_pair(current, edge)); |
| 350 EXPECT_TRUE(result.second) << current << " already has a redirect."; | 378 EXPECT_TRUE(result.second) << current << " already has a redirect."; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 375 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( | 403 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( |
| 376 net::EmbeddedTestServer::TYPE_HTTPS); | 404 net::EmbeddedTestServer::TYPE_HTTPS); |
| 377 https_server()->AddDefaultHandlers( | 405 https_server()->AddDefaultHandlers( |
| 378 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | 406 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); |
| 379 https_server()->RegisterRequestHandler( | 407 https_server()->RegisterRequestHandler( |
| 380 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, | 408 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| 381 base::Unretained(this))); | 409 base::Unretained(this))); |
| 382 https_server()->RegisterRequestHandler( | 410 https_server()->RegisterRequestHandler( |
| 383 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, | 411 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| 384 base::Unretained(this))); | 412 base::Unretained(this))); |
| 413 https_server()->RegisterRequestMonitor(base::Bind( | |
| 414 &ResourcePrefetchPredictorBrowserTest::MonitorResourceRequest, | |
| 415 base::Unretained(this))); | |
| 385 ASSERT_TRUE(https_server()->Start()); | 416 ASSERT_TRUE(https_server()->Start()); |
| 386 } | 417 } |
| 387 | 418 |
| 388 // Returns the embedded test server working over HTTPS. Must be enabled by | 419 // Returns the embedded test server working over HTTPS. Must be enabled by |
| 389 // calling EnableHttpsServer() before use. | 420 // calling EnableHttpsServer() before use. |
| 390 const net::EmbeddedTestServer* https_server() const { | 421 const net::EmbeddedTestServer* https_server() const { |
| 391 return https_server_.get(); | 422 return https_server_.get(); |
| 392 } | 423 } |
| 393 | 424 |
| 394 net::EmbeddedTestServer* https_server() { return https_server_.get(); } | 425 net::EmbeddedTestServer* https_server() { return https_server_.get(); } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 GURL current = initial_url; | 458 GURL current = initial_url; |
| 428 while (true) { | 459 while (true) { |
| 429 auto it = redirects_.find(current); | 460 auto it = redirects_.find(current); |
| 430 if (it == redirects_.end()) | 461 if (it == redirects_.end()) |
| 431 break; | 462 break; |
| 432 current = it->second.url; | 463 current = it->second.url; |
| 433 } | 464 } |
| 434 return current; | 465 return current; |
| 435 } | 466 } |
| 436 | 467 |
| 468 void MonitorResourceRequest( | |
| 469 const net::test_server::HttpRequest& request) const { | |
| 470 auto resource_it = resources_.find(request.GetURL()); | |
|
pasko
2016/12/26 14:12:17
since the type for |resources_| is declared elsewh
alexilin
2016/12/26 17:33:23
It is debatable whether "std::map<X, Y>::const_ite
pasko
2016/12/26 17:56:49
Arguably finding the definition of ResourceMap is
alexilin
2016/12/26 18:27:08
GurlToResourceSummaryMap1234567
std::map<GURL, Res
| |
| 471 if (resource_it == resources_.end()) | |
| 472 return; | |
| 473 | |
| 474 const ResourceSummary& summary = resource_it->second; | |
| 475 EXPECT_FALSE(summary.is_request_prohibited) << request.GetURL().spec() | |
| 476 << "\n" | |
| 477 << request.all_headers; | |
| 478 } | |
| 479 | |
| 437 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( | 480 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( |
|
pasko
2016/12/26 14:12:17
I think it is time for a brief comment of how requ
alexilin
2016/12/26 17:33:23
Done.
+ added remark about the execution thread.
I
pasko
2016/12/26 17:56:49
Thanks!
| |
| 438 const net::test_server::HttpRequest& request) const { | 481 const net::test_server::HttpRequest& request) const { |
| 439 auto resource_it = resources_.find(request.GetURL()); | 482 auto resource_it = resources_.find(request.GetURL()); |
| 440 if (resource_it == resources_.end()) | 483 if (resource_it == resources_.end()) |
| 441 return nullptr; | 484 return nullptr; |
| 442 | 485 |
| 443 const ResourceSummary& summary = resource_it->second; | 486 const ResourceSummary& summary = resource_it->second; |
| 444 if (summary.is_external) | 487 if (summary.is_external) |
| 445 return nullptr; | 488 return nullptr; |
| 446 | 489 |
| 447 auto http_response = | 490 auto http_response = |
| 448 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 491 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 449 http_response->set_code(net::HTTP_OK); | 492 |
| 493 if (request.headers.find("If-None-Match") != request.headers.end() && | |
| 494 request.headers.at("If-None-Match") == | |
| 495 GetVersionnedETag(summary.version, request.relative_url)) { | |
| 496 http_response->set_code(net::HTTP_NOT_MODIFIED); | |
| 497 } else { | |
| 498 http_response->set_code(net::HTTP_OK); | |
| 499 } | |
| 500 | |
| 450 if (!summary.request.mime_type.empty()) | 501 if (!summary.request.mime_type.empty()) |
| 451 http_response->set_content_type(summary.request.mime_type); | 502 http_response->set_content_type(summary.request.mime_type); |
| 452 if (!summary.content.empty()) | 503 if (!summary.content.empty()) |
| 453 http_response->set_content(summary.content); | 504 http_response->set_content(summary.content); |
| 454 if (summary.is_no_store) | 505 if (summary.is_no_store) |
| 455 http_response->AddCustomHeader("Cache-Control", "no-store"); | 506 http_response->AddCustomHeader("Cache-Control", "no-store"); |
| 456 if (summary.request.has_validators) { | 507 if (summary.request.has_validators) { |
| 457 http_response->AddCustomHeader( | 508 http_response->AddCustomHeader( |
| 458 "ETag", base::StringPrintf("'%zu%s'", summary.version, | 509 "ETag", GetVersionnedETag(summary.version, request.relative_url)); |
| 459 request.relative_url.c_str())); | |
| 460 } | 510 } |
| 461 if (summary.request.always_revalidate) | 511 if (summary.request.always_revalidate) |
| 462 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 512 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 463 else | 513 else |
| 464 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 514 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 465 return std::move(http_response); | 515 return std::move(http_response); |
| 466 } | 516 } |
| 467 | 517 |
| 468 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( | 518 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 469 const net::test_server::HttpRequest& request) const { | 519 const net::test_server::HttpRequest& request) const { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 576 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | 626 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 577 JavascriptInnerHtml) { | 627 JavascriptInnerHtml) { |
| 578 auto externalScript = AddExternalResource( | 628 auto externalScript = AddExternalResource( |
| 579 GetURL(kScriptInnerHtmlPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 629 GetURL(kScriptInnerHtmlPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 580 externalScript->request.mime_type = kJavascriptMime; | 630 externalScript->request.mime_type = kJavascriptMime; |
| 581 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 631 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 582 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | 632 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 583 net::HIGHEST); | 633 net::HIGHEST); |
| 584 // https://www.w3.org/TR/2014/REC-html5-20141028/scripting-1.html#the-script-e lement | 634 // https://www.w3.org/TR/2014/REC-html5-20141028/scripting-1.html#the-script-e lement |
| 585 // Script elements don't execute when inserted using innerHTML attribute. | 635 // Script elements don't execute when inserted using innerHTML attribute. |
| 586 AddUnrecordedResources({GetURL(kScriptPath)}); | 636 AddUnobservableResources({GetURL(kScriptPath)}); |
| 587 TestLearningAndPrefetching(GetURL(kHtmlInnerHtmlPath)); | 637 TestLearningAndPrefetching(GetURL(kHtmlInnerHtmlPath)); |
| 588 } | 638 } |
| 589 | 639 |
| 590 // Requests originated by XMLHttpRequest have content::RESOURCE_TYPE_XHR. | 640 // Requests originated by XMLHttpRequest have content::RESOURCE_TYPE_XHR. |
| 591 // Actual resource type is inferred from the mime-type. | 641 // Actual resource type is inferred from the mime-type. |
| 592 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, JavascriptXHR) { | 642 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, JavascriptXHR) { |
| 593 auto externalScript = AddExternalResource( | 643 auto externalScript = AddExternalResource( |
| 594 GetURL(kScriptXHRPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 644 GetURL(kScriptXHRPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 595 externalScript->request.mime_type = kJavascriptMime; | 645 externalScript->request.mime_type = kJavascriptMime; |
| 596 auto image = AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, | 646 auto image = AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, |
| 597 net::HIGHEST); | 647 net::HIGHEST); |
| 598 image->request.mime_type = kImageMime; | 648 image->request.mime_type = kImageMime; |
| 599 auto style = AddResource(GetURL(kStylePath), | 649 auto style = AddResource(GetURL(kStylePath), |
| 600 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | 650 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); |
| 601 style->request.mime_type = kStyleMime; | 651 style->request.mime_type = kStyleMime; |
| 602 auto script = AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, | 652 auto script = AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, |
| 603 net::HIGHEST); | 653 net::HIGHEST); |
| 604 script->request.mime_type = kJavascriptMime; | 654 script->request.mime_type = kJavascriptMime; |
| 605 TestLearningAndPrefetching(GetURL(kHtmlXHRPath)); | 655 TestLearningAndPrefetching(GetURL(kHtmlXHRPath)); |
| 606 } | 656 } |
| 607 | 657 |
| 608 // ResourcePrefetchPredictor ignores all resources requested from subframes. | 658 // ResourcePrefetchPredictor ignores all resources requested from subframes. |
| 609 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, | 659 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 610 IframeShouldBeIgnored) { | 660 IframeShouldBeIgnored) { |
| 611 // Included from html_iframe.html. | 661 // Included from html_iframe.html. |
| 612 AddResource(GetURL(kImagePath2), content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 662 AddResource(GetURL(kImagePath2), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 613 AddResource(GetURL(kStylePath2), content::RESOURCE_TYPE_STYLESHEET, | 663 AddResource(GetURL(kStylePath2), content::RESOURCE_TYPE_STYLESHEET, |
| 614 net::HIGHEST); | 664 net::HIGHEST); |
| 615 AddResource(GetURL(kScriptPath2), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 665 AddResource(GetURL(kScriptPath2), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 616 // Included from <iframe src="html_subresources.html"> and not recored. | 666 // Included from <iframe src="html_subresources.html"> and shouldn't be |
| 617 AddUnrecordedResources({GetURL(kImagePath), GetURL(kStylePath), | 667 // observed. |
| 618 GetURL(kScriptPath), GetURL(kFontPath)}); | 668 AddUnobservableResources({GetURL(kImagePath), GetURL(kStylePath), |
| 669 GetURL(kScriptPath), GetURL(kFontPath)}); | |
| 619 TestLearningAndPrefetching(GetURL(kHtmlIframePath)); | 670 TestLearningAndPrefetching(GetURL(kHtmlIframePath)); |
| 620 } | 671 } |
| 621 | 672 |
| 673 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, AlwaysRevalidate) { | |
| 674 std::vector<ResourceSummary*> resources = { | |
| 675 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, | |
| 676 net::LOWEST), | |
| 677 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, | |
| 678 net::HIGHEST), | |
| 679 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, | |
| 680 net::MEDIUM), | |
| 681 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, | |
| 682 net::HIGHEST), | |
| 683 }; | |
| 684 for (auto& resource : resources) | |
| 685 resource->request.always_revalidate = true; | |
| 686 TestLearningAndPrefetching(GetURL(kHtmlSubresourcesPath)); | |
| 687 } | |
| 688 | |
| 622 } // namespace predictors | 689 } // namespace predictors |
| OLD | NEW |