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

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: Merged with ToT 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
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
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
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
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, &current_value) || 657 if (!request_headers->GetHeader(key, &current_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, &current_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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698