diff options
-rw-r--r-- | net/http/http_cache.cc | 106 | ||||
-rw-r--r-- | net/http/http_cache_unittest.cc | 192 | ||||
-rw-r--r-- | net/http/http_response_headers.cc | 9 | ||||
-rw-r--r-- | net/http/http_response_headers.h | 4 | ||||
-rw-r--r-- | net/http/http_response_headers_unittest.cc | 55 | ||||
-rw-r--r-- | net/http/partial_data.cc | 53 | ||||
-rw-r--r-- | net/http/partial_data.h | 3 |
7 files changed, 374 insertions, 48 deletions
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 5035fb9..b7707d1 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -309,6 +309,9 @@ class HttpCache::Transaction // copy is valid). Returns true if able to make the request conditional. bool ConditionalizeRequest(); + // Makes sure that a 206 response is expected. Returns a network error code. + bool ValidatePartialResponse(const HttpResponseHeaders* headers); + // Reads data from the network. int ReadFromNetwork(IOBuffer* data, int data_len); @@ -335,6 +338,10 @@ class HttpCache::Transaction // Called when we are done writing to the cache entry. void DoneWritingToEntry(bool success); + // Deletes the current partial cache entry (sparse), and optionally removes + // the control object (partial_). + void DoomPartialEntry(bool delete_object); + // Performs the needed work after receiving data from the network. int DoNetworkReadCompleted(int result); @@ -798,6 +805,7 @@ void HttpCache::Transaction::SetRequest(const HttpRequestInfo* request) { } else { // The range is invalid or we cannot handle it properly. effective_load_flags_ |= LOAD_DISABLE_CACHE; + partial_.reset(NULL); } } @@ -883,15 +891,23 @@ int HttpCache::Transaction::BeginPartialCacheValidation() { return BeginCacheValidation(); #endif - if (!partial_.get()) { + bool byte_range_requested = partial_.get() != NULL; + if (!byte_range_requested) { // The request is not for a range, but we have stored just ranges. - // TODO(rvargas): Add support for this case. - NOTREACHED(); + partial_.reset(new PartialData()); + if (!custom_request_.get()) { + custom_request_.reset(new HttpRequestInfo(*request_)); + request_ = custom_request_.get(); + DCHECK(custom_request_->extra_headers.empty()); + } } - if (!partial_->UpdateFromStoredHeaders(response_.headers)) { - // TODO(rvargas): Handle this error. - NOTREACHED(); + if (!partial_->UpdateFromStoredHeaders(response_.headers, + entry_->disk_entry)) { + // The stored data cannot be used. Get rid of it and restart this request. + DoomPartialEntry(!byte_range_requested); + mode_ = WRITE; + return AddToEntry(); } return ContinuePartialCacheValidation(); @@ -899,8 +915,6 @@ int HttpCache::Transaction::BeginPartialCacheValidation() { int HttpCache::Transaction::ContinuePartialCacheValidation() { DCHECK(mode_ == READ_WRITE); - // TODO(rvargas): Avoid re-validation of each cached piece. - int rv = partial_->PrepareCacheValidation(entry_->disk_entry, &custom_request_->extra_headers); @@ -914,6 +928,15 @@ int HttpCache::Transaction::ContinuePartialCacheValidation() { return HandleResult(rv); } + if (reading_ && partial_->IsCurrentRangeCached()) { + rv = ReadFromEntry(read_buf_, read_buf_len_); + + // We are supposed to hanlde errors here. + if (rv < 0 && rv != ERR_IO_PENDING) + HandleResult(rv); + return rv; + } + return BeginCacheValidation(); } @@ -1080,6 +1103,50 @@ bool HttpCache::Transaction::ConditionalizeRequest() { return true; } +bool HttpCache::Transaction::ValidatePartialResponse( + const HttpResponseHeaders* headers) { +#ifdef ENABLE_RANGE_SUPPORT + bool partial_content = headers->response_code() == 206; +#else + bool partial_content = false; +#endif + + bool failure = false; + if (!partial_content) { + if (!partial_.get()) + return false; + + // TODO(rvargas): Do we need to consider other results here?. + if (headers->response_code() == 200 || headers->response_code() == 416) + failure = true; + + if (!reading_ && failure) { + // We are expecting 206 or 304 because we asked for a range. Given that + // the server is refusing the request we'll remove the sparse entry. + DoomPartialEntry(true); + mode_ = NONE; + return false; + } + } + + if (!failure && partial_.get() && partial_->ResponseHeadersOK(headers)) + return true; + + // We have a problem. We may or may not be reading already (in which case we + // returned the headers), but we'll just pretend that this request is not + // using the cache and see what happens. Most likely this is the first + // response from the server (it's not changing its mind midway, right?). + if (mode_ & WRITE) { + DoneWritingToEntry(mode_ != WRITE); + } else if (mode_ & READ && entry_) { + cache_->DoneReadingFromEntry(entry_, this); + } + + entry_ = NULL; + mode_ = NONE; + return false; +} + int HttpCache::Transaction::ReadFromNetwork(IOBuffer* data, int data_len) { int rv = network_trans_->Read(data, data_len, &network_read_callback_); read_buf_ = data; @@ -1197,6 +1264,14 @@ void HttpCache::Transaction::DoneWritingToEntry(bool success) { mode_ = NONE; // switch to 'pass through' mode } +void HttpCache::Transaction::DoomPartialEntry(bool delete_object) { + cache_->DoneWithEntry(entry_, this); + cache_->DoomEntry(cache_key_); + entry_ = NULL; + if (delete_object) + partial_.reset(NULL); +} + void HttpCache::Transaction::OnNetworkInfoAvailable(int result) { DCHECK(result != ERR_IO_PENDING); @@ -1211,19 +1286,8 @@ void HttpCache::Transaction::OnNetworkInfoAvailable(int result) { new_response->headers->response_code() == 407) { auth_response_ = *new_response; } else { -#ifdef ENABLE_RANGE_SUPPORT - bool partial_content = new_response->headers->response_code() == 206; -#else - bool partial_content = false; -#endif - // TODO(rvargas): Validate partial_content vs partial_ and mode_ - if (partial_content) { - DCHECK(partial_.get()); - if (!partial_->ResponseHeadersOK(new_response->headers)) { - // TODO(rvargas): Handle this error. - NOTREACHED(); - } - } + bool partial_content = ValidatePartialResponse(new_response->headers); + // Are we expecting a response to a conditional query? if (mode_ == READ_WRITE || mode_ == UPDATE) { if (new_response->headers->response_code() == 304 || partial_content) { diff --git a/net/http/http_cache_unittest.cc b/net/http/http_cache_unittest.cc index 3f9e667..2efd751 100644 --- a/net/http/http_cache_unittest.cc +++ b/net/http/http_cache_unittest.cc @@ -485,8 +485,10 @@ void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, std::string* response_status, std::string* response_headers, std::string* response_data) { - if (request->extra_headers.empty()) + if (request->extra_headers.empty()) { + response_status->assign("HTTP/1.1 416 Requested Range Not Satisfiable"); return; + } std::vector<net::HttpByteRange> ranges; if (!net::HttpUtil::ParseRanges(request->extra_headers, &ranges) || @@ -505,9 +507,20 @@ void RangeTransactionServer::RangeHandler(const net::HttpRequestInfo* request, response_headers->append(content_range); if (request->extra_headers.find("If-None-Match") == std::string::npos) { - EXPECT_EQ(9, end - start); - std::string data = StringPrintf("rg: %02d-%02d ", start, end); + EXPECT_EQ(9, (end - start) % 10); + std::string data; + for (int block_start = start; block_start < end; block_start += 10) + StringAppendF(&data, "rg: %02d-%02d ", block_start, block_start + 9); *response_data = data; + + if (end - start != 9) { + // We also have to fix content-length. + int len = end - start + 1; + EXPECT_EQ(0, len % 10); + std::string content_length = StringPrintf("Content-Length: %d\n", len); + response_headers->replace(response_headers->find("Content-Length:"), + content_length.size(), content_length); + } } else { response_status->assign("HTTP/1.1 304 Not Modified"); response_data->clear(); @@ -1634,13 +1647,14 @@ TEST(HttpCache, RangeGET_SkipsCache) { TEST(HttpCache, GET_Crazy206) { MockHttpCache cache; - AddMockTransaction(&kRangeGET_TransactionOK); // Test that receiving 206 for a regular request is handled correctly. // Write to the cache. MockTransaction transaction(kRangeGET_TransactionOK); + AddMockTransaction(&transaction); transaction.request_headers = ""; + transaction.handler = NULL; RunTransactionTest(cache.http_cache(), transaction); EXPECT_EQ(1, cache.network_layer()->transaction_count()); @@ -1653,7 +1667,7 @@ TEST(HttpCache, GET_Crazy206) { EXPECT_EQ(2, cache.network_layer()->transaction_count()); EXPECT_EQ(1, cache.disk_cache()->open_count()); EXPECT_EQ(1, cache.disk_cache()->create_count()); - RemoveMockTransaction(&kRangeGET_TransactionOK); + RemoveMockTransaction(&transaction); } TEST(HttpCache, DISABLED_RangeGET_OK) { @@ -1706,7 +1720,7 @@ TEST(HttpCache, DISABLED_RangeGET_OK) { RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); EXPECT_TRUE(Verify206Response(headers, 20, 59)); - EXPECT_EQ(6, cache.network_layer()->transaction_count()); + EXPECT_EQ(5, cache.network_layer()->transaction_count()); EXPECT_EQ(3, cache.disk_cache()->open_count()); EXPECT_EQ(1, cache.disk_cache()->create_count()); @@ -1742,7 +1756,7 @@ TEST(HttpCache, DISABLED_UnknownRangeGET_1) { RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); EXPECT_TRUE(Verify206Response(headers, 60, 79)); - EXPECT_EQ(3, cache.network_layer()->transaction_count()); + EXPECT_EQ(2, cache.network_layer()->transaction_count()); EXPECT_EQ(1, cache.disk_cache()->open_count()); EXPECT_EQ(1, cache.disk_cache()->create_count()); @@ -1751,15 +1765,19 @@ TEST(HttpCache, DISABLED_UnknownRangeGET_1) { TEST(HttpCache, DISABLED_UnknownRangeGET_2) { MockHttpCache cache; - AddMockTransaction(&kRangeGET_TransactionOK); // Test that we can cache range requests when the start or end is unknown. // We start with one request from a given point, followed by a suffix request. + // We'll also verify that synchronous cache responses work as intended. std::string headers; - // Write to the cache (70-79). MockTransaction transaction(kRangeGET_TransactionOK); + transaction.test_mode = TEST_MODE_SYNC_CACHE_START | + TEST_MODE_SYNC_CACHE_READ; + AddMockTransaction(&transaction); + + // Write to the cache (70-79). transaction.request_headers = "Range: bytes = 70-\r\n"; transaction.data = "rg: 70-79 "; RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); @@ -1778,6 +1796,38 @@ TEST(HttpCache, DISABLED_UnknownRangeGET_2) { RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); EXPECT_TRUE(Verify206Response(headers, 60, 79)); + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + RemoveMockTransaction(&transaction); +} + +TEST(HttpCache, DISABLED_GET_Previous206) { + MockHttpCache cache; + AddMockTransaction(&kRangeGET_TransactionOK); + + // Test that we can handle non-range requests when we have cached a range. + + std::string headers; + + // Write to the cache (40-49). + RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, + &headers); + + EXPECT_TRUE(Verify206Response(headers, 40, 49)); + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // Write and read from the cache (0-79), when not asked for a range. + MockTransaction transaction(kRangeGET_TransactionOK); + transaction.request_headers = ""; + transaction.data = "rg: 00-09 rg: 10-19 rg: 20-29 rg: 30-39 rg: 40-49 " + "rg: 50-59 rg: 60-69 rg: 70-79 "; + RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); + + EXPECT_EQ(0U, headers.find("HTTP/1.1 200 OK\n")); EXPECT_EQ(3, cache.network_layer()->transaction_count()); EXPECT_EQ(1, cache.disk_cache()->open_count()); EXPECT_EQ(1, cache.disk_cache()->create_count()); @@ -1785,6 +1835,130 @@ TEST(HttpCache, DISABLED_UnknownRangeGET_2) { RemoveMockTransaction(&kRangeGET_TransactionOK); } +TEST(HttpCache, DISABLED_GET_Previous206_NotSparse) { + MockHttpCache cache; + + // Test that we can handle cached 206 responses that are not sparse. + + // Create a disk cache entry that stores 206 headers while not being sparse. + disk_cache::Entry* entry; + ASSERT_TRUE(cache.disk_cache()->CreateEntry(kSimpleGET_Transaction.url, + &entry)); + + std::string raw_headers(kRangeGET_TransactionOK.status); + raw_headers.append("\n"); + raw_headers.append(kRangeGET_TransactionOK.response_headers); + raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), + raw_headers.size()); + + net::HttpResponseInfo response; + response.headers = new net::HttpResponseHeaders(raw_headers); + net::HttpCache::WriteResponseInfo(entry, &response, true); + + scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); + int len = static_cast<int>(base::strlcpy(buf->data(), + kRangeGET_TransactionOK.data, 500)); + EXPECT_EQ(len, entry->WriteData(1, 0, buf, len, NULL, true)); + entry->Close(); + + // Now see that we don't use the stored entry. + std::string headers; + RunTransactionTestWithResponse(cache.http_cache(), kSimpleGET_Transaction, + &headers); + + // We are expecting a 200. + std::string expected_headers(kSimpleGET_Transaction.status); + expected_headers.append("\n"); + expected_headers.append(kSimpleGET_Transaction.response_headers); + EXPECT_EQ(expected_headers, headers); + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(2, cache.disk_cache()->create_count()); +} + +TEST(HttpCache, DISABLED_GET_Previous206_NotSparse_2) { + MockHttpCache cache; + AddMockTransaction(&kRangeGET_TransactionOK); + + // Test that we can handle cached 206 responses that are not sparse. This time + // we issue a range request and expect to receive a range. + + // Create a disk cache entry that stores 206 headers while not being sparse. + disk_cache::Entry* entry; + ASSERT_TRUE(cache.disk_cache()->CreateEntry(kRangeGET_TransactionOK.url, + &entry)); + + std::string raw_headers(kRangeGET_TransactionOK.status); + raw_headers.append("\n"); + raw_headers.append(kRangeGET_TransactionOK.response_headers); + raw_headers = net::HttpUtil::AssembleRawHeaders(raw_headers.data(), + raw_headers.size()); + + net::HttpResponseInfo response; + response.headers = new net::HttpResponseHeaders(raw_headers); + net::HttpCache::WriteResponseInfo(entry, &response, true); + + scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(500)); + int len = static_cast<int>(base::strlcpy(buf->data(), + kRangeGET_TransactionOK.data, 500)); + EXPECT_EQ(len, entry->WriteData(1, 0, buf, len, NULL, true)); + entry->Close(); + + // Now see that we don't use the stored entry. + std::string headers; + RunTransactionTestWithResponse(cache.http_cache(), kRangeGET_TransactionOK, + &headers); + + // We are expecting a 206. + EXPECT_TRUE(Verify206Response(headers, 40, 49)); + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(2, cache.disk_cache()->create_count()); + + RemoveMockTransaction(&kRangeGET_TransactionOK); +} + +TEST(HttpCache, DISABLED_RangeRequestResultsIn200) { + MockHttpCache cache; + AddMockTransaction(&kRangeGET_TransactionOK); + + // Test that we can handle a 200 response when dealing with sparse entries. + + std::string headers; + + // Write to the cache (70-79). + MockTransaction transaction(kRangeGET_TransactionOK); + transaction.request_headers = "Range: bytes = -10\r\n"; + transaction.data = "rg: 70-79 "; + RunTransactionTestWithResponse(cache.http_cache(), transaction, &headers); + + EXPECT_TRUE(Verify206Response(headers, 70, 79)); + EXPECT_EQ(1, cache.network_layer()->transaction_count()); + EXPECT_EQ(0, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + // Now we'll issue a request that results in a plain 200 response, but to + // the to the same URL that we used to store sparse data, and making sure + // that we ask for a range. + RemoveMockTransaction(&kRangeGET_TransactionOK); + MockTransaction transaction2(kSimpleGET_Transaction); + transaction2.url = kRangeGET_TransactionOK.url; + transaction2.request_headers = kRangeGET_TransactionOK.request_headers; + AddMockTransaction(&transaction2); + + RunTransactionTestWithResponse(cache.http_cache(), transaction2, &headers); + + std::string expected_headers(kSimpleGET_Transaction.status); + expected_headers.append("\n"); + expected_headers.append(kSimpleGET_Transaction.response_headers); + EXPECT_EQ(expected_headers, headers); + EXPECT_EQ(2, cache.network_layer()->transaction_count()); + EXPECT_EQ(1, cache.disk_cache()->open_count()); + EXPECT_EQ(1, cache.disk_cache()->create_count()); + + RemoveMockTransaction(&transaction2); +} + TEST(HttpCache, SyncRead) { MockHttpCache cache; diff --git a/net/http/http_response_headers.cc b/net/http/http_response_headers.cc index f86eff8..9cbd72f 100644 --- a/net/http/http_response_headers.cc +++ b/net/http/http_response_headers.cc @@ -256,6 +256,15 @@ void HttpResponseHeaders::AddHeader(const std::string& header) { Parse(new_raw_headers); } +void HttpResponseHeaders::ReplaceStatusLine(const std::string& new_status) { + // Copy up to the null byte. This just copies the status line. + std::string new_raw_headers(new_status); + new_raw_headers.push_back('\0'); + + HeaderSet empty_to_remove; + MergeWithHeaders(new_raw_headers, empty_to_remove); +} + void HttpResponseHeaders::Parse(const std::string& raw_input) { raw_headers_.reserve(raw_input.size()); diff --git a/net/http/http_response_headers.h b/net/http/http_response_headers.h index 0552904..547370d 100644 --- a/net/http/http_response_headers.h +++ b/net/http/http_response_headers.h @@ -71,6 +71,10 @@ class HttpResponseHeaders : // end of the list. void AddHeader(const std::string& header); + // Replaces the current status line with the provided one (|new_status| should + // not have any EOL). + void ReplaceStatusLine(const std::string& new_status); + // Creates a normalized header string. The output will be formatted exactly // like so: // HTTP/<version> <status_code> <status_text>\n diff --git a/net/http/http_response_headers_unittest.cc b/net/http/http_response_headers_unittest.cc index ad03107..9f0cfde 100644 --- a/net/http/http_response_headers_unittest.cc +++ b/net/http/http_response_headers_unittest.cc @@ -1504,3 +1504,58 @@ TEST(HttpResponseHeadersTest, RemoveHeader) { EXPECT_EQ(string(tests[i].expected_headers), resulting_headers); } } + +TEST(HttpResponseHeadersTest, ReplaceStatus) { + const struct { + const char* orig_headers; + const char* new_status; + const char* expected_headers; + } tests[] = { + { "HTTP/1.1 206 Partial Content\n" + "connection: keep-alive\n" + "Cache-control: max-age=10000\n" + "Content-Length: 450\n", + + "HTTP/1.1 200 OK", + + "HTTP/1.1 200 OK\n" + "connection: keep-alive\n" + "Cache-control: max-age=10000\n" + "Content-Length: 450\n" + }, + { "HTTP/1.1 200 OK\n" + "connection: keep-alive\n", + + "HTTP/1.1 304 Not Modified", + + "HTTP/1.1 304 Not Modified\n" + "connection: keep-alive\n" + }, + { "HTTP/1.1 200 OK\n" + "connection: keep-alive \n" + "Content-Length : 450 \n" + "Cache-control: max-age=10000\n", + + "HTTP/1//1 304 Not Modified", + + "HTTP/1.0 304 Not Modified\n" + "connection: keep-alive\n" + "Content-Length: 450\n" + "Cache-control: max-age=10000\n" + }, + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) { + string orig_headers(tests[i].orig_headers); + HeadersToRaw(&orig_headers); + scoped_refptr<HttpResponseHeaders> parsed = + new HttpResponseHeaders(orig_headers); + + string name(tests[i].new_status); + parsed->ReplaceStatusLine(name); + + string resulting_headers; + parsed->GetNormalizedHeaders(&resulting_headers); + EXPECT_EQ(string(tests[i].expected_headers), resulting_headers); + } +} diff --git a/net/http/partial_data.cc b/net/http/partial_data.cc index 8d56966..a4d5976 100644 --- a/net/http/partial_data.cc +++ b/net/http/partial_data.cc @@ -53,7 +53,7 @@ int PartialData::PrepareCacheValidation(disk_cache::Entry* entry, // Scan the disk cache for the first cached portion within this range. int64 range_len = byte_range_.HasLastBytePosition() ? - byte_range_.last_byte_position() - current_range_start_ + 1: kint32max; + byte_range_.last_byte_position() - current_range_start_ + 1 : kint32max; if (range_len > kint32max) range_len = kint32max; int len = static_cast<int32>(range_len); @@ -100,20 +100,32 @@ bool PartialData::IsLastRange() const { return final_range_; } -bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers) { +bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers, + disk_cache::Entry* entry) { std::string length_value; resource_size_ = 0; if (!headers->GetNormalizedHeader(kLengthHeader, &length_value)) return false; // We must have stored the resource length. - if (!StringToInt64(length_value, &resource_size_)) + if (!StringToInt64(length_value, &resource_size_) || !resource_size_) return false; - if (resource_size_ && !byte_range_.ComputeBounds(resource_size_)) - return false; + if (byte_range_.IsValid()) { + if (!byte_range_.ComputeBounds(resource_size_)) + return false; + + if (current_range_start_ < 0) + current_range_start_ = byte_range_.first_byte_position(); + } else { + // This is not a range request but we have partial data stored. + current_range_start_ = 0; + byte_range_.set_last_byte_position(resource_size_ - 1); + } - if (current_range_start_ < 0) - current_range_start_ = byte_range_.first_byte_position(); + // Make sure that this is really a sparse entry. + int64 n; + if (ERR_CACHE_OPERATION_NOT_SUPPORTED == entry->GetAvailableRange(0, 5, &n)) + return false; return current_range_start_ >= 0; } @@ -141,7 +153,7 @@ bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { if (start != current_range_start_) return false; - if (end > byte_range_.last_byte_position()) + if (byte_range_.IsValid() && end > byte_range_.last_byte_position()) return false; return true; @@ -154,15 +166,23 @@ void PartialData::FixResponseHeaders(HttpResponseHeaders* headers) { headers->RemoveHeader(kLengthHeader); headers->RemoveHeader(kRangeHeader); - DCHECK(byte_range_.HasFirstBytePosition()); - DCHECK(byte_range_.HasLastBytePosition()); - headers->AddHeader(StringPrintf("%s: bytes %lld-%lld/%lld", kRangeHeader, - byte_range_.first_byte_position(), - byte_range_.last_byte_position(), - resource_size_)); + int64 range_len; + if (byte_range_.IsValid()) { + DCHECK(byte_range_.HasFirstBytePosition()); + DCHECK(byte_range_.HasLastBytePosition()); + headers->AddHeader(StringPrintf("%s: bytes %lld-%lld/%lld", kRangeHeader, + byte_range_.first_byte_position(), + byte_range_.last_byte_position(), + resource_size_)); + range_len = byte_range_.last_byte_position() - + byte_range_.first_byte_position() + 1; + } else { + // TODO(rvargas): Is it safe to change the protocol version? + headers->ReplaceStatusLine("HTTP/1.1 200 OK"); + DCHECK_NE(resource_size_, 0); + range_len = resource_size_; + } - int64 range_len = byte_range_.last_byte_position() - - byte_range_.first_byte_position() + 1; headers->AddHeader(StringPrintf("%s: %lld", kLengthHeader, range_len)); } @@ -214,5 +234,4 @@ void PartialData::AddRangeHeader(int64 start, int64 end, std::string* headers) { my_end.c_str())); } - } // namespace net diff --git a/net/http/partial_data.h b/net/http/partial_data.h index 8c3471d..ade720d 100644 --- a/net/http/partial_data.h +++ b/net/http/partial_data.h @@ -62,7 +62,8 @@ class PartialData { // Extracts info from headers already stored in the cache. Returns false if // there is any problem with the headers or the requested range. - bool UpdateFromStoredHeaders(const HttpResponseHeaders* headers); + bool UpdateFromStoredHeaders(const HttpResponseHeaders* headers, + disk_cache::Entry* entry); // Returns true if the response headers match what we expect, false otherwise. bool ResponseHeadersOK(const HttpResponseHeaders* headers); |