1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/url_request/url_request_throttler_manager.h" 6 7 #include "base/memory/scoped_ptr.h" 8 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram_samples.h" 10 #include "base/metrics/statistics_recorder.h" 11 #include "base/pickle.h" 12 #include "base/stl_util.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/stringprintf.h" 15 #include "base/time/time.h" 16 #include "net/base/load_flags.h" 17 #include "net/base/test_completion_callback.h" 18 #include "net/url_request/url_request_context.h" 19 #include "net/url_request/url_request_test_util.h" 20 #include "net/url_request/url_request_throttler_header_interface.h" 21 #include "net/url_request/url_request_throttler_test_support.h" 22 #include "testing/gtest/include/gtest/gtest.h" 23 24 using base::TimeDelta; 25 using base::TimeTicks; 26 27 namespace net { 28 29 namespace { 30 31 using base::Histogram; 32 using base::HistogramBase; 33 using base::HistogramSamples; 34 using base::StatisticsRecorder; 35 36 class MockURLRequestThrottlerEntry : public URLRequestThrottlerEntry { 37 public: 38 explicit MockURLRequestThrottlerEntry( 39 net::URLRequestThrottlerManager* manager) 40 : net::URLRequestThrottlerEntry(manager, std::string()), 41 mock_backoff_entry_(&backoff_policy_) { 42 InitPolicy(); 43 } 44 MockURLRequestThrottlerEntry( 45 net::URLRequestThrottlerManager* manager, 46 const TimeTicks& exponential_backoff_release_time, 47 const TimeTicks& sliding_window_release_time, 48 const TimeTicks& fake_now) 49 : net::URLRequestThrottlerEntry(manager, std::string()), 50 fake_time_now_(fake_now), 51 mock_backoff_entry_(&backoff_policy_) { 52 InitPolicy(); 53 54 mock_backoff_entry_.set_fake_now(fake_now); 55 set_exponential_backoff_release_time(exponential_backoff_release_time); 56 set_sliding_window_release_time(sliding_window_release_time); 57 } 58 59 void InitPolicy() { 60 // Some tests become flaky if we have jitter. 61 backoff_policy_.jitter_factor = 0.0; 62 63 // This lets us avoid having to make multiple failures initially (this 64 // logic is already tested in the BackoffEntry unit tests). 65 backoff_policy_.num_errors_to_ignore = 0; 66 } 67 68 virtual const BackoffEntry* GetBackoffEntry() const OVERRIDE { 69 return &mock_backoff_entry_; 70 } 71 72 virtual BackoffEntry* GetBackoffEntry() OVERRIDE { 73 return &mock_backoff_entry_; 74 } 75 76 static bool ExplicitUserRequest(int load_flags) { 77 return URLRequestThrottlerEntry::ExplicitUserRequest(load_flags); 78 } 79 80 void ResetToBlank(const TimeTicks& time_now) { 81 fake_time_now_ = time_now; 82 mock_backoff_entry_.set_fake_now(time_now); 83 84 GetBackoffEntry()->Reset(); 85 GetBackoffEntry()->SetCustomReleaseTime(time_now); 86 set_sliding_window_release_time(time_now); 87 } 88 89 // Overridden for tests. 90 virtual TimeTicks ImplGetTimeNow() const OVERRIDE { return fake_time_now_; } 91 92 void set_exponential_backoff_release_time( 93 const base::TimeTicks& release_time) { 94 GetBackoffEntry()->SetCustomReleaseTime(release_time); 95 } 96 97 base::TimeTicks sliding_window_release_time() const { 98 return URLRequestThrottlerEntry::sliding_window_release_time(); 99 } 100 101 void set_sliding_window_release_time( 102 const base::TimeTicks& release_time) { 103 URLRequestThrottlerEntry::set_sliding_window_release_time( 104 release_time); 105 } 106 107 TimeTicks fake_time_now_; 108 MockBackoffEntry mock_backoff_entry_; 109 110 protected: 111 virtual ~MockURLRequestThrottlerEntry() {} 112 }; 113 114 class MockURLRequestThrottlerManager : public URLRequestThrottlerManager { 115 public: 116 MockURLRequestThrottlerManager() : create_entry_index_(0) {} 117 118 // Method to process the URL using URLRequestThrottlerManager protected 119 // method. 120 std::string DoGetUrlIdFromUrl(const GURL& url) { return GetIdFromUrl(url); } 121 122 // Method to use the garbage collecting method of URLRequestThrottlerManager. 123 void DoGarbageCollectEntries() { GarbageCollectEntries(); } 124 125 // Returns the number of entries in the map. 126 int GetNumberOfEntries() const { return GetNumberOfEntriesForTests(); } 127 128 void CreateEntry(bool is_outdated) { 129 TimeTicks time = TimeTicks::Now(); 130 if (is_outdated) { 131 time -= TimeDelta::FromMilliseconds( 132 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs + 1000); 133 } 134 std::string fake_url_string("http://www.fakeurl.com/"); 135 fake_url_string.append(base::IntToString(create_entry_index_++)); 136 GURL fake_url(fake_url_string); 137 OverrideEntryForTests( 138 fake_url, 139 new MockURLRequestThrottlerEntry(this, time, TimeTicks::Now(), 140 TimeTicks::Now())); 141 } 142 143 private: 144 int create_entry_index_; 145 }; 146 147 struct TimeAndBool { 148 TimeAndBool(const TimeTicks& time_value, bool expected, int line_num) { 149 time = time_value; 150 result = expected; 151 line = line_num; 152 } 153 TimeTicks time; 154 bool result; 155 int line; 156 }; 157 158 struct GurlAndString { 159 GurlAndString(const GURL& url_value, 160 const std::string& expected, 161 int line_num) { 162 url = url_value; 163 result = expected; 164 line = line_num; 165 } 166 GURL url; 167 std::string result; 168 int line; 169 }; 170 171 } // namespace 172 173 class URLRequestThrottlerEntryTest : public testing::Test { 174 protected: 175 URLRequestThrottlerEntryTest() : request_(GURL(), NULL, &context_, NULL) { 176 } 177 178 virtual void SetUp(); 179 virtual void TearDown(); 180 181 // After calling this function, histogram snapshots in |samples_| contain 182 // only the delta caused by the test case currently running. 183 void CalculateHistogramDeltas(); 184 185 TimeTicks now_; 186 MockURLRequestThrottlerManager manager_; // Dummy object, not used. 187 scoped_refptr<MockURLRequestThrottlerEntry> entry_; 188 189 std::map<std::string, HistogramSamples*> original_samples_; 190 std::map<std::string, HistogramSamples*> samples_; 191 192 TestURLRequestContext context_; 193 TestURLRequest request_; 194 }; 195 196 // List of all histograms we care about in these unit tests. 197 const char* kHistogramNames[] = { 198 "Throttling.FailureCountAtSuccess", 199 "Throttling.PerceivedDowntime", 200 "Throttling.RequestThrottled", 201 "Throttling.SiteOptedOut", 202 }; 203 204 void URLRequestThrottlerEntryTest::SetUp() { 205 request_.set_load_flags(0); 206 207 now_ = TimeTicks::Now(); 208 entry_ = new MockURLRequestThrottlerEntry(&manager_); 209 entry_->ResetToBlank(now_); 210 211 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { 212 // Must retrieve original samples for each histogram for comparison 213 // as other tests may affect them. 214 const char* name = kHistogramNames[i]; 215 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 216 if (histogram) { 217 original_samples_[name] = histogram->SnapshotSamples().release(); 218 } else { 219 original_samples_[name] = NULL; 220 } 221 } 222 } 223 224 void URLRequestThrottlerEntryTest::TearDown() { 225 STLDeleteValues(&original_samples_); 226 STLDeleteValues(&samples_); 227 } 228 229 void URLRequestThrottlerEntryTest::CalculateHistogramDeltas() { 230 for (size_t i = 0; i < arraysize(kHistogramNames); ++i) { 231 const char* name = kHistogramNames[i]; 232 HistogramSamples* original = original_samples_[name]; 233 234 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 235 if (histogram) { 236 ASSERT_EQ(HistogramBase::kUmaTargetedHistogramFlag, histogram->flags()); 237 238 scoped_ptr<HistogramSamples> samples(histogram->SnapshotSamples()); 239 if (original) 240 samples->Subtract(*original); 241 samples_[name] = samples.release(); 242 } 243 } 244 245 // Ensure we don't accidentally use the originals in our tests. 246 STLDeleteValues(&original_samples_); 247 original_samples_.clear(); 248 } 249 250 std::ostream& operator<<(std::ostream& out, const base::TimeTicks& time) { 251 return out << time.ToInternalValue(); 252 } 253 254 TEST_F(URLRequestThrottlerEntryTest, InterfaceDuringExponentialBackoff) { 255 entry_->set_exponential_backoff_release_time( 256 entry_->fake_time_now_ + TimeDelta::FromMilliseconds(1)); 257 EXPECT_TRUE(entry_->ShouldRejectRequest(request_)); 258 259 // Also end-to-end test the load flags exceptions. 260 request_.set_load_flags(LOAD_MAYBE_USER_GESTURE); 261 EXPECT_FALSE(entry_->ShouldRejectRequest(request_)); 262 263 CalculateHistogramDeltas(); 264 ASSERT_EQ(1, samples_["Throttling.RequestThrottled"]->GetCount(0)); 265 ASSERT_EQ(1, samples_["Throttling.RequestThrottled"]->GetCount(1)); 266 } 267 268 TEST_F(URLRequestThrottlerEntryTest, InterfaceNotDuringExponentialBackoff) { 269 entry_->set_exponential_backoff_release_time(entry_->fake_time_now_); 270 EXPECT_FALSE(entry_->ShouldRejectRequest(request_)); 271 entry_->set_exponential_backoff_release_time( 272 entry_->fake_time_now_ - TimeDelta::FromMilliseconds(1)); 273 EXPECT_FALSE(entry_->ShouldRejectRequest(request_)); 274 275 CalculateHistogramDeltas(); 276 ASSERT_EQ(2, samples_["Throttling.RequestThrottled"]->GetCount(0)); 277 ASSERT_EQ(0, samples_["Throttling.RequestThrottled"]->GetCount(1)); 278 } 279 280 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateFailure) { 281 MockURLRequestThrottlerHeaderAdapter failure_response(503); 282 entry_->UpdateWithResponse(std::string(), &failure_response); 283 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) 284 << "A failure should increase the release_time"; 285 } 286 287 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccess) { 288 MockURLRequestThrottlerHeaderAdapter success_response(200); 289 entry_->UpdateWithResponse(std::string(), &success_response); 290 EXPECT_EQ(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) 291 << "A success should not add any delay"; 292 } 293 294 TEST_F(URLRequestThrottlerEntryTest, InterfaceUpdateSuccessThenFailure) { 295 MockURLRequestThrottlerHeaderAdapter failure_response(503); 296 MockURLRequestThrottlerHeaderAdapter success_response(200); 297 entry_->UpdateWithResponse(std::string(), &success_response); 298 entry_->UpdateWithResponse(std::string(), &failure_response); 299 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), entry_->fake_time_now_) 300 << "This scenario should add delay"; 301 entry_->UpdateWithResponse(std::string(), &success_response); 302 } 303 304 TEST_F(URLRequestThrottlerEntryTest, IsEntryReallyOutdated) { 305 TimeDelta lifetime = TimeDelta::FromMilliseconds( 306 MockURLRequestThrottlerEntry::kDefaultEntryLifetimeMs); 307 const TimeDelta kFiveMs = TimeDelta::FromMilliseconds(5); 308 309 TimeAndBool test_values[] = { 310 TimeAndBool(now_, false, __LINE__), 311 TimeAndBool(now_ - kFiveMs, false, __LINE__), 312 TimeAndBool(now_ + kFiveMs, false, __LINE__), 313 TimeAndBool(now_ - (lifetime - kFiveMs), false, __LINE__), 314 TimeAndBool(now_ - lifetime, true, __LINE__), 315 TimeAndBool(now_ - (lifetime + kFiveMs), true, __LINE__)}; 316 317 for (unsigned int i = 0; i < arraysize(test_values); ++i) { 318 entry_->set_exponential_backoff_release_time(test_values[i].time); 319 EXPECT_EQ(entry_->IsEntryOutdated(), test_values[i].result) << 320 "Test case #" << i << " line " << test_values[i].line << " failed"; 321 } 322 } 323 324 TEST_F(URLRequestThrottlerEntryTest, MaxAllowedBackoff) { 325 for (int i = 0; i < 30; ++i) { 326 MockURLRequestThrottlerHeaderAdapter response_adapter(503); 327 entry_->UpdateWithResponse(std::string(), &response_adapter); 328 } 329 330 TimeDelta delay = entry_->GetExponentialBackoffReleaseTime() - now_; 331 EXPECT_EQ(delay.InMilliseconds(), 332 MockURLRequestThrottlerEntry::kDefaultMaximumBackoffMs); 333 } 334 335 TEST_F(URLRequestThrottlerEntryTest, MalformedContent) { 336 MockURLRequestThrottlerHeaderAdapter response_adapter(503); 337 for (int i = 0; i < 5; ++i) 338 entry_->UpdateWithResponse(std::string(), &response_adapter); 339 340 TimeTicks release_after_failures = entry_->GetExponentialBackoffReleaseTime(); 341 342 // Inform the entry that a response body was malformed, which is supposed to 343 // increase the back-off time. Note that we also submit a successful 344 // UpdateWithResponse to pair with ReceivedContentWasMalformed() since that 345 // is what happens in practice (if a body is received, then a non-500 346 // response must also have been received). 347 entry_->ReceivedContentWasMalformed(200); 348 MockURLRequestThrottlerHeaderAdapter success_adapter(200); 349 entry_->UpdateWithResponse(std::string(), &success_adapter); 350 EXPECT_GT(entry_->GetExponentialBackoffReleaseTime(), release_after_failures); 351 } 352 353 TEST_F(URLRequestThrottlerEntryTest, SlidingWindow) { 354 int max_send = URLRequestThrottlerEntry::kDefaultMaxSendThreshold; 355 int sliding_window = 356 URLRequestThrottlerEntry::kDefaultSlidingWindowPeriodMs; 357 358 TimeTicks time_1 = entry_->fake_time_now_ + 359 TimeDelta::FromMilliseconds(sliding_window / 3); 360 TimeTicks time_2 = entry_->fake_time_now_ + 361 TimeDelta::FromMilliseconds(2 * sliding_window / 3); 362 TimeTicks time_3 = entry_->fake_time_now_ + 363 TimeDelta::FromMilliseconds(sliding_window); 364 TimeTicks time_4 = entry_->fake_time_now_ + 365 TimeDelta::FromMilliseconds(sliding_window + 2 * sliding_window / 3); 366 367 entry_->set_exponential_backoff_release_time(time_1); 368 369 for (int i = 0; i < max_send / 2; ++i) { 370 EXPECT_EQ(2 * sliding_window / 3, 371 entry_->ReserveSendingTimeForNextRequest(time_2)); 372 } 373 EXPECT_EQ(time_2, entry_->sliding_window_release_time()); 374 375 entry_->fake_time_now_ = time_3; 376 377 for (int i = 0; i < (max_send + 1) / 2; ++i) 378 EXPECT_EQ(0, entry_->ReserveSendingTimeForNextRequest(TimeTicks())); 379 380 EXPECT_EQ(time_4, entry_->sliding_window_release_time()); 381 } 382 383 TEST_F(URLRequestThrottlerEntryTest, ExplicitUserRequest) { 384 ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest(0)); 385 ASSERT_TRUE(MockURLRequestThrottlerEntry::ExplicitUserRequest( 386 LOAD_MAYBE_USER_GESTURE)); 387 ASSERT_FALSE(MockURLRequestThrottlerEntry::ExplicitUserRequest( 388 ~LOAD_MAYBE_USER_GESTURE)); 389 } 390 391 class URLRequestThrottlerManagerTest : public testing::Test { 392 protected: 393 URLRequestThrottlerManagerTest() 394 : request_(GURL(), NULL, &context_, NULL) { 395 } 396 397 virtual void SetUp() { 398 request_.set_load_flags(0); 399 } 400 401 // context_ must be declared before request_. 402 TestURLRequestContext context_; 403 TestURLRequest request_; 404 }; 405 406 TEST_F(URLRequestThrottlerManagerTest, IsUrlStandardised) { 407 MockURLRequestThrottlerManager manager; 408 GurlAndString test_values[] = { 409 GurlAndString(GURL("http://www.example.com"), 410 std::string("http://www.example.com/"), 411 __LINE__), 412 GurlAndString(GURL("http://www.Example.com"), 413 std::string("http://www.example.com/"), 414 __LINE__), 415 GurlAndString(GURL("http://www.ex4mple.com/Pr4c71c41"), 416 std::string("http://www.ex4mple.com/pr4c71c41"), 417 __LINE__), 418 GurlAndString(GURL("http://www.example.com/0/token/false"), 419 std::string("http://www.example.com/0/token/false"), 420 __LINE__), 421 GurlAndString(GURL("http://www.example.com/index.php?code=javascript"), 422 std::string("http://www.example.com/index.php"), 423 __LINE__), 424 GurlAndString(GURL("http://www.example.com/index.php?code=1#superEntry"), 425 std::string("http://www.example.com/index.php"), 426 __LINE__), 427 GurlAndString(GURL("http://www.example.com/index.php#superEntry"), 428 std::string("http://www.example.com/index.php"), 429 __LINE__), 430 GurlAndString(GURL("http://www.example.com:1234/"), 431 std::string("http://www.example.com:1234/"), 432 __LINE__)}; 433 434 for (unsigned int i = 0; i < arraysize(test_values); ++i) { 435 std::string temp = manager.DoGetUrlIdFromUrl(test_values[i].url); 436 EXPECT_EQ(temp, test_values[i].result) << 437 "Test case #" << i << " line " << test_values[i].line << " failed"; 438 } 439 } 440 441 TEST_F(URLRequestThrottlerManagerTest, AreEntriesBeingCollected) { 442 MockURLRequestThrottlerManager manager; 443 444 manager.CreateEntry(true); // true = Entry is outdated. 445 manager.CreateEntry(true); 446 manager.CreateEntry(true); 447 manager.DoGarbageCollectEntries(); 448 EXPECT_EQ(0, manager.GetNumberOfEntries()); 449 450 manager.CreateEntry(false); 451 manager.CreateEntry(false); 452 manager.CreateEntry(false); 453 manager.CreateEntry(true); 454 manager.DoGarbageCollectEntries(); 455 EXPECT_EQ(3, manager.GetNumberOfEntries()); 456 } 457 458 TEST_F(URLRequestThrottlerManagerTest, IsHostBeingRegistered) { 459 MockURLRequestThrottlerManager manager; 460 461 manager.RegisterRequestUrl(GURL("http://www.example.com/")); 462 manager.RegisterRequestUrl(GURL("http://www.google.com/")); 463 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0")); 464 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0?code=1")); 465 manager.RegisterRequestUrl(GURL("http://www.google.com/index/0#lolsaure")); 466 467 EXPECT_EQ(3, manager.GetNumberOfEntries()); 468 } 469 470 void ExpectEntryAllowsAllOnErrorIfOptedOut( 471 net::URLRequestThrottlerEntryInterface* entry, 472 bool opted_out, 473 const URLRequest& request) { 474 EXPECT_FALSE(entry->ShouldRejectRequest(request)); 475 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); 476 for (int i = 0; i < 10; ++i) { 477 // Host doesn't really matter in this scenario so we skip it. 478 entry->UpdateWithResponse(std::string(), &failure_adapter); 479 } 480 EXPECT_NE(opted_out, entry->ShouldRejectRequest(request)); 481 482 if (opted_out) { 483 // We're not mocking out GetTimeNow() in this scenario 484 // so add a 100 ms buffer to avoid flakiness (that should always 485 // give enough time to get from the TimeTicks::Now() call here 486 // to the TimeTicks::Now() call in the entry class). 487 EXPECT_GT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100), 488 entry->GetExponentialBackoffReleaseTime()); 489 } else { 490 // As above, add 100 ms. 491 EXPECT_LT(TimeTicks::Now() + TimeDelta::FromMilliseconds(100), 492 entry->GetExponentialBackoffReleaseTime()); 493 } 494 } 495 496 TEST_F(URLRequestThrottlerManagerTest, OptOutHeader) { 497 MockURLRequestThrottlerManager manager; 498 scoped_refptr<net::URLRequestThrottlerEntryInterface> entry = 499 manager.RegisterRequestUrl(GURL("http://www.google.com/yodude")); 500 501 // Fake a response with the opt-out header. 502 MockURLRequestThrottlerHeaderAdapter response_adapter( 503 std::string(), 504 MockURLRequestThrottlerEntry::kExponentialThrottlingDisableValue, 505 200); 506 entry->UpdateWithResponse("www.google.com", &response_adapter); 507 508 // Ensure that the same entry on error always allows everything. 509 ExpectEntryAllowsAllOnErrorIfOptedOut(entry.get(), true, request_); 510 511 // Ensure that a freshly created entry (for a different URL on an 512 // already opted-out host) also gets "always allow" behavior. 513 scoped_refptr<net::URLRequestThrottlerEntryInterface> other_entry = 514 manager.RegisterRequestUrl(GURL("http://www.google.com/bingobob")); 515 ExpectEntryAllowsAllOnErrorIfOptedOut(other_entry.get(), true, request_); 516 517 // Fake a response with the opt-out header incorrectly specified. 518 scoped_refptr<net::URLRequestThrottlerEntryInterface> no_opt_out_entry = 519 manager.RegisterRequestUrl(GURL("http://www.nike.com/justdoit")); 520 MockURLRequestThrottlerHeaderAdapter wrong_adapter( 521 std::string(), "yesplease", 200); 522 no_opt_out_entry->UpdateWithResponse("www.nike.com", &wrong_adapter); 523 ExpectEntryAllowsAllOnErrorIfOptedOut( 524 no_opt_out_entry.get(), false, request_); 525 526 // A localhost entry should always be opted out. 527 scoped_refptr<net::URLRequestThrottlerEntryInterface> localhost_entry = 528 manager.RegisterRequestUrl(GURL("http://localhost/hello")); 529 ExpectEntryAllowsAllOnErrorIfOptedOut(localhost_entry.get(), true, request_); 530 } 531 532 TEST_F(URLRequestThrottlerManagerTest, ClearOnNetworkChange) { 533 for (int i = 0; i < 3; ++i) { 534 MockURLRequestThrottlerManager manager; 535 scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_before = 536 manager.RegisterRequestUrl(GURL("http://www.example.com/")); 537 MockURLRequestThrottlerHeaderAdapter failure_adapter(503); 538 for (int j = 0; j < 10; ++j) { 539 // Host doesn't really matter in this scenario so we skip it. 540 entry_before->UpdateWithResponse(std::string(), &failure_adapter); 541 } 542 EXPECT_TRUE(entry_before->ShouldRejectRequest(request_)); 543 544 switch (i) { 545 case 0: 546 manager.OnIPAddressChanged(); 547 break; 548 case 1: 549 manager.OnConnectionTypeChanged( 550 net::NetworkChangeNotifier::CONNECTION_UNKNOWN); 551 break; 552 case 2: 553 manager.OnConnectionTypeChanged( 554 net::NetworkChangeNotifier::CONNECTION_NONE); 555 break; 556 default: 557 FAIL(); 558 } 559 560 scoped_refptr<net::URLRequestThrottlerEntryInterface> entry_after = 561 manager.RegisterRequestUrl(GURL("http://www.example.com/")); 562 EXPECT_FALSE(entry_after->ShouldRejectRequest(request_)); 563 } 564 } 565 566 } // namespace net 567