| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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/partial_data.h" | 5 #include "net/http/partial_data.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 #include "net/disk_cache/disk_cache.h" | 10 #include "net/disk_cache/disk_cache.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 | 46 |
| 47 AddRangeHeader(current_range_start_, end, headers); | 47 AddRangeHeader(current_range_start_, end, headers); |
| 48 } | 48 } |
| 49 | 49 |
| 50 int PartialData::PrepareCacheValidation(disk_cache::Entry* entry, | 50 int PartialData::PrepareCacheValidation(disk_cache::Entry* entry, |
| 51 std::string* headers) { | 51 std::string* headers) { |
| 52 DCHECK(current_range_start_ >= 0); | 52 DCHECK(current_range_start_ >= 0); |
| 53 | 53 |
| 54 // Scan the disk cache for the first cached portion within this range. | 54 // Scan the disk cache for the first cached portion within this range. |
| 55 int64 range_len = byte_range_.HasLastBytePosition() ? | 55 int64 range_len = byte_range_.HasLastBytePosition() ? |
| 56 byte_range_.last_byte_position() - current_range_start_ + 1: kint32max; | 56 byte_range_.last_byte_position() - current_range_start_ + 1 : kint32max; |
| 57 if (range_len > kint32max) | 57 if (range_len > kint32max) |
| 58 range_len = kint32max; | 58 range_len = kint32max; |
| 59 int len = static_cast<int32>(range_len); | 59 int len = static_cast<int32>(range_len); |
| 60 if (!len) | 60 if (!len) |
| 61 return 0; | 61 return 0; |
| 62 range_present_ = false; | 62 range_present_ = false; |
| 63 | 63 |
| 64 cached_min_len_ = entry->GetAvailableRange(current_range_start_, len, | 64 cached_min_len_ = entry->GetAvailableRange(current_range_start_, len, |
| 65 &cached_start_); | 65 &cached_start_); |
| 66 if (cached_min_len_ < 0) { | 66 if (cached_min_len_ < 0) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 93 } | 93 } |
| 94 | 94 |
| 95 bool PartialData::IsCurrentRangeCached() const { | 95 bool PartialData::IsCurrentRangeCached() const { |
| 96 return range_present_; | 96 return range_present_; |
| 97 } | 97 } |
| 98 | 98 |
| 99 bool PartialData::IsLastRange() const { | 99 bool PartialData::IsLastRange() const { |
| 100 return final_range_; | 100 return final_range_; |
| 101 } | 101 } |
| 102 | 102 |
| 103 bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers) { | 103 bool PartialData::UpdateFromStoredHeaders(const HttpResponseHeaders* headers, |
| 104 disk_cache::Entry* entry) { |
| 104 std::string length_value; | 105 std::string length_value; |
| 105 resource_size_ = 0; | 106 resource_size_ = 0; |
| 106 if (!headers->GetNormalizedHeader(kLengthHeader, &length_value)) | 107 if (!headers->GetNormalizedHeader(kLengthHeader, &length_value)) |
| 107 return false; // We must have stored the resource length. | 108 return false; // We must have stored the resource length. |
| 108 | 109 |
| 109 if (!StringToInt64(length_value, &resource_size_)) | 110 if (!StringToInt64(length_value, &resource_size_) || !resource_size_) |
| 110 return false; | 111 return false; |
| 111 | 112 |
| 112 if (resource_size_ && !byte_range_.ComputeBounds(resource_size_)) | 113 if (byte_range_.IsValid()) { |
| 114 if (!byte_range_.ComputeBounds(resource_size_)) |
| 115 return false; |
| 116 |
| 117 if (current_range_start_ < 0) |
| 118 current_range_start_ = byte_range_.first_byte_position(); |
| 119 } else { |
| 120 // This is not a range request but we have partial data stored. |
| 121 current_range_start_ = 0; |
| 122 byte_range_.set_last_byte_position(resource_size_ - 1); |
| 123 } |
| 124 |
| 125 // Make sure that this is really a sparse entry. |
| 126 int64 n; |
| 127 if (ERR_CACHE_OPERATION_NOT_SUPPORTED == entry->GetAvailableRange(0, 5, &n)) |
| 113 return false; | 128 return false; |
| 114 | 129 |
| 115 if (current_range_start_ < 0) | |
| 116 current_range_start_ = byte_range_.first_byte_position(); | |
| 117 | |
| 118 return current_range_start_ >= 0; | 130 return current_range_start_ >= 0; |
| 119 } | 131 } |
| 120 | 132 |
| 121 bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { | 133 bool PartialData::ResponseHeadersOK(const HttpResponseHeaders* headers) { |
| 122 int64 start, end, total_length; | 134 int64 start, end, total_length; |
| 123 if (!headers->GetContentRange(&start, &end, &total_length)) | 135 if (!headers->GetContentRange(&start, &end, &total_length)) |
| 124 return false; | 136 return false; |
| 125 if (total_length <= 0) | 137 if (total_length <= 0) |
| 126 return false; | 138 return false; |
| 127 | 139 |
| 128 if (!resource_size_) { | 140 if (!resource_size_) { |
| 129 // First response. Update our values with the ones provided by the server. | 141 // First response. Update our values with the ones provided by the server. |
| 130 resource_size_ = total_length; | 142 resource_size_ = total_length; |
| 131 if (!byte_range_.HasFirstBytePosition()) { | 143 if (!byte_range_.HasFirstBytePosition()) { |
| 132 byte_range_.set_first_byte_position(start); | 144 byte_range_.set_first_byte_position(start); |
| 133 current_range_start_ = start; | 145 current_range_start_ = start; |
| 134 } | 146 } |
| 135 if (!byte_range_.HasLastBytePosition()) | 147 if (!byte_range_.HasLastBytePosition()) |
| 136 byte_range_.set_last_byte_position(end); | 148 byte_range_.set_last_byte_position(end); |
| 137 } else if (resource_size_ != total_length) { | 149 } else if (resource_size_ != total_length) { |
| 138 return false; | 150 return false; |
| 139 } | 151 } |
| 140 | 152 |
| 141 if (start != current_range_start_) | 153 if (start != current_range_start_) |
| 142 return false; | 154 return false; |
| 143 | 155 |
| 144 if (end > byte_range_.last_byte_position()) | 156 if (byte_range_.IsValid() && end > byte_range_.last_byte_position()) |
| 145 return false; | 157 return false; |
| 146 | 158 |
| 147 return true; | 159 return true; |
| 148 } | 160 } |
| 149 | 161 |
| 150 // We are making multiple requests to complete the range requested by the user. | 162 // We are making multiple requests to complete the range requested by the user. |
| 151 // Just assume that everything is fine and say that we are returning what was | 163 // Just assume that everything is fine and say that we are returning what was |
| 152 // requested. | 164 // requested. |
| 153 void PartialData::FixResponseHeaders(HttpResponseHeaders* headers) { | 165 void PartialData::FixResponseHeaders(HttpResponseHeaders* headers) { |
| 154 headers->RemoveHeader(kLengthHeader); | 166 headers->RemoveHeader(kLengthHeader); |
| 155 headers->RemoveHeader(kRangeHeader); | 167 headers->RemoveHeader(kRangeHeader); |
| 156 | 168 |
| 157 DCHECK(byte_range_.HasFirstBytePosition()); | 169 int64 range_len; |
| 158 DCHECK(byte_range_.HasLastBytePosition()); | 170 if (byte_range_.IsValid()) { |
| 159 headers->AddHeader(StringPrintf("%s: bytes %lld-%lld/%lld", kRangeHeader, | 171 DCHECK(byte_range_.HasFirstBytePosition()); |
| 160 byte_range_.first_byte_position(), | 172 DCHECK(byte_range_.HasLastBytePosition()); |
| 161 byte_range_.last_byte_position(), | 173 headers->AddHeader(StringPrintf("%s: bytes %lld-%lld/%lld", kRangeHeader, |
| 162 resource_size_)); | 174 byte_range_.first_byte_position(), |
| 175 byte_range_.last_byte_position(), |
| 176 resource_size_)); |
| 177 range_len = byte_range_.last_byte_position() - |
| 178 byte_range_.first_byte_position() + 1; |
| 179 } else { |
| 180 // TODO(rvargas): Is it safe to change the protocol version? |
| 181 headers->ReplaceStatusLine("HTTP/1.1 200 OK"); |
| 182 DCHECK_NE(resource_size_, 0); |
| 183 range_len = resource_size_; |
| 184 } |
| 163 | 185 |
| 164 int64 range_len = byte_range_.last_byte_position() - | |
| 165 byte_range_.first_byte_position() + 1; | |
| 166 headers->AddHeader(StringPrintf("%s: %lld", kLengthHeader, range_len)); | 186 headers->AddHeader(StringPrintf("%s: %lld", kLengthHeader, range_len)); |
| 167 } | 187 } |
| 168 | 188 |
| 169 void PartialData::FixContentLength(HttpResponseHeaders* headers) { | 189 void PartialData::FixContentLength(HttpResponseHeaders* headers) { |
| 170 headers->RemoveHeader(kLengthHeader); | 190 headers->RemoveHeader(kLengthHeader); |
| 171 headers->AddHeader(StringPrintf("%s: %lld", kLengthHeader, resource_size_)); | 191 headers->AddHeader(StringPrintf("%s: %lld", kLengthHeader, resource_size_)); |
| 172 } | 192 } |
| 173 | 193 |
| 174 int PartialData::CacheRead(disk_cache::Entry* entry, IOBuffer* data, | 194 int PartialData::CacheRead(disk_cache::Entry* entry, IOBuffer* data, |
| 175 int data_len, CompletionCallback* callback) { | 195 int data_len, CompletionCallback* callback) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 std::string my_start, my_end; | 227 std::string my_start, my_end; |
| 208 if (start >= 0) | 228 if (start >= 0) |
| 209 my_start = Int64ToString(start); | 229 my_start = Int64ToString(start); |
| 210 if (end >= 0) | 230 if (end >= 0) |
| 211 my_end = Int64ToString(end); | 231 my_end = Int64ToString(end); |
| 212 | 232 |
| 213 headers->append(StringPrintf("Range: bytes=%s-%s\r\n", my_start.c_str(), | 233 headers->append(StringPrintf("Range: bytes=%s-%s\r\n", my_start.c_str(), |
| 214 my_end.c_str())); | 234 my_end.c_str())); |
| 215 } | 235 } |
| 216 | 236 |
| 217 | |
| 218 } // namespace net | 237 } // namespace net |
| OLD | NEW |