| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 if (not_modified_) { | 878 if (not_modified_) { |
| 879 response_status->assign("HTTP/1.1 304 Not Modified"); | 879 response_status->assign("HTTP/1.1 304 Not Modified"); |
| 880 response_data->clear(); | 880 response_data->clear(); |
| 881 return; | 881 return; |
| 882 } | 882 } |
| 883 | 883 |
| 884 std::vector<net::HttpByteRange> ranges; | 884 std::vector<net::HttpByteRange> ranges; |
| 885 std::string range_header; | 885 std::string range_header; |
| 886 if (!request->extra_headers.GetHeader( | 886 if (!request->extra_headers.GetHeader( |
| 887 net::HttpRequestHeaders::kRange, &range_header) || | 887 net::HttpRequestHeaders::kRange, &range_header) || |
| 888 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || | 888 !net::HttpUtil::ParseRangeHeader(range_header, &ranges) || bad_200_ || |
| 889 ranges.size() != 1) | 889 ranges.size() != 1) { |
| 890 // This is not a byte range request. We return 200. |
| 891 response_status->assign("HTTP/1.1 200 OK"); |
| 892 response_headers->assign("Date: Wed, 28 Nov 2007 09:40:09 GMT"); |
| 893 response_data->assign("Not a range"); |
| 890 return; | 894 return; |
| 895 } |
| 896 |
| 891 // We can handle this range request. | 897 // We can handle this range request. |
| 892 net::HttpByteRange byte_range = ranges[0]; | 898 net::HttpByteRange byte_range = ranges[0]; |
| 893 if (byte_range.first_byte_position() > 79) { | 899 if (byte_range.first_byte_position() > 79) { |
| 894 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); | 900 response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); |
| 895 response_data->clear(); | 901 response_data->clear(); |
| 896 return; | 902 return; |
| 897 } | 903 } |
| 898 | 904 |
| 899 EXPECT_TRUE(byte_range.ComputeBounds(80)); | 905 EXPECT_TRUE(byte_range.ComputeBounds(80)); |
| 900 int start = static_cast<int>(byte_range.first_byte_position()); | 906 int start = static_cast<int>(byte_range.first_byte_position()); |
| 901 int end = static_cast<int>(byte_range.last_byte_position()); | 907 int end = static_cast<int>(byte_range.last_byte_position()); |
| 902 | 908 |
| 903 EXPECT_LT(end, 80); | 909 EXPECT_LT(end, 80); |
| 904 | 910 |
| 905 std::string content_range = base::StringPrintf( | 911 std::string content_range = base::StringPrintf( |
| 906 "Content-Range: bytes %d-%d/80\n", start, end); | 912 "Content-Range: bytes %d-%d/80\n", start, end); |
| 907 response_headers->append(content_range); | 913 response_headers->append(content_range); |
| 908 | 914 |
| 909 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) { | 915 if (!request->extra_headers.HasHeader("If-None-Match") || modified_) { |
| 910 EXPECT_EQ(9, (end - start) % 10); | |
| 911 std::string data; | 916 std::string data; |
| 912 for (int block_start = start; block_start < end; block_start += 10) { | 917 if (end == start) { |
| 913 base::StringAppendF(&data, "rg: %02d-%02d ", | 918 EXPECT_EQ(0, end % 10); |
| 914 block_start, block_start + 9); | 919 data = "r"; |
| 920 } else { |
| 921 EXPECT_EQ(9, (end - start) % 10); |
| 922 for (int block_start = start; block_start < end; block_start += 10) { |
| 923 base::StringAppendF(&data, "rg: %02d-%02d ", |
| 924 block_start, block_start + 9); |
| 925 } |
| 915 } | 926 } |
| 916 *response_data = data; | 927 *response_data = data; |
| 917 | 928 |
| 918 if (end - start != 9) { | 929 if (end - start != 9) { |
| 919 // We also have to fix content-length. | 930 // We also have to fix content-length. |
| 920 int len = end - start + 1; | 931 int len = end - start + 1; |
| 921 EXPECT_EQ(0, len % 10); | |
| 922 std::string content_length = base::StringPrintf("Content-Length: %d\n", | 932 std::string content_length = base::StringPrintf("Content-Length: %d\n", |
| 923 len); | 933 len); |
| 924 response_headers->replace(response_headers->find("Content-Length:"), | 934 response_headers->replace(response_headers->find("Content-Length:"), |
| 925 content_length.size(), content_length); | 935 content_length.size(), content_length); |
| 926 } | 936 } |
| 927 if (bad_200_) { | |
| 928 // We return a range, but with a response code of 200. | |
| 929 response_status->assign("HTTP/1.1 200 Success"); | |
| 930 } | |
| 931 } else { | 937 } else { |
| 932 response_status->assign("HTTP/1.1 304 Not Modified"); | 938 response_status->assign("HTTP/1.1 304 Not Modified"); |
| 933 response_data->clear(); | 939 response_data->clear(); |
| 934 } | 940 } |
| 935 } | 941 } |
| 936 | 942 |
| 937 const MockTransaction kRangeGET_TransactionOK = { | 943 const MockTransaction kRangeGET_TransactionOK = { |
| 938 "http://www.google.com/range", | 944 "http://www.google.com/range", |
| 939 "GET", | 945 "GET", |
| 940 base::Time(), | 946 base::Time(), |
| (...skipping 26 matching lines...) Expand all Loading... |
| 967 ASSERT_TRUE( | 973 ASSERT_TRUE( |
| 968 headers->GetContentRange(&range_start, &range_end, &object_size)); | 974 headers->GetContentRange(&range_start, &range_end, &object_size)); |
| 969 int64 content_length = headers->GetContentLength(); | 975 int64 content_length = headers->GetContentLength(); |
| 970 | 976 |
| 971 int length = end - start + 1; | 977 int length = end - start + 1; |
| 972 ASSERT_EQ(length, content_length); | 978 ASSERT_EQ(length, content_length); |
| 973 ASSERT_EQ(start, range_start); | 979 ASSERT_EQ(start, range_start); |
| 974 ASSERT_EQ(end, range_end); | 980 ASSERT_EQ(end, range_end); |
| 975 } | 981 } |
| 976 | 982 |
| 983 // Creates a truncated entry that can be resumed using byte ranges. |
| 984 void CreateTruncatedEntry(std::string raw_headers, MockHttpCache* cache) { |
| 985 // Create a disk cache entry that stores an incomplete resource. |
| 986 disk_cache::Entry* entry; |
| 987 ASSERT_TRUE(cache->CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, |
| 988 NULL)); |
| 989 |
| 990 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), |
| 991 raw_headers.size()); |
| 992 |
| 993 net::HttpResponseInfo response; |
| 994 response.response_time = base::Time::Now(); |
| 995 response.request_time = base::Time::Now(); |
| 996 response.headers = new net::HttpResponseHeaders(raw_headers); |
| 997 // Set the last argument for this to be an incomplete request. |
| 998 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); |
| 999 |
| 1000 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); |
| 1001 int len = static_cast<int>(base::strlcpy(buf->data(), |
| 1002 "rg: 00-09 rg: 10-19 ", 100)); |
| 1003 TestCompletionCallback cb; |
| 1004 int rv = entry->WriteData(1, 0, buf, len, &cb, true); |
| 1005 EXPECT_EQ(len, cb.GetResult(rv)); |
| 1006 entry->Close(); |
| 1007 } |
| 1008 |
| 977 // Helper to represent a network HTTP response. | 1009 // Helper to represent a network HTTP response. |
| 978 struct Response { | 1010 struct Response { |
| 979 // Set this response into |trans|. | 1011 // Set this response into |trans|. |
| 980 void AssignTo(MockTransaction* trans) const { | 1012 void AssignTo(MockTransaction* trans) const { |
| 981 trans->status = status; | 1013 trans->status = status; |
| 982 trans->response_headers = headers; | 1014 trans->response_headers = headers; |
| 983 trans->data = body; | 1015 trans->data = body; |
| 984 } | 1016 } |
| 985 | 1017 |
| 986 std::string status_and_headers() const { | 1018 std::string status_and_headers() const { |
| (...skipping 2297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3284 EXPECT_EQ(0, cache.disk_cache()->open_count()); | 3316 EXPECT_EQ(0, cache.disk_cache()->open_count()); |
| 3285 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 3317 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 3286 | 3318 |
| 3287 // Now we'll issue a request without any range that should result first in a | 3319 // Now we'll issue a request without any range that should result first in a |
| 3288 // 206 (when revalidating), and then in a weird standard answer: the test | 3320 // 206 (when revalidating), and then in a weird standard answer: the test |
| 3289 // server will not modify the response so we'll get the default range... a | 3321 // server will not modify the response so we'll get the default range... a |
| 3290 // real server will answer with 200. | 3322 // real server will answer with 200. |
| 3291 MockTransaction transaction2(kRangeGET_TransactionOK); | 3323 MockTransaction transaction2(kRangeGET_TransactionOK); |
| 3292 transaction2.request_headers = EXTRA_HEADER; | 3324 transaction2.request_headers = EXTRA_HEADER; |
| 3293 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE; | 3325 transaction2.load_flags |= net::LOAD_VALIDATE_CACHE; |
| 3294 transaction2.data = "rg: 40-49 "; | 3326 transaction2.data = "Not a range"; |
| 3295 RangeTransactionServer handler; | 3327 RangeTransactionServer handler; |
| 3296 handler.set_modified(true); | 3328 handler.set_modified(true); |
| 3297 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); | 3329 RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); |
| 3298 | 3330 |
| 3299 EXPECT_EQ(0U, headers.find("HTTP/1.1 206 Partial Content\n")); | 3331 EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); |
| 3300 EXPECT_EQ(3, cache.network_layer()->transaction_count()); | 3332 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 3301 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 3333 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 3302 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 3334 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 3303 | 3335 |
| 3304 // Verify that the previous request deleted the entry. | 3336 // Verify that the previous request deleted the entry. |
| 3305 RunTransactionTest(cache.http_cache(), transaction); | 3337 RunTransactionTest(cache.http_cache(), transaction); |
| 3306 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 3338 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| 3307 | 3339 |
| 3308 RemoveMockTransaction(&transaction); | 3340 RemoveMockTransaction(&transaction); |
| 3309 } | 3341 } |
| (...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3858 transaction.test_mode = TEST_MODE_SYNC_NET_START; | 3890 transaction.test_mode = TEST_MODE_SYNC_NET_START; |
| 3859 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; | 3891 transaction.load_flags |= net::LOAD_VALIDATE_CACHE; |
| 3860 AddMockTransaction(&transaction); | 3892 AddMockTransaction(&transaction); |
| 3861 | 3893 |
| 3862 // Write to the cache. | 3894 // Write to the cache. |
| 3863 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); | 3895 RunTransactionTest(cache.http_cache(), kRangeGET_TransactionOK); |
| 3864 | 3896 |
| 3865 // And now read from the cache and the network. | 3897 // And now read from the cache and the network. |
| 3866 RangeTransactionServer handler; | 3898 RangeTransactionServer handler; |
| 3867 handler.set_bad_200(true); | 3899 handler.set_bad_200(true); |
| 3900 transaction.data = "Not a range"; |
| 3868 RunTransactionTest(cache.http_cache(), transaction); | 3901 RunTransactionTest(cache.http_cache(), transaction); |
| 3869 | 3902 |
| 3870 EXPECT_EQ(3, cache.network_layer()->transaction_count()); | 3903 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 3871 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 3904 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 3872 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 3905 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 3873 | 3906 |
| 3874 RemoveMockTransaction(&transaction); | 3907 RemoveMockTransaction(&transaction); |
| 3875 } | 3908 } |
| 3876 | 3909 |
| 3877 // Tests that when the server gives us less data than expected, we don't keep | 3910 // Tests that when the server gives us less data than expected, we don't keep |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4173 entry->Close(); | 4206 entry->Close(); |
| 4174 | 4207 |
| 4175 RemoveMockTransaction(&transaction); | 4208 RemoveMockTransaction(&transaction); |
| 4176 } | 4209 } |
| 4177 | 4210 |
| 4178 // Tests that we can continue with a request that was interrupted. | 4211 // Tests that we can continue with a request that was interrupted. |
| 4179 TEST(HttpCache, GET_IncompleteResource) { | 4212 TEST(HttpCache, GET_IncompleteResource) { |
| 4180 MockHttpCache cache; | 4213 MockHttpCache cache; |
| 4181 AddMockTransaction(&kRangeGET_TransactionOK); | 4214 AddMockTransaction(&kRangeGET_TransactionOK); |
| 4182 | 4215 |
| 4183 // Create a disk cache entry that stores an incomplete resource. | |
| 4184 disk_cache::Entry* entry; | |
| 4185 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, | |
| 4186 NULL)); | |
| 4187 | |
| 4188 std::string raw_headers("HTTP/1.1 200 OK\n" | 4216 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 4189 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" | 4217 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
| 4190 "ETag: \"foo\"\n" | 4218 "ETag: \"foo\"\n" |
| 4191 "Accept-Ranges: bytes\n" | 4219 "Accept-Ranges: bytes\n" |
| 4192 "Content-Length: 80\n"); | 4220 "Content-Length: 80\n"); |
| 4193 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), | 4221 CreateTruncatedEntry(raw_headers, &cache); |
| 4194 raw_headers.size()); | |
| 4195 | |
| 4196 net::HttpResponseInfo response; | |
| 4197 response.headers = new net::HttpResponseHeaders(raw_headers); | |
| 4198 // Set the last argument for this to be an incomplete request. | |
| 4199 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); | |
| 4200 | |
| 4201 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); | |
| 4202 int len = static_cast<int>(base::strlcpy(buf->data(), | |
| 4203 "rg: 00-09 rg: 10-19 ", 100)); | |
| 4204 TestCompletionCallback cb; | |
| 4205 int rv = entry->WriteData(1, 0, buf, len, &cb, true); | |
| 4206 EXPECT_EQ(len, cb.GetResult(rv)); | |
| 4207 | 4222 |
| 4208 // Now make a regular request. | 4223 // Now make a regular request. |
| 4209 std::string headers; | 4224 std::string headers; |
| 4210 MockTransaction transaction(kRangeGET_TransactionOK); | 4225 MockTransaction transaction(kRangeGET_TransactionOK); |
| 4211 transaction.request_headers = EXTRA_HEADER; | 4226 transaction.request_headers = EXTRA_HEADER; |
| 4212 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " | 4227 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
| 4213 "rg: 50-59 rg: 60-69 rg: 70-79 "; | 4228 "rg: 50-59 rg: 60-69 rg: 70-79 "; |
| 4214 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 4229 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
| 4215 | 4230 |
| 4216 // We update the headers with the ones received while revalidating. | 4231 // We update the headers with the ones received while revalidating. |
| 4217 std::string expected_headers( | 4232 std::string expected_headers( |
| 4218 "HTTP/1.1 200 OK\n" | 4233 "HTTP/1.1 200 OK\n" |
| 4219 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" | 4234 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
| 4220 "Accept-Ranges: bytes\n" | 4235 "Accept-Ranges: bytes\n" |
| 4221 "ETag: \"foo\"\n" | 4236 "ETag: \"foo\"\n" |
| 4222 "Content-Length: 80\n"); | 4237 "Content-Length: 80\n"); |
| 4223 | 4238 |
| 4224 EXPECT_EQ(expected_headers, headers); | 4239 EXPECT_EQ(expected_headers, headers); |
| 4225 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 4240 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 4226 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 4241 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 4227 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4242 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 4228 | 4243 |
| 4229 RemoveMockTransaction(&kRangeGET_TransactionOK); | |
| 4230 | |
| 4231 // Verify that the disk entry was updated. | 4244 // Verify that the disk entry was updated. |
| 4245 disk_cache::Entry* entry; |
| 4246 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); |
| 4232 EXPECT_EQ(80, entry->GetDataSize(1)); | 4247 EXPECT_EQ(80, entry->GetDataSize(1)); |
| 4233 bool truncated = true; | 4248 bool truncated = true; |
| 4249 net::HttpResponseInfo response; |
| 4234 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); | 4250 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); |
| 4235 EXPECT_FALSE(truncated); | 4251 EXPECT_FALSE(truncated); |
| 4236 entry->Close(); | 4252 entry->Close(); |
| 4253 |
| 4254 RemoveMockTransaction(&kRangeGET_TransactionOK); |
| 4237 } | 4255 } |
| 4238 | 4256 |
| 4239 // Tests that we delete truncated entries if the server changes its mind midway. | 4257 // Tests that we delete truncated entries if the server changes its mind midway. |
| 4240 TEST(HttpCache, GET_IncompleteResource2) { | 4258 TEST(HttpCache, GET_IncompleteResource2) { |
| 4241 MockHttpCache cache; | 4259 MockHttpCache cache; |
| 4242 AddMockTransaction(&kRangeGET_TransactionOK); | 4260 AddMockTransaction(&kRangeGET_TransactionOK); |
| 4243 | 4261 |
| 4244 // Create a disk cache entry that stores an incomplete resource. | |
| 4245 disk_cache::Entry* entry; | |
| 4246 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, | |
| 4247 NULL)); | |
| 4248 | |
| 4249 | |
| 4250 // Content-length will be intentionally bad. | 4262 // Content-length will be intentionally bad. |
| 4251 std::string raw_headers("HTTP/1.1 200 OK\n" | 4263 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 4252 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" | 4264 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
| 4253 "ETag: \"foo\"\n" | 4265 "ETag: \"foo\"\n" |
| 4254 "Accept-Ranges: bytes\n" | 4266 "Accept-Ranges: bytes\n" |
| 4255 "Content-Length: 50\n"); | 4267 "Content-Length: 50\n"); |
| 4256 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), | 4268 CreateTruncatedEntry(raw_headers, &cache); |
| 4257 raw_headers.size()); | |
| 4258 | 4269 |
| 4259 net::HttpResponseInfo response; | 4270 // Now make a regular request. We expect the code to fail the validation and |
| 4260 response.headers = new net::HttpResponseHeaders(raw_headers); | 4271 // retry the request without using byte ranges. |
| 4261 // Set the last argument for this to be an incomplete request. | |
| 4262 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); | |
| 4263 | |
| 4264 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); | |
| 4265 int len = static_cast<int>(base::strlcpy(buf->data(), | |
| 4266 "rg: 00-09 rg: 10-19 ", 100)); | |
| 4267 TestCompletionCallback cb; | |
| 4268 int rv = entry->WriteData(1, 0, buf, len, &cb, true); | |
| 4269 EXPECT_EQ(len, cb.GetResult(rv)); | |
| 4270 entry->Close(); | |
| 4271 | |
| 4272 // Now make a regular request. | |
| 4273 std::string headers; | 4272 std::string headers; |
| 4274 MockTransaction transaction(kRangeGET_TransactionOK); | 4273 MockTransaction transaction(kRangeGET_TransactionOK); |
| 4275 transaction.request_headers = EXTRA_HEADER; | 4274 transaction.request_headers = EXTRA_HEADER; |
| 4276 transaction.data = "rg: 00-09 rg: 10-19 "; | 4275 transaction.data = "Not a range"; |
| 4277 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); | 4276 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
| 4278 | 4277 |
| 4279 // We update the headers with the ones received while revalidating. | 4278 // The server will return 200 instead of a byte range. |
| 4280 std::string expected_headers( | 4279 std::string expected_headers( |
| 4281 "HTTP/1.1 200 OK\n" | 4280 "HTTP/1.1 200 OK\n" |
| 4282 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" | 4281 "Date: Wed, 28 Nov 2007 09:40:09 GMT\n"); |
| 4283 "Accept-Ranges: bytes\n" | |
| 4284 "ETag: \"foo\"\n" | |
| 4285 "Content-Length: 50\n"); | |
| 4286 | 4282 |
| 4287 EXPECT_EQ(expected_headers, headers); | 4283 EXPECT_EQ(expected_headers, headers); |
| 4288 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 4284 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 4289 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 4285 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 4290 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4286 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 4291 | 4287 |
| 4288 // Verify that the disk entry was deleted. |
| 4289 disk_cache::Entry* entry; |
| 4290 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); |
| 4292 RemoveMockTransaction(&kRangeGET_TransactionOK); | 4291 RemoveMockTransaction(&kRangeGET_TransactionOK); |
| 4292 } |
| 4293 | 4293 |
| 4294 // Verify that the disk entry was deleted. | 4294 // Tests that we always validate a truncated request. |
| 4295 ASSERT_FALSE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); | 4295 TEST(HttpCache, GET_IncompleteResource3) { |
| 4296 MockHttpCache cache; |
| 4297 AddMockTransaction(&kRangeGET_TransactionOK); |
| 4298 |
| 4299 // This should not require validation for 10 hours. |
| 4300 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 4301 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
| 4302 "ETag: \"foo\"\n" |
| 4303 "Cache-Control: max-age= 36000\n" |
| 4304 "Accept-Ranges: bytes\n" |
| 4305 "Content-Length: 80\n"); |
| 4306 CreateTruncatedEntry(raw_headers, &cache); |
| 4307 |
| 4308 // Now make a regular request. |
| 4309 std::string headers; |
| 4310 MockTransaction transaction(kRangeGET_TransactionOK); |
| 4311 transaction.request_headers = EXTRA_HEADER; |
| 4312 transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " |
| 4313 "rg: 50-59 rg: 60-69 rg: 70-79 "; |
| 4314 |
| 4315 scoped_ptr<Context> c(new Context); |
| 4316 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans)); |
| 4317 |
| 4318 MockHttpRequest request(transaction); |
| 4319 int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); |
| 4320 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); |
| 4321 |
| 4322 // We should have checked with the server before finishing Start(). |
| 4323 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 4324 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 4325 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 4326 |
| 4327 RemoveMockTransaction(&kRangeGET_TransactionOK); |
| 4328 } |
| 4329 |
| 4330 // Tests that we cache a 200 response to the validation request. |
| 4331 TEST(HttpCache, GET_IncompleteResource4) { |
| 4332 MockHttpCache cache; |
| 4333 AddMockTransaction(&kRangeGET_TransactionOK); |
| 4334 |
| 4335 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 4336 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
| 4337 "ETag: \"foo\"\n" |
| 4338 "Accept-Ranges: bytes\n" |
| 4339 "Content-Length: 80\n"); |
| 4340 CreateTruncatedEntry(raw_headers, &cache); |
| 4341 |
| 4342 // Now make a regular request. |
| 4343 std::string headers; |
| 4344 MockTransaction transaction(kRangeGET_TransactionOK); |
| 4345 transaction.request_headers = EXTRA_HEADER; |
| 4346 transaction.data = "Not a range"; |
| 4347 RangeTransactionServer handler; |
| 4348 handler.set_bad_200(true); |
| 4349 RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); |
| 4350 |
| 4351 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 4352 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 4353 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 4354 |
| 4355 // Verify that the disk entry was updated. |
| 4356 disk_cache::Entry* entry; |
| 4357 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); |
| 4358 EXPECT_EQ(11, entry->GetDataSize(1)); |
| 4359 bool truncated = true; |
| 4360 net::HttpResponseInfo response; |
| 4361 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); |
| 4362 EXPECT_FALSE(truncated); |
| 4363 entry->Close(); |
| 4364 |
| 4365 RemoveMockTransaction(&kRangeGET_TransactionOK); |
| 4296 } | 4366 } |
| 4297 | 4367 |
| 4298 // Tests that when we cancel a request that was interrupted, we mark it again | 4368 // Tests that when we cancel a request that was interrupted, we mark it again |
| 4299 // as truncated. | 4369 // as truncated. |
| 4300 TEST(HttpCache, GET_CancelIncompleteResource) { | 4370 TEST(HttpCache, GET_CancelIncompleteResource) { |
| 4301 MockHttpCache cache; | 4371 MockHttpCache cache; |
| 4302 AddMockTransaction(&kRangeGET_TransactionOK); | 4372 AddMockTransaction(&kRangeGET_TransactionOK); |
| 4303 | 4373 |
| 4304 // Create a disk cache entry that stores an incomplete resource. | |
| 4305 disk_cache::Entry* entry; | |
| 4306 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, | |
| 4307 NULL)); | |
| 4308 | |
| 4309 std::string raw_headers("HTTP/1.1 200 OK\n" | 4374 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 4310 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" | 4375 "Last-Modified: Sat, 18 Apr 2009 01:10:43 GMT\n" |
| 4311 "ETag: \"foo\"\n" | 4376 "ETag: \"foo\"\n" |
| 4312 "Accept-Ranges: bytes\n" | 4377 "Accept-Ranges: bytes\n" |
| 4313 "Content-Length: 80\n"); | 4378 "Content-Length: 80\n"); |
| 4314 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), | 4379 CreateTruncatedEntry(raw_headers, &cache); |
| 4315 raw_headers.size()); | |
| 4316 | |
| 4317 net::HttpResponseInfo response; | |
| 4318 response.headers = new net::HttpResponseHeaders(raw_headers); | |
| 4319 | |
| 4320 // Set the last argument for this to be an incomplete request. | |
| 4321 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); | |
| 4322 | |
| 4323 scoped_refptr<net::IOBufferWithSize> buf(new net::IOBufferWithSize(100)); | |
| 4324 int len = static_cast<int>(base::strlcpy(buf->data(), "rg: 00-09 rg: 10-19 ", | |
| 4325 buf->size())); | |
| 4326 TestCompletionCallback cb; | |
| 4327 int rv = entry->WriteData(1, 0, buf, len, &cb, true); | |
| 4328 EXPECT_EQ(len, cb.GetResult(rv)); | |
| 4329 | 4380 |
| 4330 // Now make a regular request. | 4381 // Now make a regular request. |
| 4331 MockTransaction transaction(kRangeGET_TransactionOK); | 4382 MockTransaction transaction(kRangeGET_TransactionOK); |
| 4332 transaction.request_headers = EXTRA_HEADER; | 4383 transaction.request_headers = EXTRA_HEADER; |
| 4333 | 4384 |
| 4334 MockHttpRequest request(transaction); | 4385 MockHttpRequest request(transaction); |
| 4335 Context* c = new Context(); | 4386 Context* c = new Context(); |
| 4336 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans)); | 4387 EXPECT_EQ(net::OK, cache.http_cache()->CreateTransaction(&c->trans)); |
| 4337 | 4388 |
| 4338 rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); | 4389 int rv = c->trans->Start(&request, &c->callback, net::BoundNetLog()); |
| 4339 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); | 4390 EXPECT_EQ(net::OK, c->callback.GetResult(rv)); |
| 4340 | 4391 |
| 4341 // Read 20 bytes from the cache, and 10 from the net. | 4392 // Read 20 bytes from the cache, and 10 from the net. |
| 4342 rv = c->trans->Read(buf, len, &c->callback); | 4393 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); |
| 4343 EXPECT_EQ(len, c->callback.GetResult(rv)); | 4394 rv = c->trans->Read(buf, 20, &c->callback); |
| 4395 EXPECT_EQ(20, c->callback.GetResult(rv)); |
| 4344 rv = c->trans->Read(buf, 10, &c->callback); | 4396 rv = c->trans->Read(buf, 10, &c->callback); |
| 4345 EXPECT_EQ(10, c->callback.GetResult(rv)); | 4397 EXPECT_EQ(10, c->callback.GetResult(rv)); |
| 4346 | 4398 |
| 4347 // At this point, we are already reading so canceling the request should leave | 4399 // At this point, we are already reading so canceling the request should leave |
| 4348 // a truncated one. | 4400 // a truncated one. |
| 4349 delete c; | 4401 delete c; |
| 4350 | 4402 |
| 4351 RemoveMockTransaction(&kRangeGET_TransactionOK); | |
| 4352 | |
| 4353 EXPECT_EQ(2, cache.network_layer()->transaction_count()); | 4403 EXPECT_EQ(2, cache.network_layer()->transaction_count()); |
| 4354 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 4404 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 4355 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4405 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 4356 | 4406 |
| 4357 // Verify that the disk entry was updated: now we have 30 bytes. | 4407 // Verify that the disk entry was updated: now we have 30 bytes. |
| 4408 disk_cache::Entry* entry; |
| 4409 ASSERT_TRUE(cache.OpenBackendEntry(kRangeGET_TransactionOK.url, &entry)); |
| 4358 EXPECT_EQ(30, entry->GetDataSize(1)); | 4410 EXPECT_EQ(30, entry->GetDataSize(1)); |
| 4359 bool truncated = false; | 4411 bool truncated = false; |
| 4412 net::HttpResponseInfo response; |
| 4360 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); | 4413 EXPECT_TRUE(MockHttpCache::ReadResponseInfo(entry, &response, &truncated)); |
| 4361 EXPECT_TRUE(truncated); | 4414 EXPECT_TRUE(truncated); |
| 4362 entry->Close(); | 4415 entry->Close(); |
| 4416 RemoveMockTransaction(&kRangeGET_TransactionOK); |
| 4363 } | 4417 } |
| 4364 | 4418 |
| 4365 // Tests that we can handle range requests when we have a truncated entry. | 4419 // Tests that we can handle range requests when we have a truncated entry. |
| 4366 TEST(HttpCache, RangeGET_IncompleteResource) { | 4420 TEST(HttpCache, RangeGET_IncompleteResource) { |
| 4367 MockHttpCache cache; | 4421 MockHttpCache cache; |
| 4368 AddMockTransaction(&kRangeGET_TransactionOK); | 4422 AddMockTransaction(&kRangeGET_TransactionOK); |
| 4369 | 4423 |
| 4370 // Create a disk cache entry that stores an incomplete resource. | |
| 4371 disk_cache::Entry* entry; | |
| 4372 ASSERT_TRUE(cache.CreateBackendEntry(kRangeGET_TransactionOK.url, &entry, | |
| 4373 NULL)); | |
| 4374 | |
| 4375 // Content-length will be intentionally bogus. | 4424 // Content-length will be intentionally bogus. |
| 4376 std::string raw_headers("HTTP/1.1 200 OK\n" | 4425 std::string raw_headers("HTTP/1.1 200 OK\n" |
| 4377 "Last-Modified: something\n" | 4426 "Last-Modified: something\n" |
| 4378 "ETag: \"foo\"\n" | 4427 "ETag: \"foo\"\n" |
| 4379 "Accept-Ranges: bytes\n" | 4428 "Accept-Ranges: bytes\n" |
| 4380 "Content-Length: 10\n"); | 4429 "Content-Length: 10\n"); |
| 4381 raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), | 4430 CreateTruncatedEntry(raw_headers, &cache); |
| 4382 raw_headers.size()); | |
| 4383 | |
| 4384 net::HttpResponseInfo response; | |
| 4385 response.headers = new net::HttpResponseHeaders(raw_headers); | |
| 4386 // Set the last argument for this to be an incomplete request. | |
| 4387 EXPECT_TRUE(MockHttpCache::WriteResponseInfo(entry, &response, true, true)); | |
| 4388 | |
| 4389 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(100)); | |
| 4390 int len = static_cast<int>(base::strlcpy(buf->data(), | |
| 4391 "rg: 00-09 rg: 10-19 ", 100)); | |
| 4392 TestCompletionCallback cb; | |
| 4393 int rv = entry->WriteData(1, 0, buf, len, &cb, true); | |
| 4394 EXPECT_EQ(len, cb.GetResult(rv)); | |
| 4395 entry->Close(); | |
| 4396 | 4431 |
| 4397 // Now make a range request. | 4432 // Now make a range request. |
| 4398 std::string headers; | 4433 std::string headers; |
| 4399 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, | 4434 RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, |
| 4400 &headers); | 4435 &headers); |
| 4401 | 4436 |
| 4402 Verify206Response(headers, 40, 49); | 4437 Verify206Response(headers, 40, 49); |
| 4403 EXPECT_EQ(1, cache.network_layer()->transaction_count()); | 4438 EXPECT_EQ(1, cache.network_layer()->transaction_count()); |
| 4404 EXPECT_EQ(1, cache.disk_cache()->open_count()); | 4439 EXPECT_EQ(1, cache.disk_cache()->open_count()); |
| 4405 EXPECT_EQ(2, cache.disk_cache()->create_count()); | 4440 EXPECT_EQ(2, cache.disk_cache()->create_count()); |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4866 // Now return 200 when validating the entry so the metadata will be lost. | 4901 // Now return 200 when validating the entry so the metadata will be lost. |
| 4867 MockTransaction trans2(kTypicalGET_Transaction); | 4902 MockTransaction trans2(kTypicalGET_Transaction); |
| 4868 trans2.load_flags = net::LOAD_VALIDATE_CACHE; | 4903 trans2.load_flags = net::LOAD_VALIDATE_CACHE; |
| 4869 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response); | 4904 RunTransactionTestWithResponseInfo(cache.http_cache(), trans2, &response); |
| 4870 EXPECT_TRUE(response.metadata.get() == NULL); | 4905 EXPECT_TRUE(response.metadata.get() == NULL); |
| 4871 | 4906 |
| 4872 EXPECT_EQ(3, cache.network_layer()->transaction_count()); | 4907 EXPECT_EQ(3, cache.network_layer()->transaction_count()); |
| 4873 EXPECT_EQ(4, cache.disk_cache()->open_count()); | 4908 EXPECT_EQ(4, cache.disk_cache()->open_count()); |
| 4874 EXPECT_EQ(1, cache.disk_cache()->create_count()); | 4909 EXPECT_EQ(1, cache.disk_cache()->create_count()); |
| 4875 } | 4910 } |
| OLD | NEW |