| 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 "extensions/browser/api/web_request/web_request_api_helpers.h" | 5 #include "extensions/browser/api/web_request/web_request_api_helpers.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 645 } | 645 } |
| 646 } | 646 } |
| 647 } | 647 } |
| 648 return modified; | 648 return modified; |
| 649 } | 649 } |
| 650 | 650 |
| 651 void MergeCookiesInOnBeforeSendHeadersResponses( | 651 void MergeCookiesInOnBeforeSendHeadersResponses( |
| 652 const EventResponseDeltas& deltas, | 652 const EventResponseDeltas& deltas, |
| 653 net::HttpRequestHeaders* request_headers, | 653 net::HttpRequestHeaders* request_headers, |
| 654 extensions::WarningSet* conflicting_extensions, | 654 extensions::WarningSet* conflicting_extensions, |
| 655 const net::NetLogWithSource* net_log) { | 655 const net::NetLogWithSource* net_log, |
| 656 bool* request_cookies_modified) { |
| 657 DCHECK(request_cookies_modified); |
| 658 *request_cookies_modified = false; |
| 659 |
| 656 // Skip all work if there are no registered cookie modifications. | 660 // Skip all work if there are no registered cookie modifications. |
| 657 bool cookie_modifications_exist = false; | 661 bool cookie_modifications_exist = false; |
| 658 EventResponseDeltas::const_iterator delta; | 662 EventResponseDeltas::const_iterator delta; |
| 659 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | 663 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| 660 cookie_modifications_exist |= | 664 cookie_modifications_exist |= |
| 661 !(*delta)->request_cookie_modifications.empty(); | 665 !(*delta)->request_cookie_modifications.empty(); |
| 662 } | 666 } |
| 663 if (!cookie_modifications_exist) | 667 if (!cookie_modifications_exist) |
| 664 return; | 668 return; |
| 665 | 669 |
| 666 // Parse old cookie line. | 670 // Parse old cookie line. |
| 667 std::string cookie_header; | 671 std::string cookie_header; |
| 668 request_headers->GetHeader(net::HttpRequestHeaders::kCookie, &cookie_header); | 672 request_headers->GetHeader(net::HttpRequestHeaders::kCookie, &cookie_header); |
| 669 ParsedRequestCookies cookies; | 673 ParsedRequestCookies cookies; |
| 670 net::cookie_util::ParseRequestCookieLine(cookie_header, &cookies); | 674 net::cookie_util::ParseRequestCookieLine(cookie_header, &cookies); |
| 671 | 675 |
| 672 // Modify cookies. | 676 // Modify cookies. |
| 673 bool modified = false; | 677 *request_cookies_modified |= |
| 674 modified |= MergeAddRequestCookieModifications(deltas, &cookies); | 678 MergeAddRequestCookieModifications(deltas, &cookies); |
| 675 modified |= MergeEditRequestCookieModifications(deltas, &cookies); | 679 *request_cookies_modified |= |
| 676 modified |= MergeRemoveRequestCookieModifications(deltas, &cookies); | 680 MergeEditRequestCookieModifications(deltas, &cookies); |
| 681 *request_cookies_modified |= |
| 682 MergeRemoveRequestCookieModifications(deltas, &cookies); |
| 677 | 683 |
| 678 // Reassemble and store new cookie line. | 684 // Reassemble and store new cookie line. |
| 679 if (modified) { | 685 if (*request_cookies_modified) { |
| 680 std::string new_cookie_header = | 686 std::string new_cookie_header = |
| 681 net::cookie_util::SerializeRequestCookieLine(cookies); | 687 net::cookie_util::SerializeRequestCookieLine(cookies); |
| 682 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, | 688 request_headers->SetHeader(net::HttpRequestHeaders::kCookie, |
| 683 new_cookie_header); | 689 new_cookie_header); |
| 684 } | 690 } |
| 685 } | 691 } |
| 686 | 692 |
| 687 // Returns the extension ID of the first extension in |deltas| that sets the | 693 // Returns the extension ID of the first extension in |deltas| that sets the |
| 688 // request header identified by |key| to |value|. | 694 // request header identified by |key| to |value|. |
| 689 static std::string FindSetRequestHeader( | 695 static std::string FindSetRequestHeader( |
| (...skipping 28 matching lines...) Expand all Loading... |
| 718 return (*delta)->extension_id; | 724 return (*delta)->extension_id; |
| 719 } | 725 } |
| 720 } | 726 } |
| 721 return std::string(); | 727 return std::string(); |
| 722 } | 728 } |
| 723 | 729 |
| 724 void MergeOnBeforeSendHeadersResponses( | 730 void MergeOnBeforeSendHeadersResponses( |
| 725 const EventResponseDeltas& deltas, | 731 const EventResponseDeltas& deltas, |
| 726 net::HttpRequestHeaders* request_headers, | 732 net::HttpRequestHeaders* request_headers, |
| 727 extensions::WarningSet* conflicting_extensions, | 733 extensions::WarningSet* conflicting_extensions, |
| 728 const net::NetLogWithSource* net_log) { | 734 const net::NetLogWithSource* net_log, |
| 735 bool* request_headers_modified, |
| 736 bool* request_cookies_modified) { |
| 737 DCHECK(request_headers_modified); |
| 738 DCHECK(request_cookies_modified); |
| 739 *request_headers_modified = false; |
| 740 *request_cookies_modified = false; |
| 741 |
| 729 EventResponseDeltas::const_iterator delta; | 742 EventResponseDeltas::const_iterator delta; |
| 730 | 743 |
| 731 // Here we collect which headers we have removed or set to new values | 744 // Here we collect which headers we have removed or set to new values |
| 732 // so far due to extensions of higher precedence. | 745 // so far due to extensions of higher precedence. |
| 733 std::set<std::string> removed_headers; | 746 std::set<std::string> removed_headers; |
| 734 std::set<std::string> set_headers; | 747 std::set<std::string> set_headers; |
| 735 | 748 |
| 736 // We assume here that the deltas are sorted in decreasing extension | 749 // We assume here that the deltas are sorted in decreasing extension |
| 737 // precedence (i.e. decreasing extension installation time). | 750 // precedence (i.e. decreasing extension installation time). |
| 738 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { | 751 for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 std::vector<std::string>::iterator key; | 828 std::vector<std::string>::iterator key; |
| 816 for (key = (*delta)->deleted_request_headers.begin(); | 829 for (key = (*delta)->deleted_request_headers.begin(); |
| 817 key != (*delta)->deleted_request_headers.end(); | 830 key != (*delta)->deleted_request_headers.end(); |
| 818 ++key) { | 831 ++key) { |
| 819 request_headers->RemoveHeader(*key); | 832 request_headers->RemoveHeader(*key); |
| 820 removed_headers.insert(*key); | 833 removed_headers.insert(*key); |
| 821 } | 834 } |
| 822 } | 835 } |
| 823 net_log->AddEvent(net::NetLogEventType::CHROME_EXTENSION_MODIFIED_HEADERS, | 836 net_log->AddEvent(net::NetLogEventType::CHROME_EXTENSION_MODIFIED_HEADERS, |
| 824 base::Bind(&NetLogModificationCallback, delta->get())); | 837 base::Bind(&NetLogModificationCallback, delta->get())); |
| 838 *request_headers_modified = true; |
| 825 } else { | 839 } else { |
| 826 conflicting_extensions->insert( | 840 conflicting_extensions->insert( |
| 827 extensions::Warning::CreateRequestHeaderConflictWarning( | 841 extensions::Warning::CreateRequestHeaderConflictWarning( |
| 828 (*delta)->extension_id, winning_extension_id, | 842 (*delta)->extension_id, winning_extension_id, |
| 829 conflicting_header)); | 843 conflicting_header)); |
| 830 net_log->AddEvent( | 844 net_log->AddEvent( |
| 831 net::NetLogEventType::CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 845 net::NetLogEventType::CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 832 CreateNetLogExtensionIdCallback(delta->get())); | 846 CreateNetLogExtensionIdCallback(delta->get())); |
| 833 } | 847 } |
| 834 } | 848 } |
| 835 | 849 |
| 836 MergeCookiesInOnBeforeSendHeadersResponses(deltas, request_headers, | 850 MergeCookiesInOnBeforeSendHeadersResponses(deltas, request_headers, |
| 837 conflicting_extensions, net_log); | 851 conflicting_extensions, net_log, |
| 852 request_cookies_modified); |
| 838 } | 853 } |
| 839 | 854 |
| 840 // Retrives all cookies from |override_response_headers|. | 855 // Retrives all cookies from |override_response_headers|. |
| 841 static ParsedResponseCookies GetResponseCookies( | 856 static ParsedResponseCookies GetResponseCookies( |
| 842 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { | 857 scoped_refptr<net::HttpResponseHeaders> override_response_headers) { |
| 843 ParsedResponseCookies result; | 858 ParsedResponseCookies result; |
| 844 | 859 |
| 845 size_t iter = 0; | 860 size_t iter = 0; |
| 846 std::string value; | 861 std::string value; |
| 847 while (override_response_headers->EnumerateHeader(&iter, "Set-Cookie", | 862 while (override_response_headers->EnumerateHeader(&iter, "Set-Cookie", |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 } | 1040 } |
| 1026 } | 1041 } |
| 1027 return modified; | 1042 return modified; |
| 1028 } | 1043 } |
| 1029 | 1044 |
| 1030 void MergeCookiesInOnHeadersReceivedResponses( | 1045 void MergeCookiesInOnHeadersReceivedResponses( |
| 1031 const EventResponseDeltas& deltas, | 1046 const EventResponseDeltas& deltas, |
| 1032 const net::HttpResponseHeaders* original_response_headers, | 1047 const net::HttpResponseHeaders* original_response_headers, |
| 1033 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, | 1048 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, |
| 1034 extensions::WarningSet* conflicting_extensions, | 1049 extensions::WarningSet* conflicting_extensions, |
| 1035 const net::NetLogWithSource* net_log) { | 1050 const net::NetLogWithSource* net_log, |
| 1051 bool* response_cookies_modified) { |
| 1052 DCHECK(response_cookies_modified); |
| 1053 *response_cookies_modified = false; |
| 1054 |
| 1036 // Skip all work if there are no registered cookie modifications. | 1055 // Skip all work if there are no registered cookie modifications. |
| 1037 bool cookie_modifications_exist = false; | 1056 bool cookie_modifications_exist = false; |
| 1038 EventResponseDeltas::const_reverse_iterator delta; | 1057 EventResponseDeltas::const_reverse_iterator delta; |
| 1039 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { | 1058 for (delta = deltas.rbegin(); delta != deltas.rend(); ++delta) { |
| 1040 cookie_modifications_exist |= | 1059 cookie_modifications_exist |= |
| 1041 !(*delta)->response_cookie_modifications.empty(); | 1060 !(*delta)->response_cookie_modifications.empty(); |
| 1042 } | 1061 } |
| 1043 if (!cookie_modifications_exist) | 1062 if (!cookie_modifications_exist) |
| 1044 return; | 1063 return; |
| 1045 | 1064 |
| 1046 // Only create a copy if we really want to modify the response headers. | 1065 // Only create a copy if we really want to modify the response headers. |
| 1047 if (override_response_headers->get() == NULL) { | 1066 if (override_response_headers->get() == NULL) { |
| 1048 *override_response_headers = new net::HttpResponseHeaders( | 1067 *override_response_headers = new net::HttpResponseHeaders( |
| 1049 original_response_headers->raw_headers()); | 1068 original_response_headers->raw_headers()); |
| 1050 } | 1069 } |
| 1051 | 1070 |
| 1052 ParsedResponseCookies cookies = | 1071 ParsedResponseCookies cookies = |
| 1053 GetResponseCookies(*override_response_headers); | 1072 GetResponseCookies(*override_response_headers); |
| 1054 | 1073 |
| 1055 bool modified = false; | 1074 *response_cookies_modified |= |
| 1056 modified |= MergeAddResponseCookieModifications(deltas, &cookies); | 1075 MergeAddResponseCookieModifications(deltas, &cookies); |
| 1057 modified |= MergeEditResponseCookieModifications(deltas, &cookies); | 1076 *response_cookies_modified |= |
| 1058 modified |= MergeRemoveResponseCookieModifications(deltas, &cookies); | 1077 MergeEditResponseCookieModifications(deltas, &cookies); |
| 1078 *response_cookies_modified |= |
| 1079 MergeRemoveResponseCookieModifications(deltas, &cookies); |
| 1059 | 1080 |
| 1060 // Store new value. | 1081 // Store new value. |
| 1061 if (modified) | 1082 if (*response_cookies_modified) |
| 1062 StoreResponseCookies(cookies, *override_response_headers); | 1083 StoreResponseCookies(cookies, *override_response_headers); |
| 1063 } | 1084 } |
| 1064 | 1085 |
| 1065 // Converts the key of the (key, value) pair to lower case. | 1086 // Converts the key of the (key, value) pair to lower case. |
| 1066 static ResponseHeader ToLowerCase(const ResponseHeader& header) { | 1087 static ResponseHeader ToLowerCase(const ResponseHeader& header) { |
| 1067 return ResponseHeader(base::ToLowerASCII(header.first), header.second); | 1088 return ResponseHeader(base::ToLowerASCII(header.first), header.second); |
| 1068 } | 1089 } |
| 1069 | 1090 |
| 1070 // Returns the extension ID of the first extension in |deltas| that removes the | 1091 // Returns the extension ID of the first extension in |deltas| that removes the |
| 1071 // request header identified by |key|. | 1092 // request header identified by |key|. |
| 1072 static std::string FindRemoveResponseHeader( | 1093 static std::string FindRemoveResponseHeader( |
| 1073 const EventResponseDeltas& deltas, | 1094 const EventResponseDeltas& deltas, |
| 1074 const std::string& key) { | 1095 const std::string& key) { |
| 1075 std::string lower_key = base::ToLowerASCII(key); | 1096 std::string lower_key = base::ToLowerASCII(key); |
| 1076 for (const auto& delta : deltas) { | 1097 for (const auto& delta : deltas) { |
| 1077 for (const auto& deleted_hdr : delta->deleted_response_headers) { | 1098 for (const auto& deleted_hdr : delta->deleted_response_headers) { |
| 1078 if (base::ToLowerASCII(deleted_hdr.first) == lower_key) | 1099 if (base::ToLowerASCII(deleted_hdr.first) == lower_key) |
| 1079 return delta->extension_id; | 1100 return delta->extension_id; |
| 1080 } | 1101 } |
| 1081 } | 1102 } |
| 1082 return std::string(); | 1103 return std::string(); |
| 1083 } | 1104 } |
| 1084 | 1105 |
| 1085 void MergeOnHeadersReceivedResponses( | 1106 void MergeOnHeadersReceivedResponses( |
| 1086 const EventResponseDeltas& deltas, | 1107 const EventResponseDeltas& deltas, |
| 1087 const net::HttpResponseHeaders* original_response_headers, | 1108 const net::HttpResponseHeaders* original_response_headers, |
| 1088 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, | 1109 scoped_refptr<net::HttpResponseHeaders>* override_response_headers, |
| 1089 GURL* allowed_unsafe_redirect_url, | 1110 GURL* allowed_unsafe_redirect_url, |
| 1090 extensions::WarningSet* conflicting_extensions, | 1111 extensions::WarningSet* conflicting_extensions, |
| 1091 const net::NetLogWithSource* net_log) { | 1112 const net::NetLogWithSource* net_log, |
| 1113 bool* response_headers_modified, |
| 1114 bool* response_cookies_modified) { |
| 1115 DCHECK(response_headers_modified); |
| 1116 DCHECK(response_cookies_modified); |
| 1117 *response_headers_modified = false; |
| 1118 *response_cookies_modified = false; |
| 1119 |
| 1092 EventResponseDeltas::const_iterator delta; | 1120 EventResponseDeltas::const_iterator delta; |
| 1093 | 1121 |
| 1094 // Here we collect which headers we have removed or added so far due to | 1122 // Here we collect which headers we have removed or added so far due to |
| 1095 // extensions of higher precedence. Header keys are always stored as | 1123 // extensions of higher precedence. Header keys are always stored as |
| 1096 // lower case. | 1124 // lower case. |
| 1097 std::set<ResponseHeader> removed_headers; | 1125 std::set<ResponseHeader> removed_headers; |
| 1098 std::set<ResponseHeader> added_headers; | 1126 std::set<ResponseHeader> added_headers; |
| 1099 | 1127 |
| 1100 // We assume here that the deltas are sorted in decreasing extension | 1128 // We assume here that the deltas are sorted in decreasing extension |
| 1101 // precedence (i.e. decreasing extension installation time). | 1129 // precedence (i.e. decreasing extension installation time). |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1147 i != (*delta)->added_response_headers.end(); ++i) { | 1175 i != (*delta)->added_response_headers.end(); ++i) { |
| 1148 ResponseHeader lowercase_header(ToLowerCase(*i)); | 1176 ResponseHeader lowercase_header(ToLowerCase(*i)); |
| 1149 if (added_headers.find(lowercase_header) != added_headers.end()) | 1177 if (added_headers.find(lowercase_header) != added_headers.end()) |
| 1150 continue; | 1178 continue; |
| 1151 added_headers.insert(lowercase_header); | 1179 added_headers.insert(lowercase_header); |
| 1152 (*override_response_headers)->AddHeader(i->first + ": " + i->second); | 1180 (*override_response_headers)->AddHeader(i->first + ": " + i->second); |
| 1153 } | 1181 } |
| 1154 } | 1182 } |
| 1155 net_log->AddEvent(net::NetLogEventType::CHROME_EXTENSION_MODIFIED_HEADERS, | 1183 net_log->AddEvent(net::NetLogEventType::CHROME_EXTENSION_MODIFIED_HEADERS, |
| 1156 CreateNetLogExtensionIdCallback(delta->get())); | 1184 CreateNetLogExtensionIdCallback(delta->get())); |
| 1185 *response_headers_modified = true; |
| 1157 } else { | 1186 } else { |
| 1158 conflicting_extensions->insert( | 1187 conflicting_extensions->insert( |
| 1159 extensions::Warning::CreateResponseHeaderConflictWarning( | 1188 extensions::Warning::CreateResponseHeaderConflictWarning( |
| 1160 (*delta)->extension_id, winning_extension_id, | 1189 (*delta)->extension_id, winning_extension_id, |
| 1161 conflicting_header)); | 1190 conflicting_header)); |
| 1162 net_log->AddEvent( | 1191 net_log->AddEvent( |
| 1163 net::NetLogEventType::CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 1192 net::NetLogEventType::CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 1164 CreateNetLogExtensionIdCallback(delta->get())); | 1193 CreateNetLogExtensionIdCallback(delta->get())); |
| 1165 } | 1194 } |
| 1166 } | 1195 } |
| 1167 | 1196 |
| 1168 MergeCookiesInOnHeadersReceivedResponses(deltas, original_response_headers, | 1197 MergeCookiesInOnHeadersReceivedResponses( |
| 1169 override_response_headers, conflicting_extensions, net_log); | 1198 deltas, original_response_headers, override_response_headers, |
| 1199 conflicting_extensions, net_log, response_cookies_modified); |
| 1170 | 1200 |
| 1171 GURL new_url; | 1201 GURL new_url; |
| 1172 MergeRedirectUrlOfResponses( | 1202 MergeRedirectUrlOfResponses( |
| 1173 deltas, &new_url, conflicting_extensions, net_log); | 1203 deltas, &new_url, conflicting_extensions, net_log); |
| 1174 if (new_url.is_valid()) { | 1204 if (new_url.is_valid()) { |
| 1175 // Only create a copy if we really want to modify the response headers. | 1205 // Only create a copy if we really want to modify the response headers. |
| 1176 if (override_response_headers->get() == NULL) { | 1206 if (override_response_headers->get() == NULL) { |
| 1177 *override_response_headers = new net::HttpResponseHeaders( | 1207 *override_response_headers = new net::HttpResponseHeaders( |
| 1178 original_response_headers->raw_headers()); | 1208 original_response_headers->raw_headers()); |
| 1179 } | 1209 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 for (size_t i = 0; i < kResourceTypeStringsLength; ++i) { | 1303 for (size_t i = 0; i < kResourceTypeStringsLength; ++i) { |
| 1274 if (type_str == kResourceTypeStrings[i]) { | 1304 if (type_str == kResourceTypeStrings[i]) { |
| 1275 found = true; | 1305 found = true; |
| 1276 types->push_back(kResourceTypeValues[i]); | 1306 types->push_back(kResourceTypeValues[i]); |
| 1277 } | 1307 } |
| 1278 } | 1308 } |
| 1279 return found; | 1309 return found; |
| 1280 } | 1310 } |
| 1281 | 1311 |
| 1282 } // namespace extension_web_request_api_helpers | 1312 } // namespace extension_web_request_api_helpers |
| OLD | NEW |