Chromium Code Reviews| Index: chrome/browser/extensions/api/web_request/web_request_api_helpers.cc |
| diff --git a/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc b/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc |
| index faca61a38f29bb699ef66693534b63efe5f1e82d..2dad07531af3afae972a2a722491bb73f4f8e0f1 100644 |
| --- a/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc |
| +++ b/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/stringprintf.h" |
| #include "base/values.h" |
| #include "chrome/browser/extensions/api/web_request/web_request_api.h" |
| +#include "chrome/browser/extensions/extension_warning_set.h" |
| #include "chrome/browser/renderer_host/web_cache_manager.h" |
| #include "chrome/common/url_constants.h" |
| #include "content/public/browser/browser_thread.h" |
| @@ -298,11 +299,13 @@ void MergeCancelOfResponses( |
| static bool MergeOnBeforeRequestResponsesHelper( |
| const EventResponseDeltas& deltas, |
| GURL* new_url, |
| - std::set<std::string>* conflicting_extensions, |
| + ExtensionWarningSet* conflicting_extensions, |
| const net::BoundNetLog* net_log, |
| bool consider_only_cancel_scheme_urls) { |
| bool redirected = false; |
| + // Extension that determines the |new_url|. |
| + std::string winning_extension_id; |
| EventResponseDeltas::const_iterator delta; |
| for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| if ((*delta)->new_url.is_empty()) |
| @@ -315,12 +318,18 @@ static bool MergeOnBeforeRequestResponsesHelper( |
| if (!redirected || *new_url == (*delta)->new_url) { |
| *new_url = (*delta)->new_url; |
| + winning_extension_id = (*delta)->extension_id; |
| redirected = true; |
| net_log->AddEvent( |
| net::NetLog::TYPE_CHROME_EXTENSION_REDIRECTED_REQUEST, |
| CreateNetLogExtensionIdCallback(delta->get())); |
| } else { |
| - conflicting_extensions->insert((*delta)->extension_id); |
| + conflicting_extensions->Insert( |
| + ExtensionWarning::CreateRedirectConflictWarning( |
| + (*delta)->extension_id, |
| + winning_extension_id, |
| + (*delta)->new_url, |
| + *new_url)); |
| net_log->AddEvent( |
| net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| CreateNetLogExtensionIdCallback(delta->get())); |
| @@ -332,7 +341,7 @@ static bool MergeOnBeforeRequestResponsesHelper( |
| void MergeOnBeforeRequestResponses( |
| const EventResponseDeltas& deltas, |
| GURL* new_url, |
| - std::set<std::string>* conflicting_extensions, |
| + ExtensionWarningSet* conflicting_extensions, |
| const net::BoundNetLog* net_log) { |
| // First handle only redirects to data:// URLs and about:blank. These are a |
| @@ -530,7 +539,7 @@ static bool MergeRemoveRequestCookieModifications( |
| void MergeCookiesInOnBeforeSendHeadersResponses( |
| const EventResponseDeltas& deltas, |
| net::HttpRequestHeaders* request_headers, |
| - std::set<std::string>* conflicting_extensions, |
| + ExtensionWarningSet* conflicting_extensions, |
| const net::BoundNetLog* net_log) { |
| // Skip all work if there are no registered cookie modifications. |
| bool cookie_modifications_exist = false; |
| @@ -562,10 +571,46 @@ void MergeCookiesInOnBeforeSendHeadersResponses( |
| } |
| } |
| +// Returns the extension ID of the first extension in |deltas| that sets the |
| +// request header identified by |key| to |value|. |
| +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
|
| + const EventResponseDeltas& deltas, |
| + const std::string& key, |
| + const std::string& value) { |
| + EventResponseDeltas::const_iterator delta; |
| + for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| + net::HttpRequestHeaders::Iterator modification( |
| + (*delta)->modified_request_headers); |
| + while (modification.GetNext()) { |
| + if (key == modification.name() && value == modification.value()) |
| + return (*delta)->extension_id; |
| + } |
| + } |
| + return ""; |
| +} |
| + |
| +// Returns the extension ID of the first extension in |deltas| that removes the |
| +// request header identified by |key|. |
| +static std::string FindRemoveRequestHeader( |
| + const EventResponseDeltas& deltas, |
| + const std::string& key) { |
| + EventResponseDeltas::const_iterator delta; |
| + for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| + std::vector<std::string>::iterator i; |
| + for (i = (*delta)->deleted_request_headers.begin(); |
| + i != (*delta)->deleted_request_headers.end(); |
| + ++i) { |
| + if (*i == key) |
| + return (*delta)->extension_id; |
| + } |
| + } |
| + return ""; |
| +} |
| + |
| void MergeOnBeforeSendHeadersResponses( |
| const EventResponseDeltas& deltas, |
| net::HttpRequestHeaders* request_headers, |
| - std::set<std::string>* conflicting_extensions, |
| + ExtensionWarningSet* conflicting_extensions, |
| const net::BoundNetLog* net_log) { |
| EventResponseDeltas::const_iterator delta; |
| @@ -586,6 +631,8 @@ void MergeOnBeforeSendHeadersResponses( |
| // has been modified differently before. As deltas is sorted by decreasing |
| // extension installation order, this takes care of precedence. |
| bool extension_conflicts = false; |
| + std::string winning_extension_id; |
| + std::string conflicting_header; |
| { |
| net::HttpRequestHeaders::Iterator modification( |
| (*delta)->modified_request_headers); |
| @@ -595,15 +642,23 @@ void MergeOnBeforeSendHeadersResponses( |
| const std::string& value = modification.value(); |
| // We must not delete anything that has been modified before. |
| - if (removed_headers.find(key) != removed_headers.end()) |
| + if (removed_headers.find(key) != removed_headers.end() && |
| + !extension_conflicts) { |
| + winning_extension_id = FindRemoveRequestHeader(deltas, key); |
| + conflicting_header = key; |
| extension_conflicts = true; |
| + } |
| // We must not modify anything that has been set to a *different* |
| // value before. |
| - if (set_headers.find(key) != set_headers.end()) { |
| + if (set_headers.find(key) != set_headers.end() && |
| + !extension_conflicts) { |
| std::string current_value; |
| if (!request_headers->GetHeader(key, ¤t_value) || |
| current_value != value) { |
| + winning_extension_id = |
| + FindSetRequestHeader(deltas, key, current_value); |
| + conflicting_header = key; |
| extension_conflicts = true; |
| } |
| } |
| @@ -618,8 +673,14 @@ void MergeOnBeforeSendHeadersResponses( |
| key != (*delta)->deleted_request_headers.end() && |
| !extension_conflicts; |
| ++key) { |
| - if (set_headers.find(*key) != set_headers.end()) |
| + if (set_headers.find(*key) != set_headers.end()) { |
| + std::string current_value; |
| + request_headers->GetHeader(*key, ¤t_value); |
| + winning_extension_id = |
| + FindSetRequestHeader(deltas, *key, current_value); |
| + conflicting_header = *key; |
| extension_conflicts = true; |
| + } |
| } |
| } |
| @@ -649,7 +710,10 @@ void MergeOnBeforeSendHeadersResponses( |
| net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
| base::Bind(&NetLogModificationCallback, delta->get())); |
| } else { |
| - conflicting_extensions->insert((*delta)->extension_id); |
| + conflicting_extensions->Insert( |
| + ExtensionWarning::CreateRequestHeaderConflictWarning( |
| + (*delta)->extension_id, winning_extension_id, |
| + conflicting_header)); |
| net_log->AddEvent( |
| net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| CreateNetLogExtensionIdCallback(delta->get())); |
| @@ -836,7 +900,7 @@ void MergeCookiesInOnHeadersReceivedResponses( |
| const EventResponseDeltas& deltas, |
| const net::HttpResponseHeaders* original_response_headers, |
| scoped_refptr<net::HttpResponseHeaders>* override_response_headers, |
| - std::set<std::string>* conflicting_extensions, |
| + ExtensionWarningSet* conflicting_extensions, |
| const net::BoundNetLog* net_log) { |
| // Skip all work if there are no registered cookie modifications. |
| bool cookie_modifications_exist = false; |
| @@ -874,11 +938,29 @@ static ResponseHeader ToLowerCase(const ResponseHeader& header) { |
| return ResponseHeader(lower_key, header.second); |
| } |
| +// Returns the extension ID of the first extension in |deltas| that removes the |
| +// request header identified by |key|. |
| +static std::string FindRemoveResponseHeader( |
| + const EventResponseDeltas& deltas, |
| + const std::string& key) { |
| + std::string lower_key = StringToLowerASCII(key); |
| + EventResponseDeltas::const_iterator delta; |
| + for (delta = deltas.begin(); delta != deltas.end(); ++delta) { |
| + ResponseHeaders::const_iterator i; |
| + for (i = (*delta)->deleted_response_headers.begin(); |
| + i != (*delta)->deleted_response_headers.end(); ++i) { |
| + if (StringToLowerASCII(i->first) == lower_key) |
| + return (*delta)->extension_id; |
| + } |
| + } |
| + return ""; |
| +} |
| + |
| void MergeOnHeadersReceivedResponses( |
| const EventResponseDeltas& deltas, |
| const net::HttpResponseHeaders* original_response_headers, |
| scoped_refptr<net::HttpResponseHeaders>* override_response_headers, |
| - std::set<std::string>* conflicting_extensions, |
| + ExtensionWarningSet* conflicting_extensions, |
| const net::BoundNetLog* net_log) { |
| EventResponseDeltas::const_iterator delta; |
| @@ -908,10 +990,14 @@ void MergeOnHeadersReceivedResponses( |
| // conflict. As deltas is sorted by decreasing extension installation order, |
| // this takes care of precedence. |
| bool extension_conflicts = false; |
| + std::string conflicting_header; |
| + std::string winning_extension_id; |
| ResponseHeaders::const_iterator i; |
| for (i = (*delta)->deleted_response_headers.begin(); |
| i != (*delta)->deleted_response_headers.end(); ++i) { |
| if (removed_headers.find(ToLowerCase(*i)) != removed_headers.end()) { |
| + winning_extension_id = FindRemoveResponseHeader(deltas, i->first); |
| + conflicting_header = i->first; |
| extension_conflicts = true; |
| break; |
| } |
| @@ -943,7 +1029,10 @@ void MergeOnHeadersReceivedResponses( |
| net::NetLog::TYPE_CHROME_EXTENSION_MODIFIED_HEADERS, |
| CreateNetLogExtensionIdCallback(delta->get())); |
| } else { |
| - conflicting_extensions->insert((*delta)->extension_id); |
| + conflicting_extensions->Insert( |
| + ExtensionWarning::CreateResponseHeaderConflictWarning( |
| + (*delta)->extension_id, winning_extension_id, |
| + conflicting_header)); |
| net_log->AddEvent( |
| net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| CreateNetLogExtensionIdCallback(delta->get())); |
| @@ -957,10 +1046,11 @@ void MergeOnHeadersReceivedResponses( |
| bool MergeOnAuthRequiredResponses( |
| const EventResponseDeltas& deltas, |
| net::AuthCredentials* auth_credentials, |
| - std::set<std::string>* conflicting_extensions, |
| + ExtensionWarningSet* conflicting_extensions, |
| const net::BoundNetLog* net_log) { |
| CHECK(auth_credentials); |
| bool credentials_set = false; |
| + std::string winning_extension_id; |
| for (EventResponseDeltas::const_iterator delta = deltas.begin(); |
| delta != deltas.end(); |
| @@ -972,7 +1062,9 @@ bool MergeOnAuthRequiredResponses( |
| (*delta)->auth_credentials->username() || |
| auth_credentials->password() != (*delta)->auth_credentials->password(); |
| if (credentials_set && different) { |
| - conflicting_extensions->insert((*delta)->extension_id); |
| + conflicting_extensions->Insert( |
| + ExtensionWarning::CreateCredentialsConflictWarning( |
| + (*delta)->extension_id, winning_extension_id)); |
| net_log->AddEvent( |
| net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| CreateNetLogExtensionIdCallback(delta->get())); |
| @@ -982,6 +1074,7 @@ bool MergeOnAuthRequiredResponses( |
| CreateNetLogExtensionIdCallback(delta->get())); |
| *auth_credentials = *(*delta)->auth_credentials; |
| credentials_set = true; |
| + winning_extension_id = (*delta)->extension_id; |
| } |
| } |
| return credentials_set; |