| 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 #ifndef NET_HTTP_HTTP_UTIL_H_ | 5 #ifndef NET_HTTP_HTTP_UTIL_H_ |
| 6 #define NET_HTTP_HTTP_UTIL_H_ | 6 #define NET_HTTP_HTTP_UTIL_H_ |
| 7 | 7 |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 | 9 |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/macros.h" |
| 13 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 14 #include "base/strings/string_tokenizer.h" | 15 #include "base/strings/string_tokenizer.h" |
| 15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 16 #include "net/base/net_export.h" | 17 #include "net/base/net_export.h" |
| 17 #include "net/http/http_byte_range.h" | 18 #include "net/http/http_byte_range.h" |
| 18 #include "net/http/http_version.h" | 19 #include "net/http/http_version.h" |
| 19 #include "url/gurl.h" | 20 #include "url/gurl.h" |
| 20 | 21 |
| 21 // This is a macro to support extending this string literal at compile time. | 22 // This is a macro to support extending this string literal at compile time. |
| 22 // Please excuse me polluting your global namespace! | 23 // Please excuse me polluting your global namespace! |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 // Whether the character is the start of a quotation mark. | 117 // Whether the character is the start of a quotation mark. |
| 117 static bool IsQuote(char c); | 118 static bool IsQuote(char c); |
| 118 | 119 |
| 119 // Whether the string is a valid |token| as defined in RFC 2616 Sec 2.2. | 120 // Whether the string is a valid |token| as defined in RFC 2616 Sec 2.2. |
| 120 static bool IsToken(std::string::const_iterator begin, | 121 static bool IsToken(std::string::const_iterator begin, |
| 121 std::string::const_iterator end); | 122 std::string::const_iterator end); |
| 122 static bool IsToken(const std::string& str) { | 123 static bool IsToken(const std::string& str) { |
| 123 return IsToken(str.begin(), str.end()); | 124 return IsToken(str.begin(), str.end()); |
| 124 } | 125 } |
| 125 | 126 |
| 127 // Whether the string is a valid |parmname| as defined in RFC 5987 Sec 3.2.1. |
| 128 static bool IsParmName(std::string::const_iterator begin, |
| 129 std::string::const_iterator end); |
| 130 static bool IsParmName(const std::string& str) { |
| 131 return IsParmName(str.begin(), str.end()); |
| 132 } |
| 133 |
| 126 // RFC 2616 Sec 2.2: | 134 // RFC 2616 Sec 2.2: |
| 127 // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) | 135 // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) |
| 128 // Unquote() strips the surrounding quotemarks off a string, and unescapes | 136 // Unquote() strips the surrounding quotemarks off a string, and unescapes |
| 129 // any quoted-pair to obtain the value contained by the quoted-string. | 137 // any quoted-pair to obtain the value contained by the quoted-string. |
| 130 // If the input is not quoted, then it works like the identity function. | 138 // If the input is not quoted, then it works like the identity function. |
| 131 static std::string Unquote(std::string::const_iterator begin, | 139 static std::string Unquote(std::string::const_iterator begin, |
| 132 std::string::const_iterator end); | 140 std::string::const_iterator end); |
| 133 | 141 |
| 134 // Same as above. | 142 // Same as above. |
| 135 static std::string Unquote(const std::string& str); | 143 static std::string Unquote(const std::string& str); |
| 136 | 144 |
| 145 // Similar to Unquote(), but additionally validates that the string being |
| 146 // unescaped actually is a valid quoted string. Returns false for an empty |
| 147 // string, a string without quotes, a string with mismatched quotes, and |
| 148 // a string with unescaped embeded quotes. |
| 149 // In accordance with RFC 2616 this method only allows double quotes to |
| 150 // enclose the string. |
| 151 static bool StrictUnquote(std::string::const_iterator begin, |
| 152 std::string::const_iterator end, |
| 153 std::string* out) WARN_UNUSED_RESULT; |
| 154 |
| 155 // Same as above. |
| 156 static bool StrictUnquote(const std::string& str, |
| 157 std::string* out) WARN_UNUSED_RESULT; |
| 158 |
| 137 // The reverse of Unquote() -- escapes and surrounds with " | 159 // The reverse of Unquote() -- escapes and surrounds with " |
| 138 static std::string Quote(const std::string& str); | 160 static std::string Quote(const std::string& str); |
| 139 | 161 |
| 140 // Returns the start of the status line, or -1 if no status line was found. | 162 // Returns the start of the status line, or -1 if no status line was found. |
| 141 // This allows for 4 bytes of junk to precede the status line (which is what | 163 // This allows for 4 bytes of junk to precede the status line (which is what |
| 142 // mozilla does too). | 164 // mozilla does too). |
| 143 static int LocateStartOfStatusLine(const char* buf, int buf_len); | 165 static int LocateStartOfStatusLine(const char* buf, int buf_len); |
| 144 | 166 |
| 145 // Returns index beyond the end-of-headers marker or -1 if not found. RFC | 167 // Returns index beyond the end-of-headers marker or -1 if not found. RFC |
| 146 // 2616 defines the end-of-headers marker as a double CRLF; however, some | 168 // 2616 defines the end-of-headers marker as a double CRLF; however, some |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 // quoted string. | 318 // quoted string. |
| 297 // | 319 // |
| 298 class NET_EXPORT_PRIVATE ValuesIterator { | 320 class NET_EXPORT_PRIVATE ValuesIterator { |
| 299 public: | 321 public: |
| 300 ValuesIterator(std::string::const_iterator values_begin, | 322 ValuesIterator(std::string::const_iterator values_begin, |
| 301 std::string::const_iterator values_end, | 323 std::string::const_iterator values_end, |
| 302 char delimiter); | 324 char delimiter); |
| 303 ValuesIterator(const ValuesIterator& other); | 325 ValuesIterator(const ValuesIterator& other); |
| 304 ~ValuesIterator(); | 326 ~ValuesIterator(); |
| 305 | 327 |
| 328 // Set the characters to regard as quotes. By default, this includes both |
| 329 // single and double quotes. |
| 330 void set_quote_chars(const char* quotes) { |
| 331 values_.set_quote_chars(quotes); |
| 332 } |
| 333 |
| 306 // Advances the iterator to the next value, if any. Returns true if there | 334 // Advances the iterator to the next value, if any. Returns true if there |
| 307 // is a next value. Use value* methods to access the resultant value. | 335 // is a next value. Use value* methods to access the resultant value. |
| 308 bool GetNext(); | 336 bool GetNext(); |
| 309 | 337 |
| 310 std::string::const_iterator value_begin() const { | 338 std::string::const_iterator value_begin() const { |
| 311 return value_begin_; | 339 return value_begin_; |
| 312 } | 340 } |
| 313 std::string::const_iterator value_end() const { | 341 std::string::const_iterator value_end() const { |
| 314 return value_end_; | 342 return value_end_; |
| 315 } | 343 } |
| 316 std::string value() const { | 344 std::string value() const { |
| 317 return std::string(value_begin_, value_end_); | 345 return std::string(value_begin_, value_end_); |
| 318 } | 346 } |
| 319 | 347 |
| 320 private: | 348 private: |
| 321 base::StringTokenizer values_; | 349 base::StringTokenizer values_; |
| 322 std::string::const_iterator value_begin_; | 350 std::string::const_iterator value_begin_; |
| 323 std::string::const_iterator value_end_; | 351 std::string::const_iterator value_end_; |
| 324 }; | 352 }; |
| 325 | 353 |
| 326 // Iterates over a delimited sequence of name-value pairs in an HTTP header. | 354 // Iterates over a delimited sequence of name-value pairs in an HTTP header. |
| 327 // Each pair consists of a token (the name), an equals sign, and either a | 355 // Each pair consists of a token (the name), an equals sign, and either a |
| 328 // token or quoted-string (the value). Arbitrary HTTP LWS is permitted outside | 356 // token or quoted-string (the value). Arbitrary HTTP LWS is permitted outside |
| 329 // of and between names, values, and delimiters. | 357 // of and between names, values, and delimiters. |
| 330 // | 358 // |
| 331 // String iterators returned from this class' methods may be invalidated upon | 359 // String iterators returned from this class' methods may be invalidated upon |
| 332 // calls to GetNext() or after the NameValuePairsIterator is destroyed. | 360 // calls to GetNext() or after the NameValuePairsIterator is destroyed. |
| 333 class NET_EXPORT NameValuePairsIterator { | 361 class NET_EXPORT NameValuePairsIterator { |
| 334 public: | 362 public: |
| 335 // Whether or not values are optional. VALUES_OPTIONAL allows | 363 // Whether or not values are optional. Values::NOT_REQUIRED allows |
| 336 // e.g. name1=value1;name2;name3=value3, whereas VALUES_NOT_OPTIONAL | 364 // e.g. name1=value1;name2;name3=value3, whereas Vaues::REQUIRED |
| 337 // will treat it as a parse error because name2 does not have a | 365 // will treat it as a parse error because name2 does not have a |
| 338 // corresponding equals sign. | 366 // corresponding equals sign. |
| 339 enum OptionalValues { VALUES_OPTIONAL, VALUES_NOT_OPTIONAL }; | 367 enum class Values { NOT_REQUIRED, REQUIRED }; |
| 368 |
| 369 // Whether or not unmatched quotes should be considered a failure. By |
| 370 // default this class is pretty lenient and does a best effort to parse |
| 371 // values with mismatched quotes. When set to STRICT_QUOTES a value with |
| 372 // mismatched or otherwise invalid quotes is considered a parse error. |
| 373 enum class Quotes { STRICT_QUOTES, NOT_STRICT }; |
| 340 | 374 |
| 341 NameValuePairsIterator(std::string::const_iterator begin, | 375 NameValuePairsIterator(std::string::const_iterator begin, |
| 342 std::string::const_iterator end, | 376 std::string::const_iterator end, |
| 343 char delimiter, | 377 char delimiter, |
| 344 OptionalValues optional_values); | 378 Values optional_values, |
| 379 Quotes strict_quotes); |
| 345 | 380 |
| 346 // Treats values as not optional by default (VALUES_NOT_OPTIONAL). | 381 // Treats values as not optional by default (Values::REQUIRED) and |
| 382 // treats quotes as not strict. |
| 347 NameValuePairsIterator(std::string::const_iterator begin, | 383 NameValuePairsIterator(std::string::const_iterator begin, |
| 348 std::string::const_iterator end, | 384 std::string::const_iterator end, |
| 349 char delimiter); | 385 char delimiter); |
| 350 | 386 |
| 351 NameValuePairsIterator(const NameValuePairsIterator& other); | 387 NameValuePairsIterator(const NameValuePairsIterator& other); |
| 352 | 388 |
| 353 ~NameValuePairsIterator(); | 389 ~NameValuePairsIterator(); |
| 354 | 390 |
| 355 // Advances the iterator to the next pair, if any. Returns true if there | 391 // Advances the iterator to the next pair, if any. Returns true if there |
| 356 // is a next pair. Use name* and value* methods to access the resultant | 392 // is a next pair. Use name* and value* methods to access the resultant |
| (...skipping 20 matching lines...) Expand all Loading... |
| 377 value_end_); | 413 value_end_); |
| 378 } | 414 } |
| 379 | 415 |
| 380 bool value_is_quoted() const { return value_is_quoted_; } | 416 bool value_is_quoted() const { return value_is_quoted_; } |
| 381 | 417 |
| 382 // The value before unquoting (if any). | 418 // The value before unquoting (if any). |
| 383 std::string raw_value() const { return std::string(value_begin_, | 419 std::string raw_value() const { return std::string(value_begin_, |
| 384 value_end_); } | 420 value_end_); } |
| 385 | 421 |
| 386 private: | 422 private: |
| 423 bool IsQuote(char c) const; |
| 424 |
| 387 HttpUtil::ValuesIterator props_; | 425 HttpUtil::ValuesIterator props_; |
| 388 bool valid_; | 426 bool valid_; |
| 389 | 427 |
| 390 std::string::const_iterator name_begin_; | 428 std::string::const_iterator name_begin_; |
| 391 std::string::const_iterator name_end_; | 429 std::string::const_iterator name_end_; |
| 392 | 430 |
| 393 std::string::const_iterator value_begin_; | 431 std::string::const_iterator value_begin_; |
| 394 std::string::const_iterator value_end_; | 432 std::string::const_iterator value_end_; |
| 395 | 433 |
| 396 // Do not store iterators into this string. The NameValuePairsIterator | 434 // Do not store iterators into this string. The NameValuePairsIterator |
| 397 // is copyable/assignable, and if copied the copy's iterators would point | 435 // is copyable/assignable, and if copied the copy's iterators would point |
| 398 // into the original's unquoted_value_ member. | 436 // into the original's unquoted_value_ member. |
| 399 std::string unquoted_value_; | 437 std::string unquoted_value_; |
| 400 | 438 |
| 401 bool value_is_quoted_; | 439 bool value_is_quoted_; |
| 402 | 440 |
| 403 // True if values are required for each name/value pair; false if a | 441 // True if values are required for each name/value pair; false if a |
| 404 // name is permitted to appear without a corresponding value. | 442 // name is permitted to appear without a corresponding value. |
| 405 bool values_optional_; | 443 bool values_optional_; |
| 444 |
| 445 // True if quotes values are required to be properly quoted; false if |
| 446 // mismatched quotes and other problems with quoted values should be more |
| 447 // or less gracefully treated as valid. |
| 448 bool strict_quotes_; |
| 406 }; | 449 }; |
| 407 }; | 450 }; |
| 408 | 451 |
| 409 } // namespace net | 452 } // namespace net |
| 410 | 453 |
| 411 #endif // NET_HTTP_HTTP_UTIL_H_ | 454 #endif // NET_HTTP_HTTP_UTIL_H_ |
| OLD | NEW |