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 |