| 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/predictors/resource_prefetch_predictor.h" | 6 #include "chrome/browser/predictors/resource_prefetch_predictor.h" |
| 7 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" | 7 #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" |
| 8 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" | 8 #include "chrome/browser/predictors/resource_prefetch_predictor_test_util.h" |
| 9 #include "chrome/browser/profiles/profile.h" | 9 #include "chrome/browser/profiles/profile.h" |
| 10 #include "chrome/browser/ui/browser.h" | 10 #include "chrome/browser/ui/browser.h" |
| 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| 12 #include "chrome/common/chrome_switches.h" | 12 #include "chrome/common/chrome_switches.h" |
| 13 #include "chrome/test/base/in_process_browser_test.h" | 13 #include "chrome/test/base/in_process_browser_test.h" |
| 14 #include "chrome/test/base/ui_test_utils.h" | 14 #include "chrome/test/base/ui_test_utils.h" |
| 15 #include "content/public/browser/render_frame_host.h" | 15 #include "content/public/browser/render_frame_host.h" |
| 16 #include "content/public/browser/render_process_host.h" | 16 #include "content/public/browser/render_process_host.h" |
| 17 #include "net/test/embedded_test_server/http_request.h" | 17 #include "net/test/embedded_test_server/http_request.h" |
| 18 #include "net/test/embedded_test_server/http_response.h" | 18 #include "net/test/embedded_test_server/http_response.h" |
| 19 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 21 |
| 22 namespace predictors { | 22 namespace predictors { |
| 23 | 23 |
| 24 static const char kImageUrl[] = "/predictors/image.png"; | 24 static const char kImagePath[] = "/predictors/image.png"; |
| 25 static const char kStyleUrl[] = "/predictors/style.css"; | 25 static const char kStylePath[] = "/predictors/style.css"; |
| 26 static const char kScriptUrl[] = "/predictors/script.js"; | 26 static const char kScriptPath[] = "/predictors/script.js"; |
| 27 static const char kFontUrl[] = "/predictors/font.ttf"; | 27 static const char kFontPath[] = "/predictors/font.ttf"; |
| 28 static const char kHtmlSubresourcesUrl[] = "/predictors/html_subresources.html"; | 28 static const char kHtmlSubresourcesPath[] = |
| 29 "/predictors/html_subresources.html"; |
| 30 static const char kRedirectPath[] = "/predictors/redirect.html"; |
| 31 static const char kRedirectPath2[] = "/predictors/redirect2.html"; |
| 32 static const char kRedirectPath3[] = "/predictors/redirect3.html"; |
| 29 | 33 |
| 30 struct ResourceSummary { | 34 struct ResourceSummary { |
| 31 ResourceSummary() : is_no_store(false), version(0) {} | 35 ResourceSummary() : is_no_store(false), version(0) {} |
| 32 | 36 |
| 33 ResourcePrefetchPredictor::URLRequestSummary request; | 37 ResourcePrefetchPredictor::URLRequestSummary request; |
| 34 std::string content; | 38 std::string content; |
| 35 bool is_no_store; | 39 bool is_no_store; |
| 36 size_t version; | 40 size_t version; |
| 37 }; | 41 }; |
| 38 | 42 |
| 43 struct RedirectEdge { |
| 44 // This response code should be returned by previous url in the chain. |
| 45 net::HttpStatusCode code; |
| 46 GURL url; |
| 47 }; |
| 48 |
| 39 class InitializationObserver : public TestObserver { | 49 class InitializationObserver : public TestObserver { |
| 40 public: | 50 public: |
| 41 explicit InitializationObserver(ResourcePrefetchPredictor* predictor) | 51 explicit InitializationObserver(ResourcePrefetchPredictor* predictor) |
| 42 : TestObserver(predictor) {} | 52 : TestObserver(predictor) {} |
| 43 | 53 |
| 44 void OnPredictorInitialized() override { run_loop_.Quit(); } | 54 void OnPredictorInitialized() override { run_loop_.Quit(); } |
| 45 | 55 |
| 46 void Wait() { run_loop_.Run(); } | 56 void Wait() { run_loop_.Run(); } |
| 47 | 57 |
| 48 private: | 58 private: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 | 92 |
| 83 private: | 93 private: |
| 84 base::RunLoop run_loop_; | 94 base::RunLoop run_loop_; |
| 85 size_t url_visit_count_; | 95 size_t url_visit_count_; |
| 86 PageRequestSummary summary_; | 96 PageRequestSummary summary_; |
| 87 | 97 |
| 88 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver); | 98 DISALLOW_COPY_AND_ASSIGN(ResourcePrefetchPredictorTestObserver); |
| 89 }; | 99 }; |
| 90 | 100 |
| 91 class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { | 101 class ResourcePrefetchPredictorBrowserTest : public InProcessBrowserTest { |
| 92 public: | 102 protected: |
| 93 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; | 103 using URLRequestSummary = ResourcePrefetchPredictor::URLRequestSummary; |
| 94 | 104 |
| 95 void SetUpCommandLine(base::CommandLine* command_line) override { | 105 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 96 command_line->AppendSwitchASCII( | 106 command_line->AppendSwitchASCII( |
| 97 switches::kSpeculativeResourcePrefetching, | 107 switches::kSpeculativeResourcePrefetching, |
| 98 switches::kSpeculativeResourcePrefetchingEnabled); | 108 switches::kSpeculativeResourcePrefetchingEnabled); |
| 99 } | 109 } |
| 100 | 110 |
| 101 void SetUpOnMainThread() override { | 111 void SetUpOnMainThread() override { |
| 102 embedded_test_server()->RegisterRequestHandler( | 112 embedded_test_server()->RegisterRequestHandler(base::Bind( |
| 103 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRequest, | 113 &ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| 104 base::Unretained(this))); | 114 base::Unretained(this), base::Unretained(embedded_test_server()))); |
| 115 embedded_test_server()->RegisterRequestHandler(base::Bind( |
| 116 &ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| 117 base::Unretained(this), base::Unretained(embedded_test_server()))); |
| 105 ASSERT_TRUE(embedded_test_server()->Start()); | 118 ASSERT_TRUE(embedded_test_server()->Start()); |
| 106 predictor_ = | 119 predictor_ = |
| 107 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); | 120 ResourcePrefetchPredictorFactory::GetForProfile(browser()->profile()); |
| 108 ASSERT_TRUE(predictor_); | 121 ASSERT_TRUE(predictor_); |
| 109 EnsurePredictorInitialized(); | 122 EnsurePredictorInitialized(); |
| 110 } | 123 } |
| 111 | 124 |
| 112 void NavigateToURLAndCheckSubresources( | 125 void NavigateToURLAndCheckSubresources(const GURL& main_frame_url) { |
| 113 const std::string& main_frame_relative) { | 126 GURL endpoint_url = GetRedirectEndpoint(main_frame_url); |
| 114 GURL main_frame_absolute = | |
| 115 embedded_test_server()->GetURL(main_frame_relative); | |
| 116 std::vector<URLRequestSummary> url_request_summaries; | 127 std::vector<URLRequestSummary> url_request_summaries; |
| 117 for (const auto& kv : resources_) { | 128 for (const auto& kv : resources_) { |
| 118 if (kv.second.is_no_store) | 129 if (kv.second.is_no_store) |
| 119 continue; | 130 continue; |
| 120 url_request_summaries.push_back( | 131 url_request_summaries.push_back( |
| 121 GetURLRequestSummaryForResource(main_frame_absolute, kv.second)); | 132 GetURLRequestSummaryForResource(endpoint_url, kv.second)); |
| 122 } | 133 } |
| 123 ResourcePrefetchPredictorTestObserver observer( | 134 ResourcePrefetchPredictorTestObserver observer( |
| 124 predictor_, UpdateAndGetVisitCount(main_frame_relative), | 135 predictor_, UpdateAndGetVisitCount(main_frame_url), |
| 125 CreatePageRequestSummary(main_frame_absolute.spec(), | 136 CreatePageRequestSummary(endpoint_url.spec(), main_frame_url.spec(), |
| 126 main_frame_absolute.spec(), | |
| 127 url_request_summaries)); | 137 url_request_summaries)); |
| 128 ui_test_utils::NavigateToURL(browser(), main_frame_absolute); | 138 ui_test_utils::NavigateToURL(browser(), main_frame_url); |
| 129 observer.Wait(); | 139 observer.Wait(); |
| 130 } | 140 } |
| 131 | 141 |
| 132 ResourceSummary* AddResource(const std::string& relative_url, | 142 ResourceSummary* AddResource(const GURL& resource_url, |
| 133 content::ResourceType resource_type, | 143 content::ResourceType resource_type, |
| 134 net::RequestPriority priority) { | 144 net::RequestPriority priority) { |
| 135 ResourceSummary resource; | 145 auto pair_and_whether_inserted = |
| 136 resource.request.resource_url = | 146 resources_.insert(std::make_pair(resource_url, ResourceSummary())); |
| 137 embedded_test_server()->GetURL(relative_url); | 147 EXPECT_TRUE(pair_and_whether_inserted.second) << resource_url |
| 138 resource.request.resource_type = resource_type; | 148 << " was inserted twice"; |
| 139 resource.request.priority = priority; | 149 ResourceSummary* resource = &pair_and_whether_inserted.first->second; |
| 140 auto result = resources_.insert(std::make_pair(relative_url, resource)); | 150 resource->request.resource_url = resource_url; |
| 141 return &(result.first->second); | 151 resource->request.resource_type = resource_type; |
| 152 resource->request.priority = priority; |
| 153 resource->request.has_validators = true; |
| 154 return resource; |
| 142 } | 155 } |
| 143 | 156 |
| 157 void AddRedirectChain(const GURL& initial_url, |
| 158 const std::vector<RedirectEdge>& redirect_chain) { |
| 159 ASSERT_FALSE(redirect_chain.empty()); |
| 160 GURL current = initial_url; |
| 161 for (const auto& edge : redirect_chain) { |
| 162 auto result = redirects_.insert(std::make_pair(current, edge)); |
| 163 EXPECT_TRUE(result.second) << current << " already has a redirect."; |
| 164 current = edge.url; |
| 165 } |
| 166 } |
| 167 |
| 168 // Shortcut for convenience. |
| 169 GURL GetURL(const std::string& path) const { |
| 170 return embedded_test_server()->GetURL(path); |
| 171 } |
| 172 |
| 173 void EnableHttpsServer() { |
| 174 ASSERT_FALSE(https_server_); |
| 175 https_server_ = base::MakeUnique<net::EmbeddedTestServer>( |
| 176 net::EmbeddedTestServer::TYPE_HTTPS); |
| 177 https_server()->AddDefaultHandlers( |
| 178 base::FilePath(FILE_PATH_LITERAL("chrome/test/data"))); |
| 179 https_server()->RegisterRequestHandler( |
| 180 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleRedirectRequest, |
| 181 base::Unretained(this), base::Unretained(https_server()))); |
| 182 https_server()->RegisterRequestHandler( |
| 183 base::Bind(&ResourcePrefetchPredictorBrowserTest::HandleResourceRequest, |
| 184 base::Unretained(this), base::Unretained(https_server()))); |
| 185 ASSERT_TRUE(https_server()->Start()); |
| 186 } |
| 187 |
| 188 // Returns the embedded test server working over HTTPS. Must be enabled by |
| 189 // calling EnableHttpsServer() before use. |
| 190 const net::EmbeddedTestServer* https_server() const { |
| 191 return https_server_.get(); |
| 192 } |
| 193 |
| 194 net::EmbeddedTestServer* https_server() { return https_server_.get(); } |
| 195 |
| 144 private: | 196 private: |
| 145 // ResourcePrefetchPredictor needs to be initialized before the navigation | 197 // ResourcePrefetchPredictor needs to be initialized before the navigation |
| 146 // happens otherwise this navigation will be ignored by predictor. | 198 // happens otherwise this navigation will be ignored by predictor. |
| 147 void EnsurePredictorInitialized() { | 199 void EnsurePredictorInitialized() { |
| 148 if (predictor_->initialization_state_ == | 200 if (predictor_->initialization_state_ == |
| 149 ResourcePrefetchPredictor::INITIALIZED) { | 201 ResourcePrefetchPredictor::INITIALIZED) { |
| 150 return; | 202 return; |
| 151 } | 203 } |
| 152 | 204 |
| 153 InitializationObserver observer(predictor_); | 205 InitializationObserver observer(predictor_); |
| 154 if (predictor_->initialization_state_ == | 206 if (predictor_->initialization_state_ == |
| 155 ResourcePrefetchPredictor::NOT_INITIALIZED) { | 207 ResourcePrefetchPredictor::NOT_INITIALIZED) { |
| 156 predictor_->StartInitialization(); | 208 predictor_->StartInitialization(); |
| 157 } | 209 } |
| 158 observer.Wait(); | 210 observer.Wait(); |
| 159 } | 211 } |
| 160 | 212 |
| 161 URLRequestSummary GetURLRequestSummaryForResource( | 213 URLRequestSummary GetURLRequestSummaryForResource( |
| 162 const GURL& main_frame_url, | 214 const GURL& main_frame_url, |
| 163 const ResourceSummary& resource_summary) { | 215 const ResourceSummary& resource_summary) const { |
| 164 URLRequestSummary summary(resource_summary.request); | 216 URLRequestSummary summary(resource_summary.request); |
| 165 content::WebContents* web_contents = | 217 content::WebContents* web_contents = |
| 166 browser()->tab_strip_model()->GetActiveWebContents(); | 218 browser()->tab_strip_model()->GetActiveWebContents(); |
| 167 int process_id = web_contents->GetRenderProcessHost()->GetID(); | 219 int process_id = web_contents->GetRenderProcessHost()->GetID(); |
| 168 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); | 220 int frame_id = web_contents->GetMainFrame()->GetRoutingID(); |
| 169 summary.navigation_id = | 221 summary.navigation_id = |
| 170 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); | 222 CreateNavigationID(process_id, frame_id, main_frame_url.spec()); |
| 171 return summary; | 223 return summary; |
| 172 } | 224 } |
| 173 | 225 |
| 174 std::unique_ptr<net::test_server::HttpResponse> HandleRequest( | 226 GURL GetRedirectEndpoint(const GURL& initial_url) const { |
| 175 const net::test_server::HttpRequest& request) { | 227 GURL current = initial_url; |
| 176 auto resource_it = resources_.find(request.relative_url); | 228 while (true) { |
| 229 auto it = redirects_.find(current); |
| 230 if (it == redirects_.end()) |
| 231 break; |
| 232 current = it->second.url; |
| 233 } |
| 234 return current; |
| 235 } |
| 236 |
| 237 std::unique_ptr<net::test_server::HttpResponse> HandleResourceRequest( |
| 238 const net::test_server::EmbeddedTestServer* server, |
| 239 const net::test_server::HttpRequest& request) const { |
| 240 auto resource_it = resources_.find(server->GetURL(request.relative_url)); |
| 177 if (resource_it == resources_.end()) | 241 if (resource_it == resources_.end()) |
| 178 return nullptr; | 242 return nullptr; |
| 179 | 243 |
| 180 const ResourceSummary& summary = resource_it->second; | 244 const ResourceSummary& summary = resource_it->second; |
| 181 auto http_response = | 245 auto http_response = |
| 182 base::MakeUnique<net::test_server::BasicHttpResponse>(); | 246 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 183 http_response->set_code(net::HTTP_OK); | 247 http_response->set_code(net::HTTP_OK); |
| 184 if (!summary.request.mime_type.empty()) | 248 if (!summary.request.mime_type.empty()) |
| 185 http_response->set_content_type(summary.request.mime_type); | 249 http_response->set_content_type(summary.request.mime_type); |
| 186 http_response->set_content(summary.content); | 250 if (!summary.content.empty()) |
| 251 http_response->set_content(summary.content); |
| 187 if (summary.is_no_store) | 252 if (summary.is_no_store) |
| 188 http_response->AddCustomHeader("Cache-Control", "no-store"); | 253 http_response->AddCustomHeader("Cache-Control", "no-store"); |
| 189 if (summary.request.has_validators) { | 254 if (summary.request.has_validators) { |
| 190 http_response->AddCustomHeader( | 255 http_response->AddCustomHeader( |
| 191 "ETag", base::StringPrintf("'%zu%s'", summary.version, | 256 "ETag", base::StringPrintf("'%zu%s'", summary.version, |
| 192 request.relative_url.c_str())); | 257 request.relative_url.c_str())); |
| 193 } | 258 } |
| 194 if (summary.request.always_revalidate) | 259 if (summary.request.always_revalidate) |
| 195 http_response->AddCustomHeader("Cache-Control", "no-cache"); | 260 http_response->AddCustomHeader("Cache-Control", "no-cache"); |
| 196 else | 261 else |
| 197 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); | 262 http_response->AddCustomHeader("Cache-Control", "max-age=2147483648"); |
| 198 return std::move(http_response); | 263 return std::move(http_response); |
| 199 } | 264 } |
| 200 | 265 |
| 201 size_t UpdateAndGetVisitCount(const std::string& main_frame_relative) { | 266 std::unique_ptr<net::test_server::HttpResponse> HandleRedirectRequest( |
| 202 return ++visit_count_[main_frame_relative]; | 267 const net::test_server::EmbeddedTestServer* server, |
| 268 const net::test_server::HttpRequest& request) const { |
| 269 auto redirect_it = redirects_.find(server->GetURL(request.relative_url)); |
| 270 if (redirect_it == redirects_.end()) |
| 271 return nullptr; |
| 272 |
| 273 auto http_response = |
| 274 base::MakeUnique<net::test_server::BasicHttpResponse>(); |
| 275 http_response->set_code(redirect_it->second.code); |
| 276 http_response->AddCustomHeader("Location", redirect_it->second.url.spec()); |
| 277 return std::move(http_response); |
| 278 } |
| 279 |
| 280 size_t UpdateAndGetVisitCount(const GURL& main_frame_url) { |
| 281 return ++visit_count_[main_frame_url]; |
| 203 } | 282 } |
| 204 | 283 |
| 205 ResourcePrefetchPredictor* predictor_; | 284 ResourcePrefetchPredictor* predictor_; |
| 206 std::map<std::string, ResourceSummary> resources_; | 285 std::unique_ptr<net::EmbeddedTestServer> https_server_; |
| 207 std::map<std::string, size_t> visit_count_; | 286 std::map<GURL, ResourceSummary> resources_; |
| 287 std::map<GURL, RedirectEdge> redirects_; |
| 288 std::map<GURL, size_t> visit_count_; |
| 208 }; | 289 }; |
| 209 | 290 |
| 210 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { | 291 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, LearningSimple) { |
| 211 // These resources have default priorities that correspond to | 292 // These resources have default priorities that correspond to |
| 212 // blink::typeToPriority function. | 293 // blink::typeToPriority function. |
| 213 AddResource(kImageUrl, content::RESOURCE_TYPE_IMAGE, net::LOWEST); | 294 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 214 AddResource(kStyleUrl, content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); | 295 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 215 AddResource(kScriptUrl, content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); | 296 net::HIGHEST); |
| 216 AddResource(kFontUrl, content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); | 297 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 217 NavigateToURLAndCheckSubresources(kHtmlSubresourcesUrl); | 298 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 299 net::HIGHEST); |
| 300 NavigateToURLAndCheckSubresources(GetURL(kHtmlSubresourcesPath)); |
| 301 } |
| 302 |
| 303 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 304 LearningAfterRedirect) { |
| 305 AddRedirectChain(GetURL(kRedirectPath), {{net::HTTP_MOVED_PERMANENTLY, |
| 306 GetURL(kHtmlSubresourcesPath)}}); |
| 307 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 308 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 309 net::HIGHEST); |
| 310 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 311 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 312 net::HIGHEST); |
| 313 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); |
| 314 } |
| 315 |
| 316 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 317 LearningAfterRedirectChain) { |
| 318 AddRedirectChain(GetURL(kRedirectPath), |
| 319 {{net::HTTP_FOUND, GetURL(kRedirectPath2)}, |
| 320 {net::HTTP_MOVED_PERMANENTLY, GetURL(kRedirectPath3)}, |
| 321 {net::HTTP_FOUND, GetURL(kHtmlSubresourcesPath)}}); |
| 322 AddResource(GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, net::LOWEST); |
| 323 AddResource(GetURL(kStylePath), content::RESOURCE_TYPE_STYLESHEET, |
| 324 net::HIGHEST); |
| 325 AddResource(GetURL(kScriptPath), content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 326 AddResource(GetURL(kFontPath), content::RESOURCE_TYPE_FONT_RESOURCE, |
| 327 net::HIGHEST); |
| 328 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); |
| 329 } |
| 330 |
| 331 IN_PROC_BROWSER_TEST_F(ResourcePrefetchPredictorBrowserTest, |
| 332 LearningAfterHttpToHttpsRedirect) { |
| 333 EnableHttpsServer(); |
| 334 AddRedirectChain(GetURL(kRedirectPath), |
| 335 {{net::HTTP_FOUND, https_server()->GetURL(kRedirectPath2)}, |
| 336 {net::HTTP_MOVED_PERMANENTLY, |
| 337 https_server()->GetURL(kHtmlSubresourcesPath)}}); |
| 338 AddResource(https_server()->GetURL(kImagePath), content::RESOURCE_TYPE_IMAGE, |
| 339 net::LOWEST); |
| 340 AddResource(https_server()->GetURL(kStylePath), |
| 341 content::RESOURCE_TYPE_STYLESHEET, net::HIGHEST); |
| 342 AddResource(https_server()->GetURL(kScriptPath), |
| 343 content::RESOURCE_TYPE_SCRIPT, net::MEDIUM); |
| 344 AddResource(https_server()->GetURL(kFontPath), |
| 345 content::RESOURCE_TYPE_FONT_RESOURCE, net::HIGHEST); |
| 346 NavigateToURLAndCheckSubresources(GetURL(kRedirectPath)); |
| 218 } | 347 } |
| 219 | 348 |
| 220 } // namespace predictors | 349 } // namespace predictors |
| OLD | NEW |