0

Add *_piece() methods to http_util's header iterators.

These wrap StringTokenizer which have std::string::const_iterator
thoroughly weaved through them. I suspect we'll need to switch them all
to StringPiece atomically. Start by clearing out as many of the
*_begin() and *_end() calls with a newly-added *_piece(). (This aligns
with StringTokenizer's token_piece() method.)

While I'm here, switch some easy calls that return a std::string copy to
*_piece().

Bug: 820198
Change-Id: I8c17faa40d5ea8cf4c241acc9bf907f1e139f2c7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1575164
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: Filip Gorski <fgorski@chromium.org>
Reviewed-by: Jochen Eisinger <jochen@chromium.org>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Reviewed-by: Eric Roman <eroman@chromium.org>
Commit-Queue: David Benjamin <davidben@chromium.org>
Cr-Commit-Position: refs/heads/master@{#654269}
This commit is contained in:
David Benjamin
2019-04-26 00:07:51 +00:00
committed by Commit Bot
parent 143fe89fe4
commit e4b880eaa9
16 changed files with 81 additions and 82 deletions

@ -317,7 +317,7 @@ int32_t PepperFlashRendererHost::OnNavigate(
bool rejected = false;
while (header_iter.GetNext()) {
std::string lower_case_header_name =
base::ToLowerASCII(header_iter.name());
base::ToLowerASCII(header_iter.name_piece());
if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) {
rejected = true;

@ -80,10 +80,8 @@ bool EncryptionHeaderIterator::GetNext() {
bool found_rs = false;
while (name_value_pairs.GetNext()) {
const base::StringPiece name(name_value_pairs.name_begin(),
name_value_pairs.name_end());
const base::StringPiece value(name_value_pairs.value_begin(),
name_value_pairs.value_end());
const base::StringPiece name = name_value_pairs.name_piece();
const base::StringPiece value = name_value_pairs.value_piece();
if (base::LowerCaseEqualsASCII(name, "keyid")) {
if (found_keyid)
@ -131,10 +129,8 @@ bool CryptoKeyHeaderIterator::GetNext() {
bool found_dh = false;
while (name_value_pairs.GetNext()) {
const base::StringPiece name(name_value_pairs.name_begin(),
name_value_pairs.name_end());
const base::StringPiece value(name_value_pairs.value_begin(),
name_value_pairs.value_end());
const base::StringPiece name = name_value_pairs.name_piece();
const base::StringPiece value = name_value_pairs.value_piece();
if (base::LowerCaseEqualsASCII(name, "keyid")) {
if (found_keyid)

@ -178,13 +178,11 @@ bool ParseLinkHeaderValue(
net::HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED,
net::HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
while (params_iterator.GetNext()) {
if (!net::HttpUtil::IsParmName(params_iterator.name_begin(),
params_iterator.name_end()))
if (!net::HttpUtil::IsParmName(params_iterator.name_piece()))
return false;
std::string name = base::ToLowerASCII(base::StringPiece(
params_iterator.name_begin(), params_iterator.name_end()));
std::string name = base::ToLowerASCII(params_iterator.name_piece());
if (!params_iterator.value_is_quoted() &&
params_iterator.value_begin() == params_iterator.value_end())
params_iterator.value_piece().empty())
params->insert(std::make_pair(name, base::nullopt));
else
params->insert(std::make_pair(name, params_iterator.value()));

@ -230,12 +230,13 @@ OriginPolicyThrottle::GetRequestedPolicyAndReportGroupFromHeaderString(
net::HttpUtil::NameValuePairsIterator iter(header.cbegin(), header.cend(),
',');
while (iter.GetNext()) {
std::string token_value = net::HttpUtil::TrimLWS(iter.value()).as_string();
std::string token_value =
net::HttpUtil::TrimLWS(iter.value_piece()).as_string();
bool is_token = net::HttpUtil::IsToken(token_value);
if (iter.name() == kPolicy) {
if (iter.name_piece() == kPolicy) {
valid &= is_token && policy.empty();
policy = token_value;
} else if (iter.name() == kReportTo) {
} else if (iter.name_piece() == kReportTo) {
valid &= is_token && report_to.empty();
report_to = token_value;
}

@ -105,7 +105,7 @@ bool IsCacheableBySharedCache(const SignedExchangeEnvelope::HeaderMap& headers,
net::HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED,
net::HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
while (it.GetNext()) {
auto name = it.name();
base::StringPiece name = it.name_piece();
if (name == "no-store" || name == "private") {
signed_exchange_utils::ReportErrorAndTraceEvent(
devtools_proxy,

@ -68,7 +68,7 @@ class ContentNegotiationAlgorithm {
item.value = name_value_pairs.name();
item.weight = 1.0;
while (name_value_pairs.GetNext()) {
if (base::LowerCaseEqualsASCII(name_value_pairs.name(), "q")) {
if (base::LowerCaseEqualsASCII(name_value_pairs.name_piece(), "q")) {
if (auto value = GetQValue(name_value_pairs.value()))
item.weight = *value;
} else {

@ -94,7 +94,7 @@ base::Optional<SignedExchangeVersion> GetSignedExchangeVersion(
net::HttpUtil::NameValuePairsIterator parser(
content_type.begin() + semicolon + 1, content_type.end(), ';');
while (parser.GetNext()) {
const base::StringPiece name(parser.name_begin(), parser.name_end());
const base::StringPiece name = parser.name_piece();
params[base::ToLowerASCII(name)] = parser.value();
}
if (!parser.valid())

@ -42,10 +42,11 @@ bool ParseRealm(const HttpAuthChallengeTokenizer& tokenizer,
realm->clear();
HttpUtil::NameValuePairsIterator parameters = tokenizer.param_pairs();
while (parameters.GetNext()) {
if (!base::LowerCaseEqualsASCII(parameters.name(), "realm"))
if (!base::LowerCaseEqualsASCII(parameters.name_piece(), "realm"))
continue;
if (!ConvertToUtf8AndNormalize(parameters.value(), kCharsetLatin1, realm)) {
if (!ConvertToUtf8AndNormalize(parameters.value_piece(), kCharsetLatin1,
realm)) {
return false;
}
}

@ -9,6 +9,7 @@
#include "base/hash/md5.h"
#include "base/logging.h"
#include "base/rand_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
@ -123,10 +124,10 @@ HttpAuth::AuthorizationResult HttpAuthHandlerDigest::HandleAnotherChallenge(
// for the new challenge.
std::string original_realm;
while (parameters.GetNext()) {
if (base::LowerCaseEqualsASCII(parameters.name(), "stale")) {
if (base::LowerCaseEqualsASCII(parameters.value(), "true"))
if (base::LowerCaseEqualsASCII(parameters.name_piece(), "stale")) {
if (base::LowerCaseEqualsASCII(parameters.value_piece(), "true"))
return HttpAuth::AUTHORIZATION_RESULT_STALE;
} else if (base::LowerCaseEqualsASCII(parameters.name(), "realm")) {
} else if (base::LowerCaseEqualsASCII(parameters.name_piece(), "realm")) {
original_realm = parameters.value();
}
}
@ -210,8 +211,8 @@ bool HttpAuthHandlerDigest::ParseChallenge(
// Loop through all the properties.
while (parameters.GetNext()) {
// FAIL -- couldn't parse a property.
if (!ParseChallengeProperty(parameters.name(),
parameters.value()))
if (!ParseChallengeProperty(parameters.name_piece(),
parameters.value_piece()))
return false;
}
@ -226,20 +227,20 @@ bool HttpAuthHandlerDigest::ParseChallenge(
return true;
}
bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name,
const std::string& value) {
bool HttpAuthHandlerDigest::ParseChallengeProperty(base::StringPiece name,
base::StringPiece value) {
if (base::LowerCaseEqualsASCII(name, "realm")) {
std::string realm;
if (!ConvertToUtf8AndNormalize(value, kCharsetLatin1, &realm))
return false;
realm_ = realm;
original_realm_ = value;
original_realm_ = value.as_string();
} else if (base::LowerCaseEqualsASCII(name, "nonce")) {
nonce_ = value;
nonce_ = value.as_string();
} else if (base::LowerCaseEqualsASCII(name, "domain")) {
domain_ = value;
domain_ = value.as_string();
} else if (base::LowerCaseEqualsASCII(name, "opaque")) {
opaque_ = value;
opaque_ = value.as_string();
} else if (base::LowerCaseEqualsASCII(name, "stale")) {
// Parse the stale boolean.
stale_ = base::LowerCaseEqualsASCII(value, "true");
@ -256,10 +257,15 @@ bool HttpAuthHandlerDigest::ParseChallengeProperty(const std::string& name,
} else if (base::LowerCaseEqualsASCII(name, "qop")) {
// Parse the comma separated list of qops.
// auth is the only supported qop, and all other values are ignored.
HttpUtil::ValuesIterator qop_values(value.begin(), value.end(), ',');
//
// TODO(https://crbug.com/820198): Remove this copy when
// HttpUtil::ValuesIterator can take a StringPiece.
std::string value_str = value.as_string();
HttpUtil::ValuesIterator qop_values(value_str.begin(), value_str.end(),
',');
qop_ = QOP_UNSPECIFIED;
while (qop_values.GetNext()) {
if (base::LowerCaseEqualsASCII(qop_values.value(), "auth")) {
if (base::LowerCaseEqualsASCII(qop_values.value_piece(), "auth")) {
qop_ = QOP_AUTH;
break;
}

@ -10,6 +10,7 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/strings/string_piece_forward.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_export.h"
#include "net/http/http_auth_handler.h"
@ -131,8 +132,7 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerDigest : public HttpAuthHandler {
bool ParseChallenge(HttpAuthChallengeTokenizer* challenge);
// Parse an individual property. Returns true on success.
bool ParseChallengeProperty(const std::string& name,
const std::string& value);
bool ParseChallengeProperty(base::StringPiece name, base::StringPiece value);
// Generates a random string, to be used for client-nonce.
static std::string GenerateNonce();

@ -150,8 +150,7 @@ static bool HeaderMatches(const HttpRequestHeaders& headers,
HttpUtil::ValuesIterator v(header_value.begin(), header_value.end(), ',');
while (v.GetNext()) {
if (base::LowerCaseEqualsASCII(
base::StringPiece(v.value_begin(), v.value_end()), search->value))
if (base::LowerCaseEqualsASCII(v.value_piece(), search->value))
return true;
}
}

@ -402,9 +402,7 @@ void HttpContentDisposition::Parse(const std::string& header,
HttpUtil::NameValuePairsIterator iter(pos, end, ';');
while (iter.GetNext()) {
if (filename.empty() &&
base::LowerCaseEqualsASCII(
base::StringPiece(iter.name_begin(), iter.name_end()),
"filename")) {
base::LowerCaseEqualsASCII(iter.name_piece(), "filename")) {
DecodeFilenameValue(iter.value(), referrer_charset, &filename,
&parse_result_flags_);
if (!filename.empty()) {
@ -413,9 +411,7 @@ void HttpContentDisposition::Parse(const std::string& header,
parse_result_flags_ |= HAS_SINGLE_QUOTED_FILENAME;
}
} else if (ext_filename.empty() &&
base::LowerCaseEqualsASCII(
base::StringPiece(iter.name_begin(), iter.name_end()),
"filename*")) {
base::LowerCaseEqualsASCII(iter.name_piece(), "filename*")) {
DecodeExtValue(iter.raw_value(), &ext_filename);
if (!ext_filename.empty())
parse_result_flags_ |= HAS_EXT_FILENAME;

@ -23,12 +23,7 @@ enum MaxAgeParsing { REQUIRE_MAX_AGE, DO_NOT_REQUIRE_MAX_AGE };
// seconds into a uint32_t. The string may contain an arbitrarily large number,
// which will be clipped to a supplied limit and which is guaranteed to fit
// within a 32-bit unsigned integer. False is returned on any parse error.
bool MaxAgeToLimitedInt(std::string::const_iterator begin,
std::string::const_iterator end,
uint32_t limit,
uint32_t* result) {
const base::StringPiece s(begin, end);
bool MaxAgeToLimitedInt(base::StringPiece s, uint32_t limit, uint32_t* result) {
ParseIntError error;
if (!ParseUint32(s, result, &error)) {
if (error == ParseIntError::FAILED_OVERFLOW) {
@ -130,8 +125,7 @@ bool ParseHSTSHeader(const std::string& value,
if (base::IsAsciiWhitespace(*tokenizer.token_begin()))
continue;
unquoted = HttpUtil::Unquote(tokenizer.token());
if (!MaxAgeToLimitedInt(unquoted.begin(), unquoted.end(),
kMaxHSTSAgeSecs, &max_age_candidate))
if (!MaxAgeToLimitedInt(unquoted, kMaxHSTSAgeSecs, &max_age_candidate))
return false;
state = AFTER_MAX_AGE;
break;
@ -201,16 +195,14 @@ bool ParseExpectCTHeader(const std::string& value,
HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
while (name_value_pairs.GetNext()) {
base::StringPiece name(name_value_pairs.name_begin(),
name_value_pairs.name_end());
base::StringPiece name = name_value_pairs.name_piece();
if (base::LowerCaseEqualsASCII(name, "max-age")) {
// "A given directive MUST NOT appear more than once in a given header
// field."
if (parsed_max_age)
return false;
if (!MaxAgeToLimitedInt(name_value_pairs.value_begin(),
name_value_pairs.value_end(), kMaxExpectCTAgeSecs,
&max_age_candidate)) {
if (!MaxAgeToLimitedInt(name_value_pairs.value_piece(),
kMaxExpectCTAgeSecs, &max_age_candidate)) {
return false;
}
parsed_max_age = true;
@ -219,7 +211,7 @@ bool ParseExpectCTHeader(const std::string& value,
// field."
if (enforce_candidate)
return false;
if (!name_value_pairs.value().empty())
if (!name_value_pairs.value_piece().empty())
return false;
enforce_candidate = true;
} else if (base::LowerCaseEqualsASCII(name, "report-uri")) {
@ -229,8 +221,7 @@ bool ParseExpectCTHeader(const std::string& value,
return false;
has_report_uri = true;
parsed_report_uri = GURL(base::StringPiece(name_value_pairs.value_begin(),
name_value_pairs.value_end()));
parsed_report_uri = GURL(name_value_pairs.value_piece());
if (parsed_report_uri.is_empty() || !parsed_report_uri.is_valid())
return false;
} else {

@ -265,7 +265,7 @@ bool HttpUtil::ParseRangeHeader(const std::string& ranges_specifier,
ValuesIterator byte_range_set_iterator(byte_range_set_begin,
byte_range_set_end, ',');
while (byte_range_set_iterator.GetNext()) {
size_t minus_char_offset = byte_range_set_iterator.value().find('-');
size_t minus_char_offset = byte_range_set_iterator.value_piece().find('-');
// If '-' character is not found, reports failure.
if (minus_char_offset == std::string::npos)
return false;
@ -517,7 +517,7 @@ bool HttpUtil::IsTokenChar(char c) {
}
// See RFC 7230 Sec 3.2.6 for the definition of |token|.
bool HttpUtil::IsToken(const base::StringPiece& string) {
bool HttpUtil::IsToken(base::StringPiece string) {
if (string.empty())
return false;
for (char c : string) {
@ -528,12 +528,10 @@ bool HttpUtil::IsToken(const base::StringPiece& string) {
}
// See RFC 5987 Sec 3.2.1 for the definition of |parmname|.
bool HttpUtil::IsParmName(std::string::const_iterator begin,
std::string::const_iterator end) {
if (begin == end)
bool HttpUtil::IsParmName(base::StringPiece str) {
if (str.empty())
return false;
for (std::string::const_iterator iter = begin; iter != end; ++iter) {
unsigned char c = *iter;
for (char c : str) {
if (!IsTokenChar(c) || c == '*' || c == '\'' || c == '%')
return false;
}

@ -126,14 +126,10 @@ class NET_EXPORT HttpUtil {
// Whether the character is a valid |tchar| as defined in RFC 7230 Sec 3.2.6.
static bool IsTokenChar(char c);
// Whether the string is a valid |token| as defined in RFC 7230 Sec 3.2.6.
static bool IsToken(const base::StringPiece& str);
static bool IsToken(base::StringPiece str);
// Whether the string is a valid |parmname| as defined in RFC 5987 Sec 3.2.1.
static bool IsParmName(std::string::const_iterator begin,
std::string::const_iterator end);
static bool IsParmName(const std::string& str) {
return IsParmName(str.begin(), str.end());
}
static bool IsParmName(base::StringPiece str);
// RFC 2616 Sec 2.2:
// quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
@ -306,6 +302,9 @@ class NET_EXPORT HttpUtil {
std::string name() const {
return std::string(name_begin_, name_end_);
}
base::StringPiece name_piece() const {
return base::StringPiece(name_begin_, name_end_);
}
std::string::const_iterator values_begin() const {
return values_begin_;
@ -316,6 +315,9 @@ class NET_EXPORT HttpUtil {
std::string values() const {
return std::string(values_begin_, values_end_);
}
base::StringPiece values_piece() const {
return base::StringPiece(values_begin_, values_end_);
}
private:
base::StringTokenizer lines_;
@ -357,6 +359,9 @@ class NET_EXPORT HttpUtil {
std::string value() const {
return std::string(value_begin_, value_end_);
}
base::StringPiece value_piece() const {
return base::StringPiece(value_begin_, value_end_);
}
private:
base::StringTokenizer values_;
@ -414,6 +419,9 @@ class NET_EXPORT HttpUtil {
std::string::const_iterator name_begin() const { return name_begin_; }
std::string::const_iterator name_end() const { return name_end_; }
std::string name() const { return std::string(name_begin_, name_end_); }
base::StringPiece name_piece() const {
return base::StringPiece(name_begin_, name_end_);
}
// The value of the current name-value pair.
std::string::const_iterator value_begin() const {
@ -426,6 +434,10 @@ class NET_EXPORT HttpUtil {
return value_is_quoted_ ? unquoted_value_ : std::string(value_begin_,
value_end_);
}
base::StringPiece value_piece() const {
return value_is_quoted_ ? unquoted_value_
: base::StringPiece(value_begin_, value_end_);
}
bool value_is_quoted() const { return value_is_quoted_; }

@ -73,7 +73,7 @@ bool GetByteRangeFromStr(const std::string& content_range_str,
bool GetByteRangeFromHeaders(const std::string& headers, int* start, int* end) {
net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n");
while (it.GetNext()) {
if (base::LowerCaseEqualsASCII(it.name(), "content-range")) {
if (base::LowerCaseEqualsASCII(it.name_piece(), "content-range")) {
if (GetByteRangeFromStr(it.values().c_str(), start, end))
return true;
}
@ -219,13 +219,14 @@ void URLLoaderWrapperImpl::ParseHeaders() {
net::HttpUtil::HeadersIterator it(response_headers_.begin(),
response_headers_.end(), "\n");
while (it.GetNext()) {
if (base::LowerCaseEqualsASCII(it.name(), "content-length")) {
base::StringPiece name = it.name_piece();
if (base::LowerCaseEqualsASCII(name, "content-length")) {
content_length_ = atoi(it.values().c_str());
} else if (base::LowerCaseEqualsASCII(it.name(), "accept-ranges")) {
} else if (base::LowerCaseEqualsASCII(name, "accept-ranges")) {
accept_ranges_bytes_ = base::LowerCaseEqualsASCII(it.values(), "bytes");
} else if (base::LowerCaseEqualsASCII(it.name(), "content-encoding")) {
} else if (base::LowerCaseEqualsASCII(name, "content-encoding")) {
content_encoded_ = true;
} else if (base::LowerCaseEqualsASCII(it.name(), "content-type")) {
} else if (base::LowerCaseEqualsASCII(name, "content-type")) {
content_type_ = it.values();
size_t semi_colon_pos = content_type_.find(';');
if (semi_colon_pos != std::string::npos) {
@ -233,7 +234,7 @@ void URLLoaderWrapperImpl::ParseHeaders() {
}
base::TrimWhitespaceASCII(content_type_, base::TRIM_ALL, &content_type_);
// multipart boundary.
std::string type = base::ToLowerASCII(it.values());
std::string type = base::ToLowerASCII(it.values_piece());
if (base::StartsWith(type, "multipart/", base::CompareCase::SENSITIVE)) {
const char* boundary = strstr(type.c_str(), "boundary=");
DCHECK(boundary);
@ -242,9 +243,9 @@ void URLLoaderWrapperImpl::ParseHeaders() {
is_multipart_ = !multipart_boundary_.empty();
}
}
} else if (base::LowerCaseEqualsASCII(it.name(), "content-disposition")) {
} else if (base::LowerCaseEqualsASCII(name, "content-disposition")) {
content_disposition_ = it.values();
} else if (base::LowerCaseEqualsASCII(it.name(), "content-range")) {
} else if (base::LowerCaseEqualsASCII(name, "content-range")) {
int start = 0;
int end = 0;
if (GetByteRangeFromStr(it.values().c_str(), &start, &end)) {