OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/extension_webrequest_api.h" | 5 #include "chrome/browser/extensions/extension_webrequest_api.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 | 141 |
142 // Internal representation of the webRequest.RequestFilter type, used to | 142 // Internal representation of the webRequest.RequestFilter type, used to |
143 // filter what network events an extension cares about. | 143 // filter what network events an extension cares about. |
144 struct ExtensionWebRequestEventRouter::RequestFilter { | 144 struct ExtensionWebRequestEventRouter::RequestFilter { |
145 ExtensionExtent urls; | 145 ExtensionExtent urls; |
146 std::vector<ResourceType::Type> types; | 146 std::vector<ResourceType::Type> types; |
147 int tab_id; | 147 int tab_id; |
148 int window_id; | 148 int window_id; |
149 | 149 |
150 RequestFilter() : tab_id(-1), window_id(-1) {} | 150 RequestFilter() : tab_id(-1), window_id(-1) {} |
151 bool InitFromValue(const DictionaryValue& value); | 151 // Returns false if there was an error initializing. If it is a user error, |
152 // an error message is provided, otherwise the error is internal (and | |
153 // unexpected). | |
154 bool InitFromValue(const DictionaryValue& value, std::string* error); | |
152 }; | 155 }; |
153 | 156 |
154 // Internal representation of the extraInfoSpec parameter on webRequest events, | 157 // Internal representation of the extraInfoSpec parameter on webRequest events, |
155 // used to specify extra information to be included with network events. | 158 // used to specify extra information to be included with network events. |
156 struct ExtensionWebRequestEventRouter::ExtraInfoSpec { | 159 struct ExtensionWebRequestEventRouter::ExtraInfoSpec { |
157 enum Flags { | 160 enum Flags { |
158 REQUEST_LINE = 1<<0, | 161 REQUEST_LINE = 1<<0, |
159 REQUEST_HEADERS = 1<<1, | 162 REQUEST_HEADERS = 1<<1, |
160 STATUS_LINE = 1<<2, | 163 STATUS_LINE = 1<<2, |
161 RESPONSE_HEADERS = 1<<3, | 164 RESPONSE_HEADERS = 1<<3, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
200 // If non-empty, this contains the new URL that the request will redirect to. | 203 // If non-empty, this contains the new URL that the request will redirect to. |
201 GURL* new_url; | 204 GURL* new_url; |
202 | 205 |
203 // Time the request was issued. Used for logging purposes. | 206 // Time the request was issued. Used for logging purposes. |
204 base::Time request_time; | 207 base::Time request_time; |
205 | 208 |
206 BlockedRequest() : num_handlers_blocking(0), callback(NULL), new_url(NULL) {} | 209 BlockedRequest() : num_handlers_blocking(0), callback(NULL), new_url(NULL) {} |
207 }; | 210 }; |
208 | 211 |
209 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( | 212 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( |
210 const DictionaryValue& value) { | 213 const DictionaryValue& value, std::string* error) { |
211 for (DictionaryValue::key_iterator key = value.begin_keys(); | 214 for (DictionaryValue::key_iterator key = value.begin_keys(); |
212 key != value.end_keys(); ++key) { | 215 key != value.end_keys(); ++key) { |
213 if (*key == "urls") { | 216 if (*key == "urls") { |
214 ListValue* urls_value = NULL; | 217 ListValue* urls_value = NULL; |
215 if (!value.GetList("urls", &urls_value)) | 218 if (!value.GetList("urls", &urls_value)) |
216 return false; | 219 return false; |
217 for (size_t i = 0; i < urls_value->GetSize(); ++i) { | 220 for (size_t i = 0; i < urls_value->GetSize(); ++i) { |
218 std::string url; | 221 std::string url; |
219 URLPattern pattern(URLPattern::SCHEME_ALL); | 222 URLPattern pattern(URLPattern::SCHEME_ALL); |
220 if (!urls_value->GetString(i, &url) || | 223 if (!urls_value->GetString(i, &url) || |
221 pattern.Parse(url, URLPattern::PARSE_STRICT) != | 224 pattern.Parse(url, URLPattern::PARSE_STRICT) != |
222 URLPattern::PARSE_SUCCESS) | 225 URLPattern::PARSE_SUCCESS) { |
226 *error = ExtensionErrorUtils::FormatErrorMessage( | |
227 keys::kInvalidRequestFilterUrl, url); | |
223 return false; | 228 return false; |
229 } | |
224 urls.AddPattern(pattern); | 230 urls.AddPattern(pattern); |
225 } | 231 } |
226 } else if (*key == "types") { | 232 } else if (*key == "types") { |
227 ListValue* types_value = NULL; | 233 ListValue* types_value = NULL; |
228 if (!value.GetList("types", &types_value)) | 234 if (!value.GetList("types", &types_value)) |
229 return false; | 235 return false; |
230 for (size_t i = 0; i < types_value->GetSize(); ++i) { | 236 for (size_t i = 0; i < types_value->GetSize(); ++i) { |
231 std::string type_str; | 237 std::string type_str; |
232 ResourceType::Type type; | 238 ResourceType::Type type; |
233 if (!types_value->GetString(i, &type_str) || | 239 if (!types_value->GetString(i, &type_str) || |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
659 size_t slash_sep = sub_event_name.find('/'); | 665 size_t slash_sep = sub_event_name.find('/'); |
660 std::string event_name = sub_event_name.substr(0, slash_sep); | 666 std::string event_name = sub_event_name.substr(0, slash_sep); |
661 | 667 |
662 if (!IsWebRequestEvent(event_name)) | 668 if (!IsWebRequestEvent(event_name)) |
663 return; | 669 return; |
664 | 670 |
665 EventListener listener; | 671 EventListener listener; |
666 listener.extension_id = extension_id; | 672 listener.extension_id = extension_id; |
667 listener.sub_event_name = sub_event_name; | 673 listener.sub_event_name = sub_event_name; |
668 | 674 |
675 // It's possible for AddEventListener to fail asynchronously. In that case, | |
676 // the renderer to believe the listener exists, while the browser does not. | |
battre
2011/04/27 09:45:31
nit: grammar in "the renderer to believe"
Matt Perry
2011/04/27 19:45:59
Done.
| |
677 // Ignore a RemoveEventListener in that case. | |
678 std::set<EventListener>::iterator found = | |
679 listeners_[profile_id][event_name].find(listener); | |
680 if (found == listeners_[profile_id][event_name].end()) | |
681 return; | |
682 | |
669 CHECK_EQ(listeners_[profile_id][event_name].count(listener), 1u) << | 683 CHECK_EQ(listeners_[profile_id][event_name].count(listener), 1u) << |
670 "extension=" << extension_id << " event=" << event_name; | 684 "extension=" << extension_id << " event=" << event_name; |
671 | 685 |
672 // Unblock any request that this event listener may have been blocking. | 686 // Unblock any request that this event listener may have been blocking. |
673 std::set<EventListener>::iterator found = | |
674 listeners_[profile_id][event_name].find(listener); | |
675 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); | 687 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); |
676 it != found->blocked_requests.end(); ++it) { | 688 it != found->blocked_requests.end(); ++it) { |
677 DecrementBlockCount(*it, false, GURL()); | 689 DecrementBlockCount(*it, false, GURL()); |
678 } | 690 } |
679 | 691 |
680 listeners_[profile_id][event_name].erase(listener); | 692 listeners_[profile_id][event_name].erase(listener); |
681 } | 693 } |
682 | 694 |
683 std::vector<const ExtensionWebRequestEventRouter::EventListener*> | 695 std::vector<const ExtensionWebRequestEventRouter::EventListener*> |
684 ExtensionWebRequestEventRouter::GetMatchingListeners( | 696 ExtensionWebRequestEventRouter::GetMatchingListeners( |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
772 return; | 784 return; |
773 iter->second &= ~event_type; | 785 iter->second &= ~event_type; |
774 } | 786 } |
775 | 787 |
776 bool WebRequestAddEventListener::RunImpl() { | 788 bool WebRequestAddEventListener::RunImpl() { |
777 // Argument 0 is the callback, which we don't use here. | 789 // Argument 0 is the callback, which we don't use here. |
778 | 790 |
779 ExtensionWebRequestEventRouter::RequestFilter filter; | 791 ExtensionWebRequestEventRouter::RequestFilter filter; |
780 if (HasOptionalArgument(1)) { | 792 if (HasOptionalArgument(1)) { |
781 DictionaryValue* value = NULL; | 793 DictionaryValue* value = NULL; |
794 error_.clear(); | |
782 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &value)); | 795 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &value)); |
783 EXTENSION_FUNCTION_VALIDATE(filter.InitFromValue(*value)); | 796 // Failure + an empty error string means a fatal error. |
797 EXTENSION_FUNCTION_VALIDATE(filter.InitFromValue(*value, &error_) || | |
798 !error_.empty()); | |
799 if (!error_.empty()) | |
800 return false; | |
784 } | 801 } |
785 | 802 |
786 int extra_info_spec = 0; | 803 int extra_info_spec = 0; |
787 if (HasOptionalArgument(2)) { | 804 if (HasOptionalArgument(2)) { |
788 ListValue* value = NULL; | 805 ListValue* value = NULL; |
789 EXTENSION_FUNCTION_VALIDATE(args_->GetList(2, &value)); | 806 EXTENSION_FUNCTION_VALIDATE(args_->GetList(2, &value)); |
790 EXTENSION_FUNCTION_VALIDATE( | 807 EXTENSION_FUNCTION_VALIDATE( |
791 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( | 808 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( |
792 *value, &extra_info_spec)); | 809 *value, &extra_info_spec)); |
793 } | 810 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
845 | 862 |
846 BrowserThread::PostTask( | 863 BrowserThread::PostTask( |
847 BrowserThread::IO, FROM_HERE, | 864 BrowserThread::IO, FROM_HERE, |
848 NewRunnableFunction( | 865 NewRunnableFunction( |
849 &EventHandledOnIOThread, | 866 &EventHandledOnIOThread, |
850 profile()->GetRuntimeId(), extension_id(), | 867 profile()->GetRuntimeId(), extension_id(), |
851 event_name, sub_event_name, request_id, cancel, new_url)); | 868 event_name, sub_event_name, request_id, cancel, new_url)); |
852 | 869 |
853 return true; | 870 return true; |
854 } | 871 } |
OLD | NEW |