Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(358)

Side by Side Diff: net/http/http_util.cc

Issue 92006: Implement a parser that parses the "Range" HTTP header... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_util.h ('k') | net/http/http_util_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 // The rules for parsing content-types were borrowed from Firefox: 5 // The rules for parsing content-types were borrowed from Firefox:
6 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834 6 // http://lxr.mozilla.org/mozilla/source/netwerk/base/src/nsURLHelper.cpp#834
7 7
8 #include "net/http/http_util.h" 8 #include "net/http/http_util.h"
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 if ((!eq && *had_charset) || type_has_charset) { 188 if ((!eq && *had_charset) || type_has_charset) {
189 *had_charset = true; 189 *had_charset = true;
190 charset->assign(content_type_str.begin() + charset_val, 190 charset->assign(content_type_str.begin() + charset_val,
191 content_type_str.begin() + charset_end); 191 content_type_str.begin() + charset_end);
192 StringToLowerASCII(charset); 192 StringToLowerASCII(charset);
193 } 193 }
194 } 194 }
195 } 195 }
196 196
197 // static 197 // static
198 // Parse the Range header according to RFC 2616 14.35.1
199 // ranges-specifier = byte-ranges-specifier
200 // byte-ranges-specifier = bytes-unit "=" byte-range-set
201 // byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )
202 // byte-range-spec = first-byte-pos "-" [last-byte-pos]
203 // first-byte-pos = 1*DIGIT
204 // last-byte-pos = 1*DIGIT
205 bool HttpUtil::ParseRanges(const std::string& headers,
206 std::vector<HttpByteRange>* ranges) {
207 std::string ranges_specifier;
208 HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n");
209
210 while (it.GetNext()) {
211 // Look for "Range" header.
212 if (!LowerCaseEqualsASCII(it.name(), "range"))
213 continue;
214 ranges_specifier = it.values();
215 // We just care about the first "Range" header, so break here.
216 break;
217 }
218
219 if (ranges_specifier.empty())
220 return false;
221
222 size_t equal_char_offset = ranges_specifier.find('=');
223 if (equal_char_offset == std::string::npos)
224 return false;
225
226 // Try to extract bytes-unit part.
227 std::string::const_iterator bytes_unit_begin = ranges_specifier.begin();
228 std::string::const_iterator bytes_unit_end = bytes_unit_begin +
229 equal_char_offset;
230 std::string::const_iterator byte_range_set_begin = bytes_unit_end + 1;
231 std::string::const_iterator byte_range_set_end = ranges_specifier.end();
232
233 TrimLWS(&bytes_unit_begin, &bytes_unit_end);
234 // "bytes" unit identifier is not found.
235 if (!LowerCaseEqualsASCII(bytes_unit_begin, bytes_unit_end, "bytes"))
236 return false;
237
238 ValuesIterator byte_range_set_iterator(byte_range_set_begin,
239 byte_range_set_end, ',');
240 while (byte_range_set_iterator.GetNext()) {
241 size_t minus_char_offset = byte_range_set_iterator.value().find('-');
242 // If '-' character is not found, reports failure.
243 if (minus_char_offset == std::string::npos)
244 return false;
245
246 std::string::const_iterator first_byte_pos_begin =
247 byte_range_set_iterator.value_begin();
248 std::string::const_iterator first_byte_pos_end =
249 first_byte_pos_begin + minus_char_offset;
250 TrimLWS(&first_byte_pos_begin, &first_byte_pos_end);
251 std::string first_byte_pos(first_byte_pos_begin, first_byte_pos_end);
252
253 HttpByteRange range;
254 // Try to obtain first-byte-pos.
255 if (!first_byte_pos.empty()) {
256 int64 first_byte_position = -1;
257 if (!StringToInt64(first_byte_pos, &first_byte_position))
258 return false;
259 range.set_first_byte_position(first_byte_position);
260 }
261
262 std::string::const_iterator last_byte_pos_begin =
263 byte_range_set_iterator.value_begin() + minus_char_offset + 1;
264 std::string::const_iterator last_byte_pos_end =
265 byte_range_set_iterator.value_end();
266 TrimLWS(&last_byte_pos_begin, &last_byte_pos_end);
267 std::string last_byte_pos(last_byte_pos_begin, last_byte_pos_end);
268
269 // We have last-byte-pos or suffix-byte-range-spec in this case.
270 if (!last_byte_pos.empty()) {
271 int64 last_byte_position;
272 if (!StringToInt64(last_byte_pos, &last_byte_position))
273 return false;
274 if (range.HasFirstBytePosition())
275 range.set_last_byte_position(last_byte_position);
276 else
277 range.set_suffix_length(last_byte_position);
278 } else if (!range.HasFirstBytePosition()) {
279 return false;
280 }
281
282 // Do a final check on the HttpByteRange object.
283 if (!range.IsValid())
284 return false;
285 ranges->push_back(range);
286 }
287 return ranges->size() > 0;
288 }
289
290 // static
198 bool HttpUtil::HasHeader(const std::string& headers, const char* name) { 291 bool HttpUtil::HasHeader(const std::string& headers, const char* name) {
199 size_t name_len = strlen(name); 292 size_t name_len = strlen(name);
200 string::const_iterator it = 293 string::const_iterator it =
201 std::search(headers.begin(), 294 std::search(headers.begin(),
202 headers.end(), 295 headers.end(),
203 name, 296 name,
204 name + name_len, 297 name + name_len,
205 CaseInsensitiveCompareASCII<char>()); 298 CaseInsensitiveCompareASCII<char>());
206 if (it == headers.end()) 299 if (it == headers.end())
207 return false; 300 return false;
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 TrimLWS(&value_begin_, &value_end_); 674 TrimLWS(&value_begin_, &value_end_);
582 675
583 // bypass empty values. 676 // bypass empty values.
584 if (value_begin_ != value_end_) 677 if (value_begin_ != value_end_)
585 return true; 678 return true;
586 } 679 }
587 return false; 680 return false;
588 } 681 }
589 682
590 } // namespace net 683 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_util.h ('k') | net/http/http_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698