Chromium Code Reviews| 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 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 333 base::StartsWith(lower_name, "sec-", base::CompareCase::SENSITIVE)) | 333 base::StartsWith(lower_name, "sec-", base::CompareCase::SENSITIVE)) |
| 334 return false; | 334 return false; |
| 335 for (size_t i = 0; i < arraysize(kForbiddenHeaderFields); ++i) { | 335 for (size_t i = 0; i < arraysize(kForbiddenHeaderFields); ++i) { |
| 336 if (lower_name == kForbiddenHeaderFields[i]) | 336 if (lower_name == kForbiddenHeaderFields[i]) |
| 337 return false; | 337 return false; |
| 338 } | 338 } |
| 339 return true; | 339 return true; |
| 340 } | 340 } |
| 341 | 341 |
| 342 // static | 342 // static |
| 343 bool HttpUtil::IsValidHeaderName(const std::string& name) { | 343 bool HttpUtil::IsValidHeaderName(const base::StringPiece& name) { |
| 344 // Check whether the header name is RFC 2616-compliant. | 344 // Check whether the header name is RFC 2616-compliant. |
| 345 return HttpUtil::IsToken(name); | 345 return HttpUtil::IsToken(name); |
| 346 } | 346 } |
| 347 | 347 |
| 348 // static | 348 // static |
| 349 bool HttpUtil::IsValidHeaderValue(const std::string& value) { | 349 bool HttpUtil::IsValidHeaderValue(const base::StringPiece& value) { |
| 350 // Just a sanity check: disallow NUL, CR and LF. | 350 // Just a sanity check: disallow NUL, CR and LF. |
| 351 return value.find_first_of("\0\r\n", 0, 3) == std::string::npos; | 351 for (char c : value) { |
| 352 if (c == '\0' || c == '\r' || c == '\n') | |
| 353 return false; | |
| 354 } | |
| 355 return true; | |
| 352 } | 356 } |
| 353 | 357 |
| 354 // static | 358 // static |
| 355 std::string HttpUtil::StripHeaders(const std::string& headers, | 359 std::string HttpUtil::StripHeaders(const std::string& headers, |
| 356 const char* const headers_to_remove[], | 360 const char* const headers_to_remove[], |
| 357 size_t headers_to_remove_len) { | 361 size_t headers_to_remove_len) { |
| 358 std::string stripped_headers; | 362 std::string stripped_headers; |
| 359 HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n"); | 363 HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n"); |
| 360 | 364 |
| 361 while (it.GetNext()) { | 365 while (it.GetNext()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 kNonCoalescingHeaders[i])) | 406 kNonCoalescingHeaders[i])) |
| 403 return true; | 407 return true; |
| 404 } | 408 } |
| 405 return false; | 409 return false; |
| 406 } | 410 } |
| 407 | 411 |
| 408 bool HttpUtil::IsLWS(char c) { | 412 bool HttpUtil::IsLWS(char c) { |
| 409 return strchr(HTTP_LWS, c) != NULL; | 413 return strchr(HTTP_LWS, c) != NULL; |
| 410 } | 414 } |
| 411 | 415 |
| 412 void HttpUtil::TrimLWS(std::string::const_iterator* begin, | 416 namespace { |
| 413 std::string::const_iterator* end) { | 417 template <typename ConstIterator> |
| 418 void TrimLWSImplementation(ConstIterator* begin, ConstIterator* end) { | |
| 414 // leading whitespace | 419 // leading whitespace |
| 415 while (*begin < *end && IsLWS((*begin)[0])) | 420 while (*begin < *end && HttpUtil::IsLWS((*begin)[0])) |
| 416 ++(*begin); | 421 ++(*begin); |
| 417 | 422 |
| 418 // trailing whitespace | 423 // trailing whitespace |
| 419 while (*begin < *end && IsLWS((*end)[-1])) | 424 while (*begin < *end && HttpUtil::IsLWS((*end)[-1])) |
| 420 --(*end); | 425 --(*end); |
| 421 } | 426 } |
| 427 } // namespace | |
|
mmenke
2016/08/09 16:54:47
The more common pattern in net/ is to use a single
Adam Rice
2016/08/10 03:19:07
Done. I can move the rest of the anonymous namespa
| |
| 428 | |
| 429 // static | |
| 430 void HttpUtil::TrimLWS(std::string::const_iterator* begin, | |
| 431 std::string::const_iterator* end) { | |
| 432 TrimLWSImplementation(begin, end); | |
| 433 } | |
| 434 | |
| 435 // static | |
| 436 base::StringPiece HttpUtil::TrimLWS(const base::StringPiece& string) { | |
| 437 const char* begin = string.data(); | |
| 438 const char* end = string.data() + string.size(); | |
| 439 TrimLWSImplementation(&begin, &end); | |
| 440 return base::StringPiece(begin, end - begin); | |
| 441 } | |
| 422 | 442 |
| 423 bool HttpUtil::IsQuote(char c) { | 443 bool HttpUtil::IsQuote(char c) { |
| 424 // Single quote mark isn't actually part of quoted-text production, | 444 // Single quote mark isn't actually part of quoted-text production, |
| 425 // but apparently some servers rely on this. | 445 // but apparently some servers rely on this. |
| 426 return c == '"' || c == '\''; | 446 return c == '"' || c == '\''; |
| 427 } | 447 } |
| 428 | 448 |
| 429 namespace { | 449 namespace { |
| 430 bool IsTokenChar(unsigned char c) { | 450 bool IsTokenChar(unsigned char c) { |
| 431 return !(c >= 0x80 || c <= 0x1F || c == 0x7F || c == '(' || c == ')' || | 451 return !(c >= 0x80 || c <= 0x1F || c == 0x7F || c == '(' || c == ')' || |
| 432 c == '<' || c == '>' || c == '@' || c == ',' || c == ';' || | 452 c == '<' || c == '>' || c == '@' || c == ',' || c == ';' || |
| 433 c == ':' || c == '\\' || c == '"' || c == '/' || c == '[' || | 453 c == ':' || c == '\\' || c == '"' || c == '/' || c == '[' || |
| 434 c == ']' || c == '?' || c == '=' || c == '{' || c == '}' || | 454 c == ']' || c == '?' || c == '=' || c == '{' || c == '}' || |
| 435 c == ' ' || c == '\t'); | 455 c == ' ' || c == '\t'); |
| 436 } | 456 } |
| 437 } // anonymous namespace | 457 } // anonymous namespace |
| 438 | 458 |
| 439 // See RFC 2616 Sec 2.2 for the definition of |token|. | 459 // See RFC 2616 Sec 2.2 for the definition of |token|. |
| 440 bool HttpUtil::IsToken(std::string::const_iterator begin, | 460 bool HttpUtil::IsToken(const base::StringPiece& string) { |
| 441 std::string::const_iterator end) { | 461 if (string.size() == 0) |
|
mmenke
2016/08/09 16:54:47
!string.empty() is preferred, as it doesn't requir
Adam Rice
2016/08/10 03:19:07
I can't believe I did that. Fixed.
| |
| 442 if (begin == end) | |
| 443 return false; | 462 return false; |
| 444 for (std::string::const_iterator iter = begin; iter != end; ++iter) { | 463 for (char c : string) { |
| 445 if (!IsTokenChar(*iter)) | 464 if (!IsTokenChar(c)) |
| 446 return false; | 465 return false; |
| 447 } | 466 } |
| 448 return true; | 467 return true; |
| 449 } | 468 } |
| 450 | 469 |
| 451 // See RFC 5987 Sec 3.2.1 for the definition of |parmname|. | 470 // See RFC 5987 Sec 3.2.1 for the definition of |parmname|. |
| 452 bool HttpUtil::IsParmName(std::string::const_iterator begin, | 471 bool HttpUtil::IsParmName(std::string::const_iterator begin, |
| 453 std::string::const_iterator end) { | 472 std::string::const_iterator end) { |
| 454 if (begin == end) | 473 if (begin == end) |
| 455 return false; | 474 return false; |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1053 return true; | 1072 return true; |
| 1054 } | 1073 } |
| 1055 | 1074 |
| 1056 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const { | 1075 bool HttpUtil::NameValuePairsIterator::IsQuote(char c) const { |
| 1057 if (strict_quotes_) | 1076 if (strict_quotes_) |
| 1058 return c == '"'; | 1077 return c == '"'; |
| 1059 return HttpUtil::IsQuote(c); | 1078 return HttpUtil::IsQuote(c); |
| 1060 } | 1079 } |
| 1061 | 1080 |
| 1062 } // namespace net | 1081 } // namespace net |
| OLD | NEW |