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 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | 5 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
6 | 6 |
7 #include <cmath> | 7 #include <cmath> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "net/http/http_util.h" | 27 #include "net/http/http_util.h" |
28 #include "net/url_request/url_request.h" | 28 #include "net/url_request/url_request.h" |
29 #include "url/url_constants.h" | 29 #include "url/url_constants.h" |
30 | 30 |
31 // TODO(battre): move all static functions into an anonymous namespace at the | 31 // TODO(battre): move all static functions into an anonymous namespace at the |
32 // top of this file. | 32 // top of this file. |
33 | 33 |
34 using base::Time; | 34 using base::Time; |
35 using content::ResourceType; | 35 using content::ResourceType; |
36 using extensions::ExtensionWarning; | 36 using extensions::ExtensionWarning; |
| 37 using net::cookie_util::ParsedRequestCookie; |
| 38 using net::cookie_util::ParsedRequestCookies; |
37 | 39 |
38 namespace extension_web_request_api_helpers { | 40 namespace extension_web_request_api_helpers { |
39 | 41 |
40 namespace { | 42 namespace { |
41 | 43 |
42 // A ParsedRequestCookie consists of the key and value of the cookie. | |
43 typedef std::pair<base::StringPiece, base::StringPiece> ParsedRequestCookie; | |
44 typedef std::vector<ParsedRequestCookie> ParsedRequestCookies; | |
45 typedef std::vector<linked_ptr<net::ParsedCookie> > ParsedResponseCookies; | 44 typedef std::vector<linked_ptr<net::ParsedCookie> > ParsedResponseCookies; |
46 | 45 |
47 static const char* kResourceTypeStrings[] = { | 46 static const char* kResourceTypeStrings[] = { |
48 "main_frame", | 47 "main_frame", |
49 "sub_frame", | 48 "sub_frame", |
50 "stylesheet", | 49 "stylesheet", |
51 "script", | 50 "script", |
52 "image", | 51 "image", |
53 "object", | 52 "object", |
54 "xmlhttprequest", | 53 "xmlhttprequest", |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 } | 475 } |
477 | 476 |
478 void MergeOnBeforeRequestResponses( | 477 void MergeOnBeforeRequestResponses( |
479 const EventResponseDeltas& deltas, | 478 const EventResponseDeltas& deltas, |
480 GURL* new_url, | 479 GURL* new_url, |
481 extensions::ExtensionWarningSet* conflicting_extensions, | 480 extensions::ExtensionWarningSet* conflicting_extensions, |
482 const net::BoundNetLog* net_log) { | 481 const net::BoundNetLog* net_log) { |
483 MergeRedirectUrlOfResponses(deltas, new_url, conflicting_extensions, net_log); | 482 MergeRedirectUrlOfResponses(deltas, new_url, conflicting_extensions, net_log); |
484 } | 483 } |
485 | 484 |
486 // Assumes that |header_value| is the cookie header value of a HTTP Request | |
487 // following the cookie-string schema of RFC 6265, section 4.2.1, and returns | |
488 // cookie name/value pairs. If cookie values are presented in double quotes, | |
489 // these will appear in |parsed| as well. We can assume that the cookie header | |
490 // is written by Chromium and therefore, well-formed. | |
491 static void ParseRequestCookieLine( | |
492 const std::string& header_value, | |
493 ParsedRequestCookies* parsed_cookies) { | |
494 std::string::const_iterator i = header_value.begin(); | |
495 while (i != header_value.end()) { | |
496 // Here we are at the beginning of a cookie. | |
497 | |
498 // Eat whitespace. | |
499 while (i != header_value.end() && *i == ' ') ++i; | |
500 if (i == header_value.end()) return; | |
501 | |
502 // Find cookie name. | |
503 std::string::const_iterator cookie_name_beginning = i; | |
504 while (i != header_value.end() && *i != '=') ++i; | |
505 base::StringPiece cookie_name(cookie_name_beginning, i); | |
506 | |
507 // Find cookie value. | |
508 base::StringPiece cookie_value; | |
509 if (i != header_value.end()) { // Cookies may have no value. | |
510 ++i; // Skip '='. | |
511 std::string::const_iterator cookie_value_beginning = i; | |
512 if (*i == '"') { | |
513 ++i; // Skip '"'. | |
514 while (i != header_value.end() && *i != '"') ++i; | |
515 if (i == header_value.end()) return; | |
516 ++i; // Skip '"'. | |
517 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
518 // i points to character after '"', potentially a ';' | |
519 } else { | |
520 while (i != header_value.end() && *i != ';') ++i; | |
521 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
522 // i points to ';' or end of string. | |
523 } | |
524 } | |
525 parsed_cookies->push_back(make_pair(cookie_name, cookie_value)); | |
526 // Eat ';' | |
527 if (i != header_value.end()) ++i; | |
528 } | |
529 } | |
530 | |
531 // Writes all cookies of |parsed_cookies| into a HTTP Request header value | |
532 // that belongs to the "Cookie" header. | |
533 static std::string SerializeRequestCookieLine( | |
534 const ParsedRequestCookies& parsed_cookies) { | |
535 std::string buffer; | |
536 for (ParsedRequestCookies::const_iterator i = parsed_cookies.begin(); | |
537 i != parsed_cookies.end(); ++i) { | |
538 if (!buffer.empty()) | |
539 buffer += "; "; | |
540 buffer += i->first.as_string(); | |
541 if (!i->second.empty()) | |
542 buffer += "=" + i->second.as_string(); | |
543 } | |
544 return buffer; | |
545 } | |
546 | |
547 static bool DoesRequestCookieMatchFilter( | 485 static bool DoesRequestCookieMatchFilter( |
548 const ParsedRequestCookie& cookie, | 486 const ParsedRequestCookie& cookie, |
549 RequestCookie* filter) { | 487 RequestCookie* filter) { |
550 if (!filter) return true; | 488 if (!filter) return true; |
551 if (filter->name.get() && cookie.first != *filter->name) return false; | 489 if (filter->name.get() && cookie.first != *filter->name) return false; |
552 if (filter->value.get() && cookie.second != *filter->value) return false; | 490 if (filter->value.get() && cookie.second != *filter->value) return false; |
553 return true; | 491 return true; |
554 } | 492 } |
555 | 493 |
556 // Applies all CookieModificationType::ADD operations for request cookies of | 494 // Applies all CookieModificationType::ADD operations for request cookies of |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 cookie_modifications_exist |= | 612 cookie_modifications_exist |= |
675 !(*delta)->request_cookie_modifications.empty(); | 613 !(*delta)->request_cookie_modifications.empty(); |
676 } | 614 } |
677 if (!cookie_modifications_exist) | 615 if (!cookie_modifications_exist) |
678 return; | 616 return; |
679 | 617 |
680 // Parse old cookie line. | 618 // Parse old cookie line. |
681 std::string cookie_header; | 619 std::string cookie_header; |
682 request_headers->GetHeader(net::HttpRequestHeaders::kCookie, &cookie_header); | 620 request_headers->GetHeader(net::HttpRequestHeaders::kCookie, &cookie_header); |
683 ParsedRequestCookies cookies; | 621 ParsedRequestCookies cookies; |
684 ParseRequestCookieLine(cookie_header, &cookies); | 622 net::cookie_util::ParseRequestCookieLine(cookie_header, &cookies); |
685 | 623 |
686 // Modify cookies. | 624 // Modify cookies. |
687 bool modified = false; | 625 bool modified = false; |
688 modified |= MergeAddRequestCookieModifications(deltas, &cookies); | 626 modified |= MergeAddRequestCookieModifications(deltas, &cookies); |
689 modified |= MergeEditRequestCookieModifications(deltas, &cookies); | 627 modified |= MergeEditRequestCookieModifications(deltas, &cookies); |
690 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); | 628 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); |
691 | 629 |
692 // Reassemble and store new cookie line. | 630 // Reassemble and store new cookie line. |
693 if (modified) { | 631 if (modified) { |
694 std::string new_cookie_header = SerializeRequestCookieLine(cookies); | 632 std::string new_cookie_header = |
| 633 net::cookie_util::SerializeRequestCookieLine(cookies); |
695 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, | 634 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, |
696 new_cookie_header); | 635 new_cookie_header); |
697 } | 636 } |
698 } | 637 } |
699 | 638 |
700 // Returns the extension ID of the first extension in |deltas| that sets the | 639 // Returns the extension ID of the first extension in |deltas| that sets the |
701 // request header identified by |key| to |value|. | 640 // request header identified by |key| to |value|. |
702 static std::string FindSetRequestHeader( | 641 static std::string FindSetRequestHeader( |
703 const EventResponseDeltas& deltas, | 642 const EventResponseDeltas& deltas, |
704 const std::string& key, | 643 const std::string& key, |
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 return net::HttpUtil::IsToken(name); | 1254 return net::HttpUtil::IsToken(name); |
1316 } | 1255 } |
1317 | 1256 |
1318 bool IsValidHeaderValue(const std::string& value) { | 1257 bool IsValidHeaderValue(const std::string& value) { |
1319 // Just a sanity check: disallow NUL and CRLF. | 1258 // Just a sanity check: disallow NUL and CRLF. |
1320 return value.find('\0') == std::string::npos && | 1259 return value.find('\0') == std::string::npos && |
1321 value.find("\r\n") == std::string::npos; | 1260 value.find("\r\n") == std::string::npos; |
1322 } | 1261 } |
1323 | 1262 |
1324 } // namespace extension_web_request_api_helpers | 1263 } // namespace extension_web_request_api_helpers |
OLD | NEW |