Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: chrome/browser/extensions/api/web_request/web_request_api_helpers.cc

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

Powered by Google App Engine
This is Rietveld 408576698