OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 #include "net/base/net_errors.h" | 14 #include "net/base/net_errors.h" |
15 #include "net/disk_cache/disk_cache.h" | 15 #include "net/disk_cache/disk_cache.h" |
16 #include "net/http/http_response_headers.h" | 16 #include "net/http/http_response_headers.h" |
17 #include "net/http/http_util.h" | 17 #include "net/http/http_util.h" |
18 | 18 |
19 namespace net { | 19 namespace net { |
20 | 20 |
21 namespace { | 21 namespace { |
22 | 22 |
23 // The headers that we have to process. | 23 // The headers that we have to process. |
24 const char kLengthHeader[] = "Content-Length"; | 24 const char kLengthHeader[] = "Content-Length"; |
25 const char kRangeHeader[] = "Content-Range"; | 25 const char kRangeHeader[] = "Content-Range"; |
26 const int kDataStream = 1; | 26 const int kDataStream = 1; |
27 | 27 |
28 void AddRangeHeader(int64 start, int64 end, HttpRequestHeaders* headers) { | |
29 DCHECK(start >= 0 || end >= 0); | |
30 std::string my_start, my_end; | |
31 if (start >= 0) | |
32 my_start = base::Int64ToString(start); | |
33 if (end >= 0) | |
34 my_end = base::Int64ToString(end); | |
35 | |
36 headers->SetHeader( | |
37 HttpRequestHeaders::kRange, | |
38 base::StringPrintf("bytes=%s-%s", my_start.c_str(), my_end.c_str())); | |
39 } | |
40 | |
41 } // namespace | 28 } // namespace |
42 | 29 |
43 // A core object that can be detached from the Partialdata object at destruction | 30 // A core object that can be detached from the Partialdata object at destruction |
44 // so that asynchronous operations cleanup can be performed. | 31 // so that asynchronous operations cleanup can be performed. |
45 class PartialData::Core { | 32 class PartialData::Core { |
46 public: | 33 public: |
47 // Build a new core object. Lifetime management is automatic. | 34 // Build a new core object. Lifetime management is automatic. |
48 static Core* CreateCore(PartialData* owner) { | 35 static Core* CreateCore(PartialData* owner) { |
49 return new Core(owner); | 36 return new Core(owner); |
50 } | 37 } |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 DCHECK(extra_headers_.IsEmpty()); | 136 DCHECK(extra_headers_.IsEmpty()); |
150 extra_headers_.CopyFrom(headers); | 137 extra_headers_.CopyFrom(headers); |
151 } | 138 } |
152 | 139 |
153 void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const { | 140 void PartialData::RestoreHeaders(HttpRequestHeaders* headers) const { |
154 DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange()); | 141 DCHECK(current_range_start_ >= 0 || byte_range_.IsSuffixByteRange()); |
155 int64 end = byte_range_.IsSuffixByteRange() ? | 142 int64 end = byte_range_.IsSuffixByteRange() ? |
156 byte_range_.suffix_length() : byte_range_.last_byte_position(); | 143 byte_range_.suffix_length() : byte_range_.last_byte_position(); |
157 | 144 |
158 headers->CopyFrom(extra_headers_); | 145 headers->CopyFrom(extra_headers_); |
159 if (!truncated_ && byte_range_.IsValid()) | 146 if (truncated_ || !byte_range_.IsValid()) |
160 AddRangeHeader(current_range_start_, end, headers); | 147 return; |
| 148 |
| 149 if (current_range_start_ < 0) { |
| 150 headers->SetHeader(HttpRequestHeaders::kRange, |
| 151 HttpByteRange::Suffix(end).GetHeaderValue()); |
| 152 } else { |
| 153 headers->SetHeader(HttpRequestHeaders::kRange, |
| 154 HttpByteRange::Bounded( |
| 155 current_range_start_, end).GetHeaderValue()); |
| 156 } |
161 } | 157 } |
162 | 158 |
163 int PartialData::ShouldValidateCache(disk_cache::Entry* entry, | 159 int PartialData::ShouldValidateCache(disk_cache::Entry* entry, |
164 const CompletionCallback& callback) { | 160 const CompletionCallback& callback) { |
165 DCHECK_GE(current_range_start_, 0); | 161 DCHECK_GE(current_range_start_, 0); |
166 | 162 |
167 // Scan the disk cache for the first cached portion within this range. | 163 // Scan the disk cache for the first cached portion within this range. |
168 int len = GetNextRangeLen(); | 164 int len = GetNextRangeLen(); |
169 if (!len) | 165 if (!len) |
170 return 0; | 166 return 0; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 final_range_ = true; | 211 final_range_ = true; |
216 cached_start_ = | 212 cached_start_ = |
217 byte_range_.HasLastBytePosition() ? current_range_start_ + len : 0; | 213 byte_range_.HasLastBytePosition() ? current_range_start_ + len : 0; |
218 } | 214 } |
219 | 215 |
220 if (current_range_start_ == cached_start_) { | 216 if (current_range_start_ == cached_start_) { |
221 // The data lives in the cache. | 217 // The data lives in the cache. |
222 range_present_ = true; | 218 range_present_ = true; |
223 if (len == cached_min_len_) | 219 if (len == cached_min_len_) |
224 final_range_ = true; | 220 final_range_ = true; |
225 AddRangeHeader(current_range_start_, cached_start_ + cached_min_len_ - 1, | 221 headers->SetHeader( |
226 headers); | 222 HttpRequestHeaders::kRange, |
| 223 net::HttpByteRange::Bounded( |
| 224 current_range_start_, |
| 225 cached_start_ + cached_min_len_ - 1).GetHeaderValue()); |
227 } else { | 226 } else { |
228 // This range is not in the cache. | 227 // This range is not in the cache. |
229 AddRangeHeader(current_range_start_, cached_start_ - 1, headers); | 228 headers->SetHeader( |
| 229 HttpRequestHeaders::kRange, |
| 230 net::HttpByteRange::Bounded( |
| 231 current_range_start_, cached_start_ - 1).GetHeaderValue()); |
230 } | 232 } |
231 } | 233 } |
232 | 234 |
233 bool PartialData::IsCurrentRangeCached() const { | 235 bool PartialData::IsCurrentRangeCached() const { |
234 return range_present_; | 236 return range_present_; |
235 } | 237 } |
236 | 238 |
237 bool PartialData::IsLastRange() const { | 239 bool PartialData::IsLastRange() const { |
238 return final_range_; | 240 return final_range_; |
239 } | 241 } |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
491 cached_min_len_ = result; | 493 cached_min_len_ = result; |
492 if (result >= 0) | 494 if (result >= 0) |
493 result = 1; // Return success, go ahead and validate the entry. | 495 result = 1; // Return success, go ahead and validate the entry. |
494 | 496 |
495 CompletionCallback cb = callback_; | 497 CompletionCallback cb = callback_; |
496 callback_.Reset(); | 498 callback_.Reset(); |
497 cb.Run(result); | 499 cb.Run(result); |
498 } | 500 } |
499 | 501 |
500 } // namespace net | 502 } // namespace net |
OLD | NEW |