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 #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 "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/string_number_conversions.h" | |
| 8 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 9 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 10 #include "base/values.h" | 11 #include "base/values.h" |
| 11 #include "chrome/browser/extensions/api/web_request/web_request_api.h" | 12 #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
| 12 #include "chrome/common/url_constants.h" | 13 #include "chrome/common/url_constants.h" |
| 13 #include "net/base/net_log.h" | 14 #include "net/base/net_log.h" |
| 15 #include "net/cookies/cookie_monster.h" | |
| 14 #include "net/http/http_util.h" | 16 #include "net/http/http_util.h" |
| 15 #include "net/url_request/url_request.h" | 17 #include "net/url_request/url_request.h" |
| 16 | 18 |
| 17 namespace extension_web_request_api_helpers { | 19 namespace extension_web_request_api_helpers { |
| 18 | 20 |
| 19 namespace { | 21 namespace { |
| 20 | 22 |
| 23 // A ParsedRequestCookie consists of the key and value of the cookie. | |
| 24 typedef std::pair<base::StringPiece, base::StringPiece> ParsedRequestCookie; | |
| 25 typedef std::vector<ParsedRequestCookie> ParsedRequestCookies; | |
| 26 typedef std::vector<linked_ptr<net::CookieMonster::MutableParsedCookie> > | |
| 27 ParsedResponseCookies; | |
| 28 | |
| 21 static const char* kResourceTypeStrings[] = { | 29 static const char* kResourceTypeStrings[] = { |
| 22 "main_frame", | 30 "main_frame", |
| 23 "sub_frame", | 31 "sub_frame", |
| 24 "stylesheet", | 32 "stylesheet", |
| 25 "script", | 33 "script", |
| 26 "image", | 34 "image", |
| 27 "object", | 35 "object", |
| 28 "xmlhttprequest", | 36 "xmlhttprequest", |
| 29 "other", | 37 "other", |
| 30 "other", | 38 "other", |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 46 // entry is no longer required, this should be removed. | 54 // entry is no longer required, this should be removed. |
| 47 ResourceType::LAST_TYPE, | 55 ResourceType::LAST_TYPE, |
| 48 }; | 56 }; |
| 49 | 57 |
| 50 COMPILE_ASSERT( | 58 COMPILE_ASSERT( |
| 51 arraysize(kResourceTypeStrings) == arraysize(kResourceTypeValues), | 59 arraysize(kResourceTypeStrings) == arraysize(kResourceTypeValues), |
| 52 keep_resource_types_in_sync); | 60 keep_resource_types_in_sync); |
| 53 | 61 |
| 54 } // namespace | 62 } // namespace |
| 55 | 63 |
| 64 RequestCookie::RequestCookie() {} | |
| 65 RequestCookie::~RequestCookie() {} | |
| 66 | |
| 67 ResponseCookie::ResponseCookie() {} | |
| 68 ResponseCookie::~ResponseCookie() {} | |
| 69 | |
| 70 RequestCookieModification::RequestCookieModification() {} | |
| 71 RequestCookieModification::~RequestCookieModification() {} | |
| 72 | |
| 73 ResponseCookieModification::ResponseCookieModification() : type(ADD) {} | |
| 74 ResponseCookieModification::~ResponseCookieModification() {} | |
| 56 | 75 |
| 57 EventResponseDelta::EventResponseDelta( | 76 EventResponseDelta::EventResponseDelta( |
| 58 const std::string& extension_id, const base::Time& extension_install_time) | 77 const std::string& extension_id, const base::Time& extension_install_time) |
| 59 : extension_id(extension_id), | 78 : extension_id(extension_id), |
| 60 extension_install_time(extension_install_time), | 79 extension_install_time(extension_install_time), |
| 61 cancel(false) { | 80 cancel(false) { |
| 62 } | 81 } |
| 63 | 82 |
| 64 EventResponseDelta::~EventResponseDelta() { | 83 EventResponseDelta::~EventResponseDelta() { |
| 65 } | 84 } |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 // special case as they represent a way of cancelling a request. | 334 // special case as they represent a way of cancelling a request. |
| 316 if (MergeOnBeforeRequestResponsesHelper( | 335 if (MergeOnBeforeRequestResponsesHelper( |
| 317 deltas, new_url, conflicting_extensions, net_log, true)) { | 336 deltas, new_url, conflicting_extensions, net_log, true)) { |
| 318 // If any extension cancelled a request by redirecting to a data:// URL or | 337 // If any extension cancelled a request by redirecting to a data:// URL or |
| 319 // about:blank, we don't consider the other redirects. | 338 // about:blank, we don't consider the other redirects. |
| 320 return; | 339 return; |
| 321 } | 340 } |
| 322 | 341 |
| 323 // Handle all other redirects. | 342 // Handle all other redirects. |
| 324 MergeOnBeforeRequestResponsesHelper( | 343 MergeOnBeforeRequestResponsesHelper( |
| 325 deltas, new_url, conflicting_extensions, net_log, false); | 344 deltas, new_url, conflicting_extensions, net_log, false); |
| 345 } | |
| 346 | |
| 347 // Assumes that |header_value| is the cookie header value of a HTTP Request | |
| 348 // following the cookie-string schema of RFC 6265, section 4.2.1, and returns | |
| 349 // cookie name/value pairs. If cookie values are presented in double quotes, | |
| 350 // these will appear in |parsed| as well. We can assume that the cookie header | |
| 351 // is written by Chromium and therefore, well-formed. | |
| 352 static void ParseRequestCookieLine( | |
|
Matt Perry
2012/07/09 23:26:13
We already have cookie parsing code in net/. Can w
battre
2012/08/02 17:17:34
net/ has parsing code for *response* cookie lines.
Matt Perry
2012/08/02 17:37:51
I see. And I presume there's no way to pull the st
| |
| 353 const std::string& header_value, | |
| 354 ParsedRequestCookies* parsed_cookies) { | |
| 355 std::string::const_iterator i = header_value.begin(); | |
| 356 while (i != header_value.end()) { | |
| 357 // Here we are at the beginning of a cookie. | |
| 358 | |
| 359 // Eat whitespace. | |
| 360 while (i != header_value.end() && *i == ' ') ++i; | |
| 361 if (i == header_value.end()) return; | |
| 362 | |
| 363 // Find cookie name. | |
| 364 std::string::const_iterator cookie_name_beginning = i; | |
| 365 while (i != header_value.end() && *i != '=') ++i; | |
| 366 if (i == header_value.end()) return; | |
| 367 base::StringPiece cookie_name(cookie_name_beginning, i); | |
| 368 | |
| 369 // Find cookie value. | |
| 370 ++i; // Skip '='. | |
| 371 std::string::const_iterator cookie_value_beginning = i; | |
| 372 base::StringPiece cookie_value; | |
| 373 if (*i == '"') { | |
| 374 while (i != header_value.end() && *i != '"') ++i; | |
| 375 if (i == header_value.end()) return; | |
| 376 ++i; // Skip '"'. | |
| 377 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
| 378 // i points to character after '"', potentially a ';' | |
| 379 } else { | |
| 380 while (i != header_value.end() && *i != ';') ++i; | |
| 381 cookie_value = base::StringPiece(cookie_value_beginning, i); | |
| 382 // i points to ';' or end of string. | |
| 383 } | |
| 384 parsed_cookies->push_back(make_pair(cookie_name, cookie_value)); | |
| 385 // Eat ';' | |
| 386 if (i != header_value.end()) ++i; | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 // Writes all cookies of |parsed_cookies| into a HTTP Request header value | |
| 391 // that belongs to the "Cookie" header. | |
| 392 static std::string SerializeRequestCookieLine( | |
| 393 const ParsedRequestCookies& parsed_cookies) { | |
| 394 std::string buffer; | |
| 395 for (ParsedRequestCookies::const_iterator i = parsed_cookies.begin(); | |
| 396 i != parsed_cookies.end(); ++i) { | |
| 397 if (!buffer.empty()) | |
| 398 buffer += "; "; | |
| 399 buffer += i->first.as_string() + "=" + i->second.as_string(); | |
| 400 } | |
| 401 return buffer; | |
| 402 } | |
| 403 | |
| 404 static bool DoesRequestCookieMatchFilter( | |
| 405 const ParsedRequestCookie& cookie, | |
| 406 RequestCookie* filter) { | |
| 407 if (!filter) return true; | |
| 408 if (filter->name.get() && cookie.first != *filter->name) return false; | |
| 409 if (filter->value.get() && cookie.second != *filter->value) return false; | |
| 410 return true; | |
| 411 } | |
| 412 | |
| 413 // Applies all CookieModificationType::ADD operations for request cookies of | |
| 414 // |deltas| to |cookies|. Returns whether any cookie was added. | |
| 415 static bool MergeAddRequestCookieModifications( | |
| 416 const EventResponseDeltas& deltas, | |
| 417 ParsedRequestCookies* cookies) { | |
| 418 bool modified = false; | |
| 419 // We assume here that the deltas are sorted in decreasing extension | |
| 420 // precedence (i.e. decreasing extension installation time). | |
| 421 EventResponseDeltas::const_reverse_iterator delta; | |
| 422 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
| 423 const RequestCookieModifications& modifications = | |
| 424 (*delta)->request_cookie_modifications; | |
| 425 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
| 426 mod != modifications.end(); ++mod) { | |
| 427 if ((*mod)->type != ADD || !(*mod)->modification.get()) | |
| 428 continue; | |
| 429 std::string* new_name = (*mod)->modification->name.get(); | |
| 430 std::string* new_value = (*mod)->modification->value.get(); | |
| 431 if (!new_name || !new_value) | |
| 432 continue; | |
| 433 | |
| 434 bool cookie_with_same_name_found = false; | |
| 435 for (ParsedRequestCookies::iterator cookie = cookies->begin(); | |
| 436 cookie != cookies->end() && !cookie_with_same_name_found; ++cookie) { | |
| 437 if (cookie->first == *new_name) { | |
| 438 if (cookie->second != *new_value) { | |
| 439 cookie->second = *new_value; | |
| 440 modified = true; | |
| 441 } | |
| 442 cookie_with_same_name_found = true; | |
| 443 } | |
| 444 } | |
| 445 if (!cookie_with_same_name_found) { | |
| 446 cookies->push_back(std::make_pair(*new_name, *new_value)); | |
| 447 modified = true; | |
| 448 } | |
| 449 } | |
| 450 } | |
| 451 return modified; | |
| 452 } | |
| 453 | |
| 454 // Applies all CookieModificationType::EDIT operations for request cookies of | |
| 455 // |deltas| to |cookies|. Returns whether any cookie was modified. | |
| 456 static bool MergeEditRequestCookieModifications( | |
| 457 const EventResponseDeltas& deltas, | |
| 458 ParsedRequestCookies* cookies) { | |
| 459 bool modified = false; | |
| 460 // We assume here that the deltas are sorted in decreasing extension | |
| 461 // precedence (i.e. decreasing extension installation time). | |
| 462 EventResponseDeltas::const_reverse_iterator delta; | |
| 463 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
| 464 const RequestCookieModifications& modifications = | |
| 465 (*delta)->request_cookie_modifications; | |
| 466 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
| 467 mod != modifications.end(); ++mod) { | |
| 468 if ((*mod)->type != EDIT || !(*mod)->modification.get()) | |
| 469 continue; | |
| 470 | |
| 471 std::string* new_value = (*mod)->modification->value.get(); | |
| 472 RequestCookie* filter = (*mod)->filter.get(); | |
| 473 for (ParsedRequestCookies::iterator cookie = cookies->begin(); | |
| 474 cookie != cookies->end(); ++cookie) { | |
| 475 if (!DoesRequestCookieMatchFilter(*cookie, filter)) | |
| 476 continue; | |
| 477 // If the edit operation tries to modify the cookie name, we just ignore | |
| 478 // this. We only modify the cookie value. | |
| 479 if (new_value && cookie->second != *new_value) { | |
| 480 cookie->second = *new_value; | |
| 481 modified = true; | |
| 482 } | |
| 483 } | |
| 484 } | |
| 485 } | |
| 486 return modified; | |
| 487 } | |
| 488 | |
| 489 // Applies all CookieModificationType::REMOVE operations for request cookies of | |
| 490 // |deltas| to |cookies|. Returns whether any cookie was deleted. | |
| 491 static bool MergeRemoveRequestCookieModifications( | |
| 492 const EventResponseDeltas& deltas, | |
| 493 ParsedRequestCookies* cookies) { | |
| 494 bool modified = false; | |
| 495 // We assume here that the deltas are sorted in decreasing extension | |
| 496 // precedence (i.e. decreasing extension installation time). | |
| 497 EventResponseDeltas::const_reverse_iterator delta; | |
| 498 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
| 499 const RequestCookieModifications& modifications = | |
| 500 (*delta)->request_cookie_modifications; | |
| 501 for (RequestCookieModifications::const_iterator mod = modifications.begin(); | |
| 502 mod != modifications.end(); ++mod) { | |
| 503 if ((*mod)->type != REMOVE) | |
| 504 continue; | |
| 505 | |
| 506 RequestCookie* filter = (*mod)->filter.get(); | |
| 507 ParsedRequestCookies::iterator i = cookies->begin(); | |
| 508 while (i != cookies->end()) { | |
| 509 if (DoesRequestCookieMatchFilter(*i, filter)) { | |
| 510 i = cookies->erase(i); | |
| 511 modified = true; | |
| 512 } else { | |
| 513 ++i; | |
| 514 } | |
| 515 } | |
| 516 } | |
| 517 } | |
| 518 return modified; | |
| 519 } | |
| 520 | |
| 521 void MergeCookiesInOnBeforeSendHeadersResponses( | |
| 522 const EventResponseDeltas& deltas, | |
| 523 net::HttpRequestHeaders* request_headers, | |
| 524 std::set<std::string>* conflicting_extensions, | |
| 525 const net::BoundNetLog* net_log) { | |
| 526 // Skip all work if there are no registered cookie modifications. | |
| 527 bool cookie_modifications_exist = false; | |
| 528 EventResponseDeltas::const_iterator delta; | |
| 529 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | |
| 530 cookie_modifications_exist |= | |
| 531 !(*delta)->request_cookie_modifications.empty(); | |
| 532 } | |
| 533 if (!cookie_modifications_exist) | |
| 534 return; | |
| 535 | |
| 536 // Parse old cookie line. | |
| 537 std::string cookie_header; | |
| 538 request_headers->GetHeader(net::HttpRequestHeaders::kCookie, &cookie_header); | |
| 539 ParsedRequestCookies cookies; | |
| 540 ParseRequestCookieLine(cookie_header, &cookies); | |
| 541 | |
| 542 // Modify cookies. | |
| 543 bool modified = false; | |
| 544 modified |= MergeAddRequestCookieModifications(deltas, &cookies); | |
| 545 modified |= MergeEditRequestCookieModifications(deltas, &cookies); | |
| 546 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); | |
| 547 | |
| 548 // Resemble and store new cookie line. | |
|
Matt Perry
2012/07/09 23:26:13
Reassemble*
battre
2012/08/02 17:17:34
Done.
| |
| 549 if (modified) { | |
| 550 std::string new_cookie_header = SerializeRequestCookieLine(cookies); | |
| 551 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, | |
| 552 new_cookie_header); | |
| 553 } | |
| 326 } | 554 } |
| 327 | 555 |
| 328 void MergeOnBeforeSendHeadersResponses( | 556 void MergeOnBeforeSendHeadersResponses( |
| 329 const EventResponseDeltas& deltas, | 557 const EventResponseDeltas& deltas, |
| 330 net::HttpRequestHeaders* request_headers, | 558 net::HttpRequestHeaders* request_headers, |
| 331 std::set<std::string>* conflicting_extensions, | 559 std::set<std::string>* conflicting_extensions, |
| 332 const net::BoundNetLog* net_log) { | 560 const net::BoundNetLog* net_log) { |
| 333 EventResponseDeltas::const_iterator delta; | 561 EventResponseDeltas::const_iterator delta; |
| 334 | 562 |
| 335 // Here we collect which headers we have removed or set to new values | 563 // Here we collect which headers we have removed or set to new values |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 net_log->AddEvent( | 639 net_log->AddEvent( |
| 412 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 640 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
| 413 base::Bind(&NetLogModificationCallback, delta->get())); | 641 base::Bind(&NetLogModificationCallback, delta->get())); |
| 414 } else { | 642 } else { |
| 415 conflicting_extensions->insert((*delta)->extension_id); | 643 conflicting_extensions->insert((*delta)->extension_id); |
| 416 net_log->AddEvent( | 644 net_log->AddEvent( |
| 417 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 645 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 418 CreateNetLogExtensionIdCallback(delta->get())); | 646 CreateNetLogExtensionIdCallback(delta->get())); |
| 419 } | 647 } |
| 420 } | 648 } |
| 649 | |
| 650 MergeCookiesInOnBeforeSendHeadersResponses(deltas, request_headers, | |
| 651 conflicting_extensions, net_log); | |
| 652 } | |
| 653 | |
| 654 // Retrives all cookies from |override_response_headers|. | |
| 655 static ParsedResponseCookies GetResponseCookies( | |
| 656 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { | |
| 657 ParsedResponseCookies result; | |
| 658 | |
| 659 void* iter = NULL; | |
| 660 std::string value; | |
| 661 while (override_response_headers->EnumerateHeader(&iter, "Set-Cookie", | |
| 662 &value)) { | |
| 663 result.push_back(make_linked_ptr( | |
| 664 new net::CookieMonster::MutableParsedCookie(value))); | |
| 665 } | |
| 666 return result; | |
| 667 } | |
| 668 | |
| 669 // Stores all |cookies| in |override_response_headers| deleting previously | |
| 670 // existing cookie definitions. | |
| 671 static void StoreResponseCookies( | |
| 672 const ParsedResponseCookies& cookies, | |
| 673 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { | |
| 674 override_response_headers->RemoveHeader("Set-Cookie"); | |
| 675 for (ParsedResponseCookies::const_iterator i = cookies.begin(); | |
| 676 i != cookies.end(); ++i) { | |
| 677 override_response_headers->AddHeader("Set-Cookie: " + (*i)->ToCookieLine()); | |
| 678 } | |
| 679 } | |
| 680 | |
| 681 // Modifies |cookie| according to |modification|. Each value that is set in | |
| 682 // |modification| is applied to |cookie|. | |
| 683 static bool ApplyResponseCookieModification( | |
| 684 ResponseCookie* modification, | |
| 685 net::CookieMonster::MutableParsedCookie* cookie) { | |
| 686 bool modified = false; | |
| 687 if (modification->name.get()) | |
| 688 modified |= cookie->SetName(*modification->name); | |
| 689 if (modification->value.get()) | |
| 690 modified |= cookie->SetValue(*modification->value); | |
| 691 if (modification->expires.get()) | |
| 692 modified |= cookie->SetExpires(*modification->expires); | |
| 693 if (modification->max_age.get()) | |
| 694 modified |= cookie->SetMaxAge(base::IntToString(*modification->max_age)); | |
| 695 if (modification->domain.get()) | |
| 696 modified |= cookie->SetDomain(*modification->domain); | |
| 697 if (modification->path.get()) | |
| 698 modified |= cookie->SetPath(*modification->path); | |
| 699 if (modification->secure.get()) | |
| 700 modified |= cookie->SetIsSecure(*modification->secure); | |
| 701 if (modification->http_only.get()) | |
| 702 modified |= cookie->SetIsHttpOnly(*modification->http_only); | |
| 703 return modified; | |
| 704 } | |
| 705 | |
| 706 static bool DoesResponseCookieMatchFilter( | |
| 707 net::CookieMonster::MutableParsedCookie* cookie, | |
| 708 ResponseCookie* filter) { | |
| 709 if (!cookie->IsValid()) return false; | |
| 710 if (!filter) return true; | |
| 711 if (filter->name.get() && cookie->Name() != *filter->name) return false; | |
| 712 if (filter->value.get() && cookie->Value() != *filter->value) return false; | |
| 713 if (filter->expires.get()) { | |
| 714 std::string actual_value = cookie->HasExpires() ? cookie->Expires() : ""; | |
| 715 if (actual_value != *filter->expires) | |
| 716 return false; | |
| 717 } | |
| 718 if (filter->max_age.get()) { | |
| 719 std::string actual_value = cookie->HasMaxAge() ? cookie->MaxAge() : ""; | |
| 720 if (actual_value != base::IntToString(*filter->max_age)) | |
| 721 return false; | |
| 722 } | |
| 723 if (filter->domain.get()) { | |
| 724 std::string actual_value = cookie->HasDomain() ? cookie->Domain() : ""; | |
| 725 if (actual_value != *filter->domain) | |
| 726 return false; | |
| 727 } | |
| 728 if (filter->path.get()) { | |
| 729 std::string actual_value = cookie->HasPath() ? cookie->Path() : ""; | |
| 730 if (actual_value != *filter->path) | |
| 731 return false; | |
| 732 } | |
| 733 if (filter->secure.get() && cookie->IsSecure() != *filter->secure) | |
| 734 return false; | |
| 735 if (filter->http_only.get() && cookie->IsHttpOnly() != *filter->http_only) | |
| 736 return false; | |
| 737 return true; | |
| 738 } | |
| 739 | |
| 740 // Applies all CookieModificationType::ADD operations for response cookies of | |
| 741 // |deltas| to |cookies|. Returns whether any cookie was added. | |
| 742 static bool MergeAddResponseCookieModifications( | |
| 743 const EventResponseDeltas& deltas, | |
| 744 ParsedResponseCookies* cookies) { | |
| 745 bool modified = false; | |
| 746 // We assume here that the deltas are sorted in decreasing extension | |
| 747 // precedence (i.e. decreasing extension installation time). | |
| 748 EventResponseDeltas::const_reverse_iterator delta; | |
| 749 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
| 750 const ResponseCookieModifications& modifications = | |
| 751 (*delta)->response_cookie_modifications; | |
| 752 for (ResponseCookieModifications::const_iterator mod = | |
| 753 modifications.begin(); mod != modifications.end(); ++mod) { | |
| 754 if ((*mod)->type != ADD || !(*mod)->modification.get()) | |
| 755 continue; | |
| 756 // Cookie names are not unique in response cookies so we always append | |
| 757 // and never override. | |
| 758 linked_ptr<net::CookieMonster::MutableParsedCookie> cookie = | |
| 759 make_linked_ptr(new net::CookieMonster::MutableParsedCookie("")); | |
| 760 ApplyResponseCookieModification((*mod)->modification.get(), cookie.get()); | |
| 761 cookies->push_back(cookie); | |
| 762 modified = true; | |
| 763 } | |
| 764 } | |
| 765 return modified; | |
| 766 } | |
| 767 | |
| 768 // Applies all CookieModificationType::EDIT operations for response cookies of | |
| 769 // |deltas| to |cookies|. Returns whether any cookie was modified. | |
| 770 static bool MergeEditResponseCookieModifications( | |
| 771 const EventResponseDeltas& deltas, | |
| 772 ParsedResponseCookies* cookies) { | |
| 773 bool modified = false; | |
| 774 // We assume here that the deltas are sorted in decreasing extension | |
| 775 // precedence (i.e. decreasing extension installation time). | |
| 776 EventResponseDeltas::const_reverse_iterator delta; | |
| 777 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
| 778 const ResponseCookieModifications& modifications = | |
| 779 (*delta)->response_cookie_modifications; | |
| 780 for (ResponseCookieModifications::const_iterator mod = | |
| 781 modifications.begin(); mod != modifications.end(); ++mod) { | |
| 782 if ((*mod)->type != EDIT || !(*mod)->modification.get()) | |
| 783 continue; | |
| 784 | |
| 785 for (ParsedResponseCookies::iterator cookie = cookies->begin(); | |
| 786 cookie != cookies->end(); ++cookie) { | |
| 787 if (DoesResponseCookieMatchFilter(cookie->get(), | |
| 788 (*mod)->filter.get())) { | |
| 789 modified |= ApplyResponseCookieModification( | |
| 790 (*mod)->modification.get(), cookie->get()); | |
| 791 } | |
| 792 } | |
| 793 } | |
| 794 } | |
| 795 return modified; | |
| 796 } | |
| 797 | |
| 798 // Applies all CookieModificationType::REMOVE operations for response cookies of | |
| 799 // |deltas| to |cookies|. Returns whether any cookie was deleteds. | |
|
Matt Perry
2012/07/09 23:26:13
deleted*
battre
2012/08/02 17:17:34
Done.
| |
| 800 static bool MergeRemoveResponseCookieModifications( | |
| 801 const EventResponseDeltas& deltas, | |
| 802 ParsedResponseCookies* cookies) { | |
| 803 bool modified = false; | |
| 804 // We assume here that the deltas are sorted in decreasing extension | |
| 805 // precedence (i.e. decreasing extension installation time). | |
| 806 EventResponseDeltas::const_reverse_iterator delta; | |
| 807 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
| 808 const ResponseCookieModifications& modifications = | |
| 809 (*delta)->response_cookie_modifications; | |
| 810 for (ResponseCookieModifications::const_iterator mod = | |
| 811 modifications.begin(); mod != modifications.end(); ++mod) { | |
| 812 if ((*mod)->type != REMOVE) | |
| 813 continue; | |
| 814 | |
| 815 ParsedResponseCookies::iterator i = cookies->begin(); | |
| 816 while (i != cookies->end()) { | |
| 817 if (DoesResponseCookieMatchFilter(i->get(), | |
| 818 (*mod)->filter.get())) { | |
| 819 i = cookies->erase(i); | |
| 820 modified = true; | |
| 821 } else { | |
| 822 ++i; | |
| 823 } | |
| 824 } | |
| 825 } | |
| 826 } | |
| 827 return modified; | |
| 828 } | |
| 829 | |
| 830 void MergeCookiesInOnHeadersReceivedResponses( | |
| 831 const EventResponseDeltas& deltas, | |
| 832 const net::HttpResponseHeaders* original_response_headers, | |
| 833 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, | |
| 834 std::set<std::string>* conflicting_extensions, | |
| 835 const net::BoundNetLog* net_log) { | |
| 836 // Skip all work if there are no registered cookie modifications. | |
| 837 bool cookie_modifications_exist = false; | |
| 838 EventResponseDeltas::const_reverse_iterator delta; | |
| 839 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | |
| 840 cookie_modifications_exist |= | |
| 841 !(*delta)->response_cookie_modifications.empty(); | |
| 842 } | |
| 843 if (!cookie_modifications_exist) | |
| 844 return; | |
| 845 | |
| 846 // Only create a copy if we really want to modify the response headers. | |
| 847 if (override_response_headers->get() == NULL) { | |
| 848 *override_response_headers = new net::HttpResponseHeaders( | |
| 849 original_response_headers->raw_headers()); | |
| 850 } | |
| 851 | |
| 852 ParsedResponseCookies cookies = | |
| 853 GetResponseCookies(*override_response_headers); | |
| 854 | |
| 855 bool modified = false; | |
| 856 modified |= MergeAddResponseCookieModifications(deltas, &cookies); | |
| 857 modified |= MergeEditResponseCookieModifications(deltas, &cookies); | |
| 858 modified |= MergeRemoveResponseCookieModifications(deltas, &cookies); | |
| 859 | |
| 860 // Store new value. | |
| 861 if (modified) | |
| 862 StoreResponseCookies(cookies, *override_response_headers); | |
| 421 } | 863 } |
| 422 | 864 |
| 423 // Converts the key of the (key, value) pair to lower case. | 865 // Converts the key of the (key, value) pair to lower case. |
| 424 static ResponseHeader ToLowerCase(const ResponseHeader& header) { | 866 static ResponseHeader ToLowerCase(const ResponseHeader& header) { |
| 425 std::string lower_key(header.first); | 867 std::string lower_key(header.first); |
| 426 StringToLowerASCII(&lower_key); | 868 StringToLowerASCII(&lower_key); |
| 427 return ResponseHeader(lower_key, header.second); | 869 return ResponseHeader(lower_key, header.second); |
| 428 } | 870 } |
| 429 | 871 |
| 430 void MergeOnHeadersReceivedResponses( | 872 void MergeOnHeadersReceivedResponses( |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 496 net_log->AddEvent( | 938 net_log->AddEvent( |
| 497 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 939 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
| 498 CreateNetLogExtensionIdCallback(delta->get())); | 940 CreateNetLogExtensionIdCallback(delta->get())); |
| 499 } else { | 941 } else { |
| 500 conflicting_extensions->insert((*delta)->extension_id); | 942 conflicting_extensions->insert((*delta)->extension_id); |
| 501 net_log->AddEvent( | 943 net_log->AddEvent( |
| 502 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 944 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 503 CreateNetLogExtensionIdCallback(delta->get())); | 945 CreateNetLogExtensionIdCallback(delta->get())); |
| 504 } | 946 } |
| 505 } | 947 } |
| 948 | |
| 949 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers, | |
| 950 override_response_headers, conflicting_extensions, net_log); | |
| 506 } | 951 } |
| 507 | 952 |
| 508 bool MergeOnAuthRequiredResponses( | 953 bool MergeOnAuthRequiredResponses( |
| 509 const EventResponseDeltas& deltas, | 954 const EventResponseDeltas& deltas, |
| 510 net::AuthCredentials* auth_credentials, | 955 net::AuthCredentials* auth_credentials, |
| 511 std::set<std::string>* conflicting_extensions, | 956 std::set<std::string>* conflicting_extensions, |
| 512 const net::BoundNetLog* net_log) { | 957 const net::BoundNetLog* net_log) { |
| 513 CHECK(auth_credentials); | 958 CHECK(auth_credentials); |
| 514 bool credentials_set = false; | 959 bool credentials_set = false; |
| 515 | 960 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 618 ResourceType::Type* type) { | 1063 ResourceType::Type* type) { |
| 619 const char** iter = | 1064 const char** iter = |
| 620 std::find(kResourceTypeStrings, ARRAYEND(kResourceTypeStrings), type_str); | 1065 std::find(kResourceTypeStrings, ARRAYEND(kResourceTypeStrings), type_str); |
| 621 if (iter == ARRAYEND(kResourceTypeStrings)) | 1066 if (iter == ARRAYEND(kResourceTypeStrings)) |
| 622 return false; | 1067 return false; |
| 623 *type = kResourceTypeValues[iter - kResourceTypeStrings]; | 1068 *type = kResourceTypeValues[iter - kResourceTypeStrings]; |
| 624 return true; | 1069 return true; |
| 625 } | 1070 } |
| 626 | 1071 |
| 627 } // namespace extension_web_request_api_helpers | 1072 } // namespace extension_web_request_api_helpers |
| OLD | NEW |