Chromium Code Reviews| Index: net/http/http_util.cc |
| diff --git a/net/http/http_util.cc b/net/http/http_util.cc |
| index 99b7192c838d500ce2bec2b783834f0bb94dfd22..24066ef94c5e6770ef84ae0fe1d0deef1a604786 100644 |
| --- a/net/http/http_util.cc |
| +++ b/net/http/http_util.cc |
| @@ -265,6 +265,79 @@ bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier, |
| } |
| // static |
| +// From RFC 2616 14.16: |
| +// content-range-spec = |
| +// bytes-unit SP byte-range-resp-spec "/" ( instance-length | "*" ) |
| +// byte-range-resp-spec = (first-byte-pos "-" last-byte-pos) | "*" |
| +// instance-length = 1*DIGIT |
| +// bytes-unit = "bytes" |
| +bool HttpUtil::ParseContentRangeHeader(base::StringPiece content_range_spec, |
| + int64_t* first_byte_position, |
| + int64_t* last_byte_position, |
| + int64_t* instance_length) { |
| + *first_byte_position = *last_byte_position = *instance_length = -1; |
| + content_range_spec = TrimLWS(content_range_spec); |
| + |
| + size_t space_position = content_range_spec.find(' '); |
| + if (space_position == base::StringPiece::npos) |
| + return false; |
| + |
| + // Invalid header if it doesn't contain "bytes-unit". |
| + if (!base::LowerCaseEqualsASCII( |
| + TrimLWS(content_range_spec.substr(0, space_position)), "bytes")) { |
| + return false; |
| + } |
| + |
| + size_t slash_position = content_range_spec.find('/', space_position + 1); |
| + if (slash_position == base::StringPiece::npos) |
| + return false; |
| + |
| + // Obtain the part behind the space and before slash. |
| + base::StringPiece byte_range_resp_spec = TrimLWS(content_range_spec.substr( |
| + space_position + 1, slash_position - (space_position + 1))); |
| + |
| + if (byte_range_resp_spec != "*") { |
| + size_t minus_position = byte_range_resp_spec.find('-'); |
| + if (minus_position == base::StringPiece::npos) |
| + return false; |
| + |
| + // Obtain first-byte-pos and last-byte-pos. |
| + if (!base::StringToInt64( |
| + TrimLWS(byte_range_resp_spec.substr(0, minus_position)), |
| + first_byte_position) || |
| + !base::StringToInt64( |
| + TrimLWS(byte_range_resp_spec.substr(minus_position + 1)), |
| + last_byte_position)) { |
| + *first_byte_position = *last_byte_position = -1; |
|
mmenke
2016/12/02 19:05:08
This API seems really bad. It sets these values t
sclittle
2016/12/02 22:19:22
In what way are you suggesting changing the API? F
mmenke
2016/12/02 22:31:56
We return false if it's not a valid response to a
sclittle
2016/12/03 00:43:13
From what I can see, it looks like all the callers
mmenke
2016/12/03 00:46:21
I'm fine with splitting it into multiple CLs, but
sclittle
2016/12/03 00:56:34
Woah, that is paranoid. Ok, I guess I'll do that t
|
| + return false; |
| + } |
| + if (*first_byte_position < 0 || *last_byte_position < 0 || |
| + *first_byte_position > *last_byte_position) |
| + return false; |
| + } |
| + |
| + // Parse the instance-length part. |
| + base::StringPiece instance_length_spec = |
| + TrimLWS(content_range_spec.substr(slash_position + 1)); |
| + |
| + if (base::StartsWith(instance_length_spec, "*", |
| + base::CompareCase::SENSITIVE)) { |
| + return false; |
| + } else if (!base::StringToInt64(instance_length_spec, instance_length)) { |
| + *instance_length = -1; |
| + return false; |
|
mmenke
2016/12/02 22:38:47
Actually, we don't provide enough data to validate
sclittle
2016/12/03 00:43:13
Looking at the call sites, I don't see any reader
|
| + } |
| + |
| + // We have all the values; let's verify that they make sense for a 206 |
| + // response. |
| + if (*first_byte_position < 0 || *last_byte_position < 0 || |
| + *instance_length < 0 || *instance_length - 1 < *last_byte_position) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| +// static |
| bool HttpUtil::ParseRetryAfterHeader(const std::string& retry_after_string, |
| base::Time now, |
| base::TimeDelta* retry_after) { |