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 |