| OLD | NEW |
| 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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 "net/http/http_cache.h" | 5 #include "net/http/http_cache.h" |
| 6 | 6 |
| 7 #include "base/hash_tables.h" | 7 #include "base/hash_tables.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/scoped_vector.h" | 9 #include "base/scoped_vector.h" |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 622 0 | 622 0 |
| 623 }; | 623 }; |
| 624 | 624 |
| 625 // This class provides a handler for kRangeGET_TransactionOK so that the range | 625 // This class provides a handler for kRangeGET_TransactionOK so that the range |
| 626 // request can be served on demand. | 626 // request can be served on demand. |
| 627 class RangeTransactionServer { | 627 class RangeTransactionServer { |
| 628 public: | 628 public: |
| 629 RangeTransactionServer() { | 629 RangeTransactionServer() { |
| 630 not_modified_ = false; | 630 not_modified_ = false; |
| 631 modified_ = false; | 631 modified_ = false; |
| 632 bad_200_ = false; |
| 632 } | 633 } |
| 633 ~RangeTransactionServer() { | 634 ~RangeTransactionServer() { |
| 634 not_modified_ = false; | 635 not_modified_ = false; |
| 635 modified_ = false; | 636 modified_ = false; |
| 637 bad_200_ = false; |
| 636 } | 638 } |
| 637 | 639 |
| 638 // Returns only 416 or 304 when set. | 640 // Returns only 416 or 304 when set. |
| 639 void set_not_modified(bool value) { not_modified_ = value; } | 641 void set_not_modified(bool value) { not_modified_ = value; } |
| 640 | 642 |
| 641 // Returns 206 when revalidating a range (instead of 304). | 643 // Returns 206 when revalidating a range (instead of 304). |
| 642 void set_modified(bool value) { modified_ = value; } | 644 void set_modified(bool value) { modified_ = value; } |
| 643 | 645 |
| 646 // Returns 200 instead of 206 (a malformed response overall). |
| 647 void set_bad_200(bool value) { bad_200_ = value; } |
| 648 |
| 644 static void RangeHandler(const net::HttpRequestInfo* request, | 649 static void RangeHandler(const net::HttpRequestInfo* request, |
| 645 std::string* response_status, | 650 std::string* response_status, |
| 646 std::string* response_headers, | 651 std::string* response_headers, |
| 647 std::string* response_data); | 652 std::string* response_data); |
| 648 | 653 |
| 649 private: | 654 private: |
| 650 static bool not_modified_; | 655 static bool not_modified_; |
| 651 static bool modified_; | 656 static bool modified_; |
| 657 static bool bad_200_; |
| 652 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); | 658 DISALLOW_COPY_AND_ASSIGN(RangeTransactionServer); |
| 653 }; | 659 }; |
| 654 bool RangeTransactionServer::not_modified_ = false; | 660 bool RangeTransactionServer::not_modified_ = false; |
| 655 bool RangeTransactionServer::modified_ = false; | 661 bool RangeTransactionServer::modified_ = false; |
| 662 bool RangeTransactionServer::bad_200_ = false; |
| 656 | 663 |
| 657 // A dummy extra header that must be preserved on a given request. | 664 // A dummy extra header that must be preserved on a given request. |
| 658 #define EXTRA_HEADER "Extra: header\r\n" | 665 #define EXTRA_HEADER "Extra: header\r\n" |
| 659 | 666 |
| 660 // Static. | 667 // Static. |
| 661 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, | 668 void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, |
| 662 std::string* response_status, | 669 std::string* response_status, |
| 663 std::string* response_headers, | 670 std::string* response_headers, |
| 664 std::string* response_data) { | 671 std::string* response_data) { |
| 665 if (request->extra_headers.empty()) { | 672 if (request->extra_headers.empty()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 *response_data = data; | 712 *response_data = data; |
| 706 | 713 |
| 707 if (end - start != 9) { | 714 if (end - start != 9) { |
| 708 // We also have to fix content-length. | 715 // We also have to fix content-length. |
| 709 int len = end - start + 1; | 716 int len = end - start + 1; |
| 710 EXPECT_EQ(0, len % 10); | 717 EXPECT_EQ(0, len % 10); |
| 711 std::string content_length = StringPrintf("Content-Length: %d\n", len); | 718 std::string content_length = StringPrintf("Content-Length: %d\n", len); |
| 712 response_headers->replace(response_headers->find("Content-Length:"), | 719 response_headers->replace(response_headers->find("Content-Length:"), |
| 713 content_length.size(), content_length); | 720 content_length.size(), content_length); |
| 714 } | 721 } |
| 722 if (bad_200_) { |
| 723 // We return a range, but with a response code of 200. |
| 724 response_status->assign("HTTP/1.1 200 Success"); |
| 725 } |
| 715 } else { | 726 } else { |
| 716 response_status->assign("HTTP/1.1 304 Not Modified"); | 727 response_status->assign("HTTP/1.1 304 Not Modified"); |
| 717 response_data->clear(); | 728 response_data->clear(); |
| 718 } | 729 } |
| 719 } | 730 } |
| 720 | 731 |
| 721 const MockTransaction kRangeGET_TransactionOK = { | 732 const MockTransaction kRangeGET_TransactionOK = { |
| 722 "http://www.google.com/range", | 733 "http://www.google.com/range", |
| 723 "GET", | 734 "GET", |
| 724 base::Time(), | 735 base::Time(), |
| (...skipping 2337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3062 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 3073 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
| 3063 | 3074 |
| 3064 EXPECT_TRUE(Verify206Response(headers, 70, 79)); | 3075 EXPECT_TRUE(Verify206Response(headers, 70, 79)); |
| 3065 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 3076 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 3066 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 3077 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 3067 EXPECT_EQ(0, cache.disk_cache()->create_count()); | 3078 EXPECT_EQ(0, cache.disk_cache()->create_count()); |
| 3068 | 3079 |
| 3069 RemoveMockTransaction(&kRangeGET_TransactionOK); | 3080 RemoveMockTransaction(&kRangeGET_TransactionOK); |
| 3070 } | 3081 } |
| 3071 | 3082 |
| 3083 // Tests that we don't crash when after reading from the cache we issue a |
| 3084 // request for the next range and the server gives us a 200 synchronously. |
| 3085 TEST(HttpCache, RangeGET_FastFlakyServer) { |
| 3086 MockHttpCache cache; |
| 3087 cache.http_cache()->set_enable_range_support(true); |
| 3088 |
| 3089 MockTransaction transaction(kRangeGET_TransactionOK); |
| 3090 transaction.request_headers = "Range: bytes = 40-\r\n" EXTRA_HEADER; |
| 3091 transaction.test_mode = TEST_MODE_SYNC_NET_START; |
| 3092 AddMockTransaction(&transaction); |
| 3093 |
| 3094 // Write to the cache. |
| 3095 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
| 3096 |
| 3097 // And now read from the cache and the network. |
| 3098 RangeTransactionServer handler; |
| 3099 handler.set_bad_200(true); |
| 3100 RunTransactionTest(cache.http_cache(), transaction); |
| 3101 |
| 3102 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 3103 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 3104 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 3105 |
| 3106 RemoveMockTransaction(&transaction); |
| 3107 } |
| 3108 |
| 3072 #ifdef NDEBUG | 3109 #ifdef NDEBUG |
| 3073 // This test hits a NOTREACHED so it is a release mode only test. | 3110 // This test hits a NOTREACHED so it is a release mode only test. |
| 3074 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) { | 3111 TEST(HttpCache, RangeGET_OK_LoadOnlyFromCache) { |
| 3075 MockHttpCache cache; | 3112 MockHttpCache cache; |
| 3076 cache.http_cache()->set_enable_range_support(true); | 3113 cache.http_cache()->set_enable_range_support(true); |
| 3077 AddMockTransaction(&kRangeGET_TransactionOK); | 3114 AddMockTransaction(&kRangeGET_TransactionOK); |
| 3078 | 3115 |
| 3079 // Write to the cache (40-49). | 3116 // Write to the cache (40-49). |
| 3080 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); | 3117 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
| 3081 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 3118 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3710 std::string headers; | 3747 std::string headers; |
| 3711 response.headers->GetNormalizedHeaders(&headers); | 3748 response.headers->GetNormalizedHeaders(&headers); |
| 3712 | 3749 |
| 3713 EXPECT_EQ("HTTP/1.1 200 OK\n" | 3750 EXPECT_EQ("HTTP/1.1 200 OK\n" |
| 3714 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" | 3751 "Date: Wed, 22 Jul 2009 03:15:26 GMT\n" |
| 3715 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", | 3752 "Last-Modified: Wed, 06 Feb 2008 22:38:21 GMT\n", |
| 3716 headers); | 3753 headers); |
| 3717 | 3754 |
| 3718 RemoveMockTransaction(&mock_network_response); | 3755 RemoveMockTransaction(&mock_network_response); |
| 3719 } | 3756 } |
| OLD | NEW |