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_number_conversions.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "base/values.h" | 11 #include "base/values.h" |
| 12 #include "chrome/browser/extensions/api/web_request/web_request_api.h" | 12 #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
| 13 #include "chrome/browser/extensions/extension_warning_set.h" | |
| 13 #include "chrome/browser/renderer_host/web_cache_manager.h" | 14 #include "chrome/browser/renderer_host/web_cache_manager.h" |
| 14 #include "chrome/common/url_constants.h" | 15 #include "chrome/common/url_constants.h" |
| 15 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
| 16 #include "net/base/net_log.h" | 17 #include "net/base/net_log.h" |
| 17 #include "net/cookies/parsed_cookie.h" | 18 #include "net/cookies/parsed_cookie.h" |
| 18 #include "net/http/http_util.h" | 19 #include "net/http/http_util.h" |
| 19 #include "net/url_request/url_request.h" | 20 #include "net/url_request/url_request.h" |
| 20 | 21 |
| 21 namespace extension_web_request_api_helpers { | 22 namespace extension_web_request_api_helpers { |
| 22 | 23 |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 // Helper function for MergeOnBeforeRequestResponses() that allows ignoring | 292 // Helper function for MergeOnBeforeRequestResponses() that allows ignoring |
| 292 // all redirects but those to data:// urls and about:blank. This is important | 293 // all redirects but those to data:// urls and about:blank. This is important |
| 293 // to treat these URLs as "cancel urls", i.e. URLs that extensions redirect | 294 // to treat these URLs as "cancel urls", i.e. URLs that extensions redirect |
| 294 // to if they want to express that they want to cancel a request. This reduces | 295 // to if they want to express that they want to cancel a request. This reduces |
| 295 // the number of conflicts that we need to flag, as canceling is considered | 296 // the number of conflicts that we need to flag, as canceling is considered |
| 296 // a higher precedence operation that redirects. | 297 // a higher precedence operation that redirects. |
| 297 // Returns whether a redirect occurred. | 298 // Returns whether a redirect occurred. |
| 298 static bool MergeOnBeforeRequestResponsesHelper( | 299 static bool MergeOnBeforeRequestResponsesHelper( |
| 299 const EventResponseDeltas& deltas, | 300 const EventResponseDeltas& deltas, |
| 300 GURL* new_url, | 301 GURL* new_url, |
| 301 std::set<std::string>* conflicting_extensions, | 302 ExtensionWarningSet* conflicting_extensions, |
| 302 const net::BoundNetLog* net_log, | 303 const net::BoundNetLog* net_log, |
| 303 bool consider_only_cancel_scheme_urls) { | 304 bool consider_only_cancel_scheme_urls) { |
| 304 bool redirected = false; | 305 bool redirected = false; |
| 305 | 306 |
| 307 // Extension that determines the |new_url|. | |
| 308 std::string winning_extension_id; | |
| 306 EventResponseDeltas::const_iterator delta; | 309 EventResponseDeltas::const_iterator delta; |
| 307 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | 310 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| 308 if ((*delta)->new_url.is_empty()) | 311 if ((*delta)->new_url.is_empty()) |
| 309 continue; | 312 continue; |
| 310 if (consider_only_cancel_scheme_urls && | 313 if (consider_only_cancel_scheme_urls && |
| 311 !(*delta)->new_url.SchemeIs(chrome::kDataScheme) && | 314 !(*delta)->new_url.SchemeIs(chrome::kDataScheme) && |
| 312 (*delta)->new_url.spec() != "about:blank") { | 315 (*delta)->new_url.spec() != "about:blank") { |
| 313 continue; | 316 continue; |
| 314 } | 317 } |
| 315 | 318 |
| 316 if (!redirected || *new_url == (*delta)->new_url) { | 319 if (!redirected || *new_url == (*delta)->new_url) { |
| 317 *new_url = (*delta)->new_url; | 320 *new_url = (*delta)->new_url; |
| 321 winning_extension_id = (*delta)->extension_id; | |
| 318 redirected = true; | 322 redirected = true; |
| 319 net_log->AddEvent( | 323 net_log->AddEvent( |
| 320 net::NetLog::TYPE_CHROME_EXTENSION_REDIRECTED_REQUEST, | 324 net::NetLog::TYPE_CHROME_EXTENSION_REDIRECTED_REQUEST, |
| 321 CreateNetLogExtensionIdCallback(delta->get())); | 325 CreateNetLogExtensionIdCallback(delta->get())); |
| 322 } else { | 326 } else { |
| 323 conflicting_extensions->insert((*delta)->extension_id); | 327 conflicting_extensions->Insert( |
| 328 ExtensionWarning::CreateRedirectConflictWarning( | |
| 329 (*delta)->extension_id, | |
| 330 winning_extension_id, | |
| 331 (*delta)->new_url, | |
| 332 *new_url)); | |
| 324 net_log->AddEvent( | 333 net_log->AddEvent( |
| 325 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 334 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 326 CreateNetLogExtensionIdCallback(delta->get())); | 335 CreateNetLogExtensionIdCallback(delta->get())); |
| 327 } | 336 } |
| 328 } | 337 } |
| 329 return redirected; | 338 return redirected; |
| 330 } | 339 } |
| 331 | 340 |
| 332 void MergeOnBeforeRequestResponses( | 341 void MergeOnBeforeRequestResponses( |
| 333 const EventResponseDeltas& deltas, | 342 const EventResponseDeltas& deltas, |
| 334 GURL* new_url, | 343 GURL* new_url, |
| 335 std::set<std::string>* conflicting_extensions, | 344 ExtensionWarningSet* conflicting_extensions, |
| 336 const net::BoundNetLog* net_log) { | 345 const net::BoundNetLog* net_log) { |
| 337 | 346 |
| 338 // First handle only redirects to data:// URLs and about:blank. These are a | 347 // First handle only redirects to data:// URLs and about:blank. These are a |
| 339 // special case as they represent a way of cancelling a request. | 348 // special case as they represent a way of cancelling a request. |
| 340 if (MergeOnBeforeRequestResponsesHelper( | 349 if (MergeOnBeforeRequestResponsesHelper( |
| 341 deltas, new_url, conflicting_extensions, net_log, true)) { | 350 deltas, new_url, conflicting_extensions, net_log, true)) { |
| 342 // If any extension cancelled a request by redirecting to a data:// URL or | 351 // If any extension cancelled a request by redirecting to a data:// URL or |
| 343 // about:blank, we don't consider the other redirects. | 352 // about:blank, we don't consider the other redirects. |
| 344 return; | 353 return; |
| 345 } | 354 } |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 523 } | 532 } |
| 524 } | 533 } |
| 525 } | 534 } |
| 526 } | 535 } |
| 527 return modified; | 536 return modified; |
| 528 } | 537 } |
| 529 | 538 |
| 530 void MergeCookiesInOnBeforeSendHeadersResponses( | 539 void MergeCookiesInOnBeforeSendHeadersResponses( |
| 531 const EventResponseDeltas& deltas, | 540 const EventResponseDeltas& deltas, |
| 532 net::HttpRequestHeaders* request_headers, | 541 net::HttpRequestHeaders* request_headers, |
| 533 std::set<std::string>* conflicting_extensions, | 542 ExtensionWarningSet* conflicting_extensions, |
| 534 const net::BoundNetLog* net_log) { | 543 const net::BoundNetLog* net_log) { |
| 535 // Skip all work if there are no registered cookie modifications. | 544 // Skip all work if there are no registered cookie modifications. |
| 536 bool cookie_modifications_exist = false; | 545 bool cookie_modifications_exist = false; |
| 537 EventResponseDeltas::const_iterator delta; | 546 EventResponseDeltas::const_iterator delta; |
| 538 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | 547 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| 539 cookie_modifications_exist |= | 548 cookie_modifications_exist |= |
| 540 !(*delta)->request_cookie_modifications.empty(); | 549 !(*delta)->request_cookie_modifications.empty(); |
| 541 } | 550 } |
| 542 if (!cookie_modifications_exist) | 551 if (!cookie_modifications_exist) |
| 543 return; | 552 return; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 555 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); | 564 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); |
| 556 | 565 |
| 557 // Reassemble and store new cookie line. | 566 // Reassemble and store new cookie line. |
| 558 if (modified) { | 567 if (modified) { |
| 559 std::string new_cookie_header = SerializeRequestCookieLine(cookies); | 568 std::string new_cookie_header = SerializeRequestCookieLine(cookies); |
| 560 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, | 569 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, |
| 561 new_cookie_header); | 570 new_cookie_header); |
| 562 } | 571 } |
| 563 } | 572 } |
| 564 | 573 |
| 574 // Returns the extension ID of the first extension in |deltas| that sets the | |
| 575 // request header identified by |key| to |value|. | |
| 576 static std::string FindSetRequestHeader( | |
|
Matt Perry
2012/09/06 00:21:37
move helpers to the top of the file in an anon nam
battre
2012/09/06 14:25:48
I have added a TODO for this. I would like to do t
| |
| 577 const EventResponseDeltas& deltas, | |
| 578 const std::string& key, | |
| 579 const std::string& value) { | |
| 580 EventResponseDeltas::const_iterator delta; | |
| 581 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | |
| 582 net::HttpRequestHeaders::Iterator modification( | |
| 583 (*delta)->modified_request_headers); | |
| 584 while (modification.GetNext()) { | |
| 585 if (key == modification.name() && value == modification.value()) | |
| 586 return (*delta)->extension_id; | |
| 587 } | |
| 588 } | |
| 589 return ""; | |
| 590 } | |
| 591 | |
| 592 // Returns the extension ID of the first extension in |deltas| that removes the | |
| 593 // request header identified by |key|. | |
| 594 static std::string FindRemoveRequestHeader( | |
| 595 const EventResponseDeltas& deltas, | |
| 596 const std::string& key) { | |
| 597 EventResponseDeltas::const_iterator delta; | |
| 598 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | |
| 599 std::vector<std::string>::iterator i; | |
| 600 for (i = (*delta)->deleted_request_headers.begin(); | |
| 601 i != (*delta)->deleted_request_headers.end(); | |
| 602 ++i) { | |
| 603 if (*i == key) | |
| 604 return (*delta)->extension_id; | |
| 605 } | |
| 606 } | |
| 607 return ""; | |
| 608 } | |
| 609 | |
| 565 void MergeOnBeforeSendHeadersResponses( | 610 void MergeOnBeforeSendHeadersResponses( |
| 566 const EventResponseDeltas& deltas, | 611 const EventResponseDeltas& deltas, |
| 567 net::HttpRequestHeaders* request_headers, | 612 net::HttpRequestHeaders* request_headers, |
| 568 std::set<std::string>* conflicting_extensions, | 613 ExtensionWarningSet* conflicting_extensions, |
| 569 const net::BoundNetLog* net_log) { | 614 const net::BoundNetLog* net_log) { |
| 570 EventResponseDeltas::const_iterator delta; | 615 EventResponseDeltas::const_iterator delta; |
| 571 | 616 |
| 572 // Here we collect which headers we have removed or set to new values | 617 // Here we collect which headers we have removed or set to new values |
| 573 // so far due to extensions of higher precedence. | 618 // so far due to extensions of higher precedence. |
| 574 std::set<std::string> removed_headers; | 619 std::set<std::string> removed_headers; |
| 575 std::set<std::string> set_headers; | 620 std::set<std::string> set_headers; |
| 576 | 621 |
| 577 // We assume here that the deltas are sorted in decreasing extension | 622 // We assume here that the deltas are sorted in decreasing extension |
| 578 // precedence (i.e. decreasing extension installation time). | 623 // precedence (i.e. decreasing extension installation time). |
| 579 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | 624 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| 580 if ((*delta)->modified_request_headers.IsEmpty() && | 625 if ((*delta)->modified_request_headers.IsEmpty() && |
| 581 (*delta)->deleted_request_headers.empty()) { | 626 (*delta)->deleted_request_headers.empty()) { |
| 582 continue; | 627 continue; |
| 583 } | 628 } |
| 584 | 629 |
| 585 // Check whether any modification affects a request header that | 630 // Check whether any modification affects a request header that |
| 586 // has been modified differently before. As deltas is sorted by decreasing | 631 // has been modified differently before. As deltas is sorted by decreasing |
| 587 // extension installation order, this takes care of precedence. | 632 // extension installation order, this takes care of precedence. |
| 588 bool extension_conflicts = false; | 633 bool extension_conflicts = false; |
| 634 std::string winning_extension_id; | |
| 635 std::string conflicting_header; | |
| 589 { | 636 { |
| 590 net::HttpRequestHeaders::Iterator modification( | 637 net::HttpRequestHeaders::Iterator modification( |
| 591 (*delta)->modified_request_headers); | 638 (*delta)->modified_request_headers); |
| 592 while (modification.GetNext() && !extension_conflicts) { | 639 while (modification.GetNext() && !extension_conflicts) { |
| 593 // This modification sets |key| to |value|. | 640 // This modification sets |key| to |value|. |
| 594 const std::string& key = modification.name(); | 641 const std::string& key = modification.name(); |
| 595 const std::string& value = modification.value(); | 642 const std::string& value = modification.value(); |
| 596 | 643 |
| 597 // We must not delete anything that has been modified before. | 644 // We must not delete anything that has been modified before. |
| 598 if (removed_headers.find(key) != removed_headers.end()) | 645 if (removed_headers.find(key) != removed_headers.end() && |
| 646 !extension_conflicts) { | |
| 647 winning_extension_id = FindRemoveRequestHeader(deltas, key); | |
| 648 conflicting_header = key; | |
| 599 extension_conflicts = true; | 649 extension_conflicts = true; |
| 650 } | |
| 600 | 651 |
| 601 // We must not modify anything that has been set to a *different* | 652 // We must not modify anything that has been set to a *different* |
| 602 // value before. | 653 // value before. |
| 603 if (set_headers.find(key) != set_headers.end()) { | 654 if (set_headers.find(key) != set_headers.end() && |
| 655 !extension_conflicts) { | |
| 604 std::string current_value; | 656 std::string current_value; |
| 605 if (!request_headers->GetHeader(key, ¤t_value) || | 657 if (!request_headers->GetHeader(key, ¤t_value) || |
| 606 current_value != value) { | 658 current_value != value) { |
| 659 winning_extension_id = | |
| 660 FindSetRequestHeader(deltas, key, current_value); | |
| 661 conflicting_header = key; | |
| 607 extension_conflicts = true; | 662 extension_conflicts = true; |
| 608 } | 663 } |
| 609 } | 664 } |
| 610 } | 665 } |
| 611 } | 666 } |
| 612 | 667 |
| 613 // Check whether any deletion affects a request header that has been | 668 // Check whether any deletion affects a request header that has been |
| 614 // modified before. | 669 // modified before. |
| 615 { | 670 { |
| 616 std::vector<std::string>::iterator key; | 671 std::vector<std::string>::iterator key; |
| 617 for (key = (*delta)->deleted_request_headers.begin(); | 672 for (key = (*delta)->deleted_request_headers.begin(); |
| 618 key != (*delta)->deleted_request_headers.end() && | 673 key != (*delta)->deleted_request_headers.end() && |
| 619 !extension_conflicts; | 674 !extension_conflicts; |
| 620 ++key) { | 675 ++key) { |
| 621 if (set_headers.find(*key) != set_headers.end()) | 676 if (set_headers.find(*key) != set_headers.end()) { |
| 677 std::string current_value; | |
| 678 request_headers->GetHeader(*key, ¤t_value); | |
| 679 winning_extension_id = | |
| 680 FindSetRequestHeader(deltas, *key, current_value); | |
| 681 conflicting_header = *key; | |
| 622 extension_conflicts = true; | 682 extension_conflicts = true; |
| 683 } | |
| 623 } | 684 } |
| 624 } | 685 } |
| 625 | 686 |
| 626 // Now execute the modifications if there were no conflicts. | 687 // Now execute the modifications if there were no conflicts. |
| 627 if (!extension_conflicts) { | 688 if (!extension_conflicts) { |
| 628 // Copy all modifications into the original headers. | 689 // Copy all modifications into the original headers. |
| 629 request_headers->MergeFrom((*delta)->modified_request_headers); | 690 request_headers->MergeFrom((*delta)->modified_request_headers); |
| 630 { | 691 { |
| 631 // Record which keys were changed. | 692 // Record which keys were changed. |
| 632 net::HttpRequestHeaders::Iterator modification( | 693 net::HttpRequestHeaders::Iterator modification( |
| 633 (*delta)->modified_request_headers); | 694 (*delta)->modified_request_headers); |
| 634 while (modification.GetNext()) | 695 while (modification.GetNext()) |
| 635 set_headers.insert(modification.name()); | 696 set_headers.insert(modification.name()); |
| 636 } | 697 } |
| 637 | 698 |
| 638 // Perform all deletions and record which keys were deleted. | 699 // Perform all deletions and record which keys were deleted. |
| 639 { | 700 { |
| 640 std::vector<std::string>::iterator key; | 701 std::vector<std::string>::iterator key; |
| 641 for (key = (*delta)->deleted_request_headers.begin(); | 702 for (key = (*delta)->deleted_request_headers.begin(); |
| 642 key != (*delta)->deleted_request_headers.end(); | 703 key != (*delta)->deleted_request_headers.end(); |
| 643 ++key) { | 704 ++key) { |
| 644 request_headers->RemoveHeader(*key); | 705 request_headers->RemoveHeader(*key); |
| 645 removed_headers.insert(*key); | 706 removed_headers.insert(*key); |
| 646 } | 707 } |
| 647 } | 708 } |
| 648 net_log->AddEvent( | 709 net_log->AddEvent( |
| 649 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 710 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
| 650 base::Bind(&NetLogModificationCallback, delta->get())); | 711 base::Bind(&NetLogModificationCallback, delta->get())); |
| 651 } else { | 712 } else { |
| 652 conflicting_extensions->insert((*delta)->extension_id); | 713 conflicting_extensions->Insert( |
| 714 ExtensionWarning::CreateRequestHeaderConflictWarning( | |
| 715 (*delta)->extension_id, winning_extension_id, | |
| 716 conflicting_header)); | |
| 653 net_log->AddEvent( | 717 net_log->AddEvent( |
| 654 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 718 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 655 CreateNetLogExtensionIdCallback(delta->get())); | 719 CreateNetLogExtensionIdCallback(delta->get())); |
| 656 } | 720 } |
| 657 } | 721 } |
| 658 | 722 |
| 659 MergeCookiesInOnBeforeSendHeadersResponses(deltas, request_headers, | 723 MergeCookiesInOnBeforeSendHeadersResponses(deltas, request_headers, |
| 660 conflicting_extensions, net_log); | 724 conflicting_extensions, net_log); |
| 661 } | 725 } |
| 662 | 726 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 829 } | 893 } |
| 830 } | 894 } |
| 831 } | 895 } |
| 832 return modified; | 896 return modified; |
| 833 } | 897 } |
| 834 | 898 |
| 835 void MergeCookiesInOnHeadersReceivedResponses( | 899 void MergeCookiesInOnHeadersReceivedResponses( |
| 836 const EventResponseDeltas& deltas, | 900 const EventResponseDeltas& deltas, |
| 837 const net::HttpResponseHeaders* original_response_headers, | 901 const net::HttpResponseHeaders* original_response_headers, |
| 838 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, | 902 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, |
| 839 std::set<std::string>* conflicting_extensions, | 903 ExtensionWarningSet* conflicting_extensions, |
| 840 const net::BoundNetLog* net_log) { | 904 const net::BoundNetLog* net_log) { |
| 841 // Skip all work if there are no registered cookie modifications. | 905 // Skip all work if there are no registered cookie modifications. |
| 842 bool cookie_modifications_exist = false; | 906 bool cookie_modifications_exist = false; |
| 843 EventResponseDeltas::const_reverse_iterator delta; | 907 EventResponseDeltas::const_reverse_iterator delta; |
| 844 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | 908 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { |
| 845 cookie_modifications_exist |= | 909 cookie_modifications_exist |= |
| 846 !(*delta)->response_cookie_modifications.empty(); | 910 !(*delta)->response_cookie_modifications.empty(); |
| 847 } | 911 } |
| 848 if (!cookie_modifications_exist) | 912 if (!cookie_modifications_exist) |
| 849 return; | 913 return; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 867 StoreResponseCookies(cookies, *override_response_headers); | 931 StoreResponseCookies(cookies, *override_response_headers); |
| 868 } | 932 } |
| 869 | 933 |
| 870 // Converts the key of the (key, value) pair to lower case. | 934 // Converts the key of the (key, value) pair to lower case. |
| 871 static ResponseHeader ToLowerCase(const ResponseHeader& header) { | 935 static ResponseHeader ToLowerCase(const ResponseHeader& header) { |
| 872 std::string lower_key(header.first); | 936 std::string lower_key(header.first); |
| 873 StringToLowerASCII(&lower_key); | 937 StringToLowerASCII(&lower_key); |
| 874 return ResponseHeader(lower_key, header.second); | 938 return ResponseHeader(lower_key, header.second); |
| 875 } | 939 } |
| 876 | 940 |
| 941 // Returns the extension ID of the first extension in |deltas| that removes the | |
| 942 // request header identified by |key|. | |
| 943 static std::string FindRemoveResponseHeader( | |
| 944 const EventResponseDeltas& deltas, | |
| 945 const std::string& key) { | |
| 946 std::string lower_key = StringToLowerASCII(key); | |
| 947 EventResponseDeltas::const_iterator delta; | |
| 948 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | |
| 949 ResponseHeaders::const_iterator i; | |
| 950 for (i = (*delta)->deleted_response_headers.begin(); | |
| 951 i != (*delta)->deleted_response_headers.end(); ++i) { | |
| 952 if (StringToLowerASCII(i->first) == lower_key) | |
| 953 return (*delta)->extension_id; | |
| 954 } | |
| 955 } | |
| 956 return ""; | |
| 957 } | |
| 958 | |
| 877 void MergeOnHeadersReceivedResponses( | 959 void MergeOnHeadersReceivedResponses( |
| 878 const EventResponseDeltas& deltas, | 960 const EventResponseDeltas& deltas, |
| 879 const net::HttpResponseHeaders* original_response_headers, | 961 const net::HttpResponseHeaders* original_response_headers, |
| 880 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, | 962 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, |
| 881 std::set<std::string>* conflicting_extensions, | 963 ExtensionWarningSet* conflicting_extensions, |
| 882 const net::BoundNetLog* net_log) { | 964 const net::BoundNetLog* net_log) { |
| 883 EventResponseDeltas::const_iterator delta; | 965 EventResponseDeltas::const_iterator delta; |
| 884 | 966 |
| 885 // Here we collect which headers we have removed or added so far due to | 967 // Here we collect which headers we have removed or added so far due to |
| 886 // extensions of higher precedence. Header keys are always stored as | 968 // extensions of higher precedence. Header keys are always stored as |
| 887 // lower case. | 969 // lower case. |
| 888 std::set<ResponseHeader> removed_headers; | 970 std::set<ResponseHeader> removed_headers; |
| 889 std::set<ResponseHeader> added_headers; | 971 std::set<ResponseHeader> added_headers; |
| 890 | 972 |
| 891 // We assume here that the deltas are sorted in decreasing extension | 973 // We assume here that the deltas are sorted in decreasing extension |
| 892 // precedence (i.e. decreasing extension installation time). | 974 // precedence (i.e. decreasing extension installation time). |
| 893 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | 975 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| 894 if ((*delta)->added_response_headers.empty() && | 976 if ((*delta)->added_response_headers.empty() && |
| 895 (*delta)->deleted_response_headers.empty()) { | 977 (*delta)->deleted_response_headers.empty()) { |
| 896 continue; | 978 continue; |
| 897 } | 979 } |
| 898 | 980 |
| 899 // Only create a copy if we really want to modify the response headers. | 981 // Only create a copy if we really want to modify the response headers. |
| 900 if (override_response_headers->get() == NULL) { | 982 if (override_response_headers->get() == NULL) { |
| 901 *override_response_headers = new net::HttpResponseHeaders( | 983 *override_response_headers = new net::HttpResponseHeaders( |
| 902 original_response_headers->raw_headers()); | 984 original_response_headers->raw_headers()); |
| 903 } | 985 } |
| 904 | 986 |
| 905 // We consider modifications as pairs of (delete, add) operations. | 987 // We consider modifications as pairs of (delete, add) operations. |
| 906 // If a header is deleted twice by different extensions we assume that the | 988 // If a header is deleted twice by different extensions we assume that the |
| 907 // intention was to modify it to different values and consider this a | 989 // intention was to modify it to different values and consider this a |
| 908 // conflict. As deltas is sorted by decreasing extension installation order, | 990 // conflict. As deltas is sorted by decreasing extension installation order, |
| 909 // this takes care of precedence. | 991 // this takes care of precedence. |
| 910 bool extension_conflicts = false; | 992 bool extension_conflicts = false; |
| 993 std::string conflicting_header; | |
| 994 std::string winning_extension_id; | |
| 911 ResponseHeaders::const_iterator i; | 995 ResponseHeaders::const_iterator i; |
| 912 for (i = (*delta)->deleted_response_headers.begin(); | 996 for (i = (*delta)->deleted_response_headers.begin(); |
| 913 i != (*delta)->deleted_response_headers.end(); ++i) { | 997 i != (*delta)->deleted_response_headers.end(); ++i) { |
| 914 if (removed_headers.find(ToLowerCase(*i)) != removed_headers.end()) { | 998 if (removed_headers.find(ToLowerCase(*i)) != removed_headers.end()) { |
| 999 winning_extension_id = FindRemoveResponseHeader(deltas, i->first); | |
| 1000 conflicting_header = i->first; | |
| 915 extension_conflicts = true; | 1001 extension_conflicts = true; |
| 916 break; | 1002 break; |
| 917 } | 1003 } |
| 918 } | 1004 } |
| 919 | 1005 |
| 920 // Now execute the modifications if there were no conflicts. | 1006 // Now execute the modifications if there were no conflicts. |
| 921 if (!extension_conflicts) { | 1007 if (!extension_conflicts) { |
| 922 // Delete headers | 1008 // Delete headers |
| 923 { | 1009 { |
| 924 for (i = (*delta)->deleted_response_headers.begin(); | 1010 for (i = (*delta)->deleted_response_headers.begin(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 936 if (added_headers.find(lowercase_header) != added_headers.end()) | 1022 if (added_headers.find(lowercase_header) != added_headers.end()) |
| 937 continue; | 1023 continue; |
| 938 added_headers.insert(lowercase_header); | 1024 added_headers.insert(lowercase_header); |
| 939 (*override_response_headers)->AddHeader(i->first + ": " + i->second); | 1025 (*override_response_headers)->AddHeader(i->first + ": " + i->second); |
| 940 } | 1026 } |
| 941 } | 1027 } |
| 942 net_log->AddEvent( | 1028 net_log->AddEvent( |
| 943 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, | 1029 net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
| 944 CreateNetLogExtensionIdCallback(delta->get())); | 1030 CreateNetLogExtensionIdCallback(delta->get())); |
| 945 } else { | 1031 } else { |
| 946 conflicting_extensions->insert((*delta)->extension_id); | 1032 conflicting_extensions->Insert( |
| 1033 ExtensionWarning::CreateResponseHeaderConflictWarning( | |
| 1034 (*delta)->extension_id, winning_extension_id, | |
| 1035 conflicting_header)); | |
| 947 net_log->AddEvent( | 1036 net_log->AddEvent( |
| 948 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 1037 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 949 CreateNetLogExtensionIdCallback(delta->get())); | 1038 CreateNetLogExtensionIdCallback(delta->get())); |
| 950 } | 1039 } |
| 951 } | 1040 } |
| 952 | 1041 |
| 953 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers, | 1042 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers, |
| 954 override_response_headers, conflicting_extensions, net_log); | 1043 override_response_headers, conflicting_extensions, net_log); |
| 955 } | 1044 } |
| 956 | 1045 |
| 957 bool MergeOnAuthRequiredResponses( | 1046 bool MergeOnAuthRequiredResponses( |
| 958 const EventResponseDeltas& deltas, | 1047 const EventResponseDeltas& deltas, |
| 959 net::AuthCredentials* auth_credentials, | 1048 net::AuthCredentials* auth_credentials, |
| 960 std::set<std::string>* conflicting_extensions, | 1049 ExtensionWarningSet* conflicting_extensions, |
| 961 const net::BoundNetLog* net_log) { | 1050 const net::BoundNetLog* net_log) { |
| 962 CHECK(auth_credentials); | 1051 CHECK(auth_credentials); |
| 963 bool credentials_set = false; | 1052 bool credentials_set = false; |
| 1053 std::string winning_extension_id; | |
| 964 | 1054 |
| 965 for (EventResponseDeltas::const_iterator delta = deltas.begin(); | 1055 for (EventResponseDeltas::const_iterator delta = deltas.begin(); |
| 966 delta != deltas.end(); | 1056 delta != deltas.end(); |
| 967 ++delta) { | 1057 ++delta) { |
| 968 if (!(*delta)->auth_credentials.get()) | 1058 if (!(*delta)->auth_credentials.get()) |
| 969 continue; | 1059 continue; |
| 970 bool different = | 1060 bool different = |
| 971 auth_credentials->username() != | 1061 auth_credentials->username() != |
| 972 (*delta)->auth_credentials->username() || | 1062 (*delta)->auth_credentials->username() || |
| 973 auth_credentials->password() != (*delta)->auth_credentials->password(); | 1063 auth_credentials->password() != (*delta)->auth_credentials->password(); |
| 974 if (credentials_set && different) { | 1064 if (credentials_set && different) { |
| 975 conflicting_extensions->insert((*delta)->extension_id); | 1065 conflicting_extensions->Insert( |
| 1066 ExtensionWarning::CreateCredentialsConflictWarning( | |
| 1067 (*delta)->extension_id, winning_extension_id)); | |
| 976 net_log->AddEvent( | 1068 net_log->AddEvent( |
| 977 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 1069 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 978 CreateNetLogExtensionIdCallback(delta->get())); | 1070 CreateNetLogExtensionIdCallback(delta->get())); |
| 979 } else { | 1071 } else { |
| 980 net_log->AddEvent( | 1072 net_log->AddEvent( |
| 981 net::NetLog::TYPE_CHROME_EXTENSION_PROVIDE_AUTH_CREDENTIALS, | 1073 net::NetLog::TYPE_CHROME_EXTENSION_PROVIDE_AUTH_CREDENTIALS, |
| 982 CreateNetLogExtensionIdCallback(delta->get())); | 1074 CreateNetLogExtensionIdCallback(delta->get())); |
| 983 *auth_credentials = *(*delta)->auth_credentials; | 1075 *auth_credentials = *(*delta)->auth_credentials; |
| 984 credentials_set = true; | 1076 credentials_set = true; |
| 1077 winning_extension_id = (*delta)->extension_id; | |
| 985 } | 1078 } |
| 986 } | 1079 } |
| 987 return credentials_set; | 1080 return credentials_set; |
| 988 } | 1081 } |
| 989 | 1082 |
| 990 | 1083 |
| 991 #define ARRAYEND(array) (array + arraysize(array)) | 1084 #define ARRAYEND(array) (array + arraysize(array)) |
| 992 | 1085 |
| 993 bool IsRelevantResourceType(ResourceType::Type type) { | 1086 bool IsRelevantResourceType(ResourceType::Type type) { |
| 994 ResourceType::Type* iter = | 1087 ResourceType::Type* iter = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1026 void ClearCacheOnNavigation() { | 1119 void ClearCacheOnNavigation() { |
| 1027 if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { | 1120 if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
| 1028 ClearCacheOnNavigationOnUI(); | 1121 ClearCacheOnNavigationOnUI(); |
| 1029 } else { | 1122 } else { |
| 1030 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, | 1123 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, |
| 1031 base::Bind(&ClearCacheOnNavigationOnUI)); | 1124 base::Bind(&ClearCacheOnNavigationOnUI)); |
| 1032 } | 1125 } |
| 1033 } | 1126 } |
| 1034 | 1127 |
| 1035 } // namespace extension_web_request_api_helpers | 1128 } // namespace extension_web_request_api_helpers |
| OLD | NEW |