| 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 // 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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 return !ranges->empty(); | 264 return !ranges->empty(); |
| 265 } | 265 } |
| 266 | 266 |
| 267 // static | 267 // static |
| 268 // From RFC 2616 14.16: | 268 // From RFC 2616 14.16: |
| 269 // content-range-spec = | 269 // content-range-spec = |
| 270 // bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" ) | 270 // bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" ) |
| 271 // byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*" | 271 // byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*" |
| 272 // instance-length = 1*DIGIT | 272 // instance-length = 1*DIGIT |
| 273 // bytes-unit = "bytes" | 273 // bytes-unit = "bytes" |
| 274 bool HttpUtil::ParseContentRangeHeader(base::StringPiece content_range_spec, | 274 bool HttpUtil::ParseContentRangeHeaderFor206( |
| 275 int64_t* first_byte_position, | 275 base::StringPiece content_range_spec, |
| 276 int64_t* last_byte_position, | 276 int64_t* first_byte_position, |
| 277 int64_t* instance_length) { | 277 int64_t* last_byte_position, |
| 278 int64_t* instance_length) { |
| 278 *first_byte_position = *last_byte_position = *instance_length = -1; | 279 *first_byte_position = *last_byte_position = *instance_length = -1; |
| 279 content_range_spec = TrimLWS(content_range_spec); | 280 content_range_spec = TrimLWS(content_range_spec); |
| 280 | 281 |
| 281 size_t space_position = content_range_spec.find(' '); | 282 size_t space_position = content_range_spec.find(' '); |
| 282 if (space_position == base::StringPiece::npos) | 283 if (space_position == base::StringPiece::npos) |
| 283 return false; | 284 return false; |
| 284 | 285 |
| 285 // Invalid header if it doesn't contain "bytes-unit". | 286 // Invalid header if it doesn't contain "bytes-unit". |
| 286 if (!base::LowerCaseEqualsASCII( | 287 if (!base::LowerCaseEqualsASCII( |
| 287 TrimLWS(content_range_spec.substr(0, space_position)), "bytes")) { | 288 TrimLWS(content_range_spec.substr(0, space_position)), "bytes")) { |
| 288 return false; | 289 return false; |
| 289 } | 290 } |
| 290 | 291 |
| 291 size_t slash_position = content_range_spec.find('/', space_position + 1); | 292 size_t minus_position = content_range_spec.find('-', space_position + 1); |
| 293 if (minus_position == base::StringPiece::npos) |
| 294 return false; |
| 295 size_t slash_position = content_range_spec.find('/', minus_position + 1); |
| 292 if (slash_position == base::StringPiece::npos) | 296 if (slash_position == base::StringPiece::npos) |
| 293 return false; | 297 return false; |
| 294 | 298 |
| 295 // Obtain the part behind the space and before slash. | 299 if (base::StringToInt64( |
| 296 base::StringPiece byte_range_resp_spec = TrimLWS(content_range_spec.substr( | 300 TrimLWS(content_range_spec.substr( |
| 297 space_position + 1, slash_position - (space_position + 1))); | 301 space_position + 1, minus_position - (space_position + 1))), |
| 298 | 302 first_byte_position) && |
| 299 if (byte_range_resp_spec != "*") { | 303 *first_byte_position >= 0 && |
| 300 size_t minus_position = byte_range_resp_spec.find('-'); | 304 base::StringToInt64( |
| 301 if (minus_position == base::StringPiece::npos) | 305 TrimLWS(content_range_spec.substr( |
| 302 return false; | 306 minus_position + 1, slash_position - (minus_position + 1))), |
| 303 | 307 last_byte_position) && |
| 304 // Obtain first-byte-pos and last-byte-pos. | 308 *last_byte_position >= *first_byte_position && |
| 305 if (!base::StringToInt64( | 309 base::StringToInt64( |
| 306 TrimLWS(byte_range_resp_spec.substr(0, minus_position)), | 310 TrimLWS(content_range_spec.substr(slash_position + 1)), |
| 307 first_byte_position) || | 311 instance_length) && |
| 308 !base::StringToInt64( | 312 *instance_length > *last_byte_position) { |
| 309 TrimLWS(byte_range_resp_spec.substr(minus_position + 1)), | 313 return true; |
| 310 last_byte_position)) { | |
| 311 *first_byte_position = *last_byte_position = -1; | |
| 312 return false; | |
| 313 } | |
| 314 if (*first_byte_position < 0 || *last_byte_position < 0 || | |
| 315 *first_byte_position > *last_byte_position) | |
| 316 return false; | |
| 317 } | 314 } |
| 318 | 315 *first_byte_position = *last_byte_position = *instance_length = -1; |
| 319 // Parse the instance-length part. | 316 return false; |
| 320 base::StringPiece instance_length_spec = | |
| 321 TrimLWS(content_range_spec.substr(slash_position + 1)); | |
| 322 | |
| 323 if (base::StartsWith(instance_length_spec, "*", | |
| 324 base::CompareCase::SENSITIVE)) { | |
| 325 return false; | |
| 326 } else if (!base::StringToInt64(instance_length_spec, instance_length)) { | |
| 327 *instance_length = -1; | |
| 328 return false; | |
| 329 } | |
| 330 | |
| 331 // We have all the values; let's verify that they make sense for a 206 | |
| 332 // response. | |
| 333 if (*first_byte_position < 0 || *last_byte_position < 0 || | |
| 334 *instance_length < 0 || *instance_length - 1 < *last_byte_position) | |
| 335 return false; | |
| 336 | |
| 337 return true; | |
| 338 } | 317 } |
| 339 | 318 |
| 340 // static | 319 // static |
| 341 bool HttpUtil::ParseRetryAfterHeader(const std::string& retry_after_string, | 320 bool HttpUtil::ParseRetryAfterHeader(const std::string& retry_after_string, |
| 342 base::Time now, | 321 base::Time now, |
| 343 base::TimeDelta* retry_after) { | 322 base::TimeDelta* retry_after) { |
| 344 int seconds; | 323 int seconds; |
| 345 base::Time time; | 324 base::Time time; |
| 346 base::TimeDelta interval; | 325 base::TimeDelta interval; |
| 347 | 326 |
| (...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 return true; | 1126 return true; |
| 1148 } | 1127 } |
| 1149 | 1128 |
| 1150 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const { | 1129 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const { |
| 1151 if (strict_quotes_) | 1130 if (strict_quotes_) |
| 1152 return c == '"'; | 1131 return c == '"'; |
| 1153 return HttpUtil::IsQuote(c); | 1132 return HttpUtil::IsQuote(c); |
| 1154 } | 1133 } |
| 1155 | 1134 |
| 1156 } // namespace net | 1135 } // namespace net |
| OLD | NEW |