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 "chrome/browser/extensions/api/declarative_webrequest/webrequest_action .h" | 5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action .h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" | 15 #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" |
16 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h" | 16 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h" |
17 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | 17 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
18 #include "net/url_request/url_request.h" | 18 #include "net/url_request/url_request.h" |
19 | 19 |
20 namespace extensions { | 20 namespace extensions { |
21 | 21 |
22 namespace keys = declarative_webrequest_constants; | 22 namespace keys = declarative_webrequest_constants; |
23 namespace helpers = extension_web_request_api_helpers; | |
23 | 24 |
24 namespace { | 25 namespace { |
25 // Error messages. | 26 // Error messages. |
26 const char kInvalidInstanceTypeError[] = | 27 const char kInvalidInstanceTypeError[] = |
27 "An action has an invalid instanceType: %s"; | 28 "An action has an invalid instanceType: %s"; |
28 | 29 |
29 const char kTransparentImageUrl[] = "data:image/png;base64,iVBORw0KGgoAAAANSUh" | 30 const char kTransparentImageUrl[] = "data:image/png;base64,iVBORw0KGgoAAAANSUh" |
30 "EUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="; | 31 "EUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="; |
31 const char kEmptyDocumentUrl[] = "data:text/html,"; | 32 const char kEmptyDocumentUrl[] = "data:text/html,"; |
32 | 33 |
33 #define INPUT_FORMAT_VALIDATE(test) do { \ | 34 #define INPUT_FORMAT_VALIDATE(test) do { \ |
34 if (!(test)) { \ | 35 if (!(test)) { \ |
35 *bad_message = true; \ | 36 *bad_message = true; \ |
36 return scoped_ptr<WebRequestAction>(NULL); \ | 37 return scoped_ptr<WebRequestAction>(NULL); \ |
37 } \ | 38 } \ |
38 } while (0) | 39 } while (0) |
39 | 40 |
41 scoped_ptr<helpers::RequestCookie> ParseRequestCookie( | |
42 const DictionaryValue* dict) { | |
43 scoped_ptr<helpers::RequestCookie> result(new helpers::RequestCookie); | |
44 std::string tmp; | |
45 if (dict->GetString(keys::kNameKey, &tmp)) | |
46 result->name.reset(new std::string(tmp)); | |
47 if (dict->GetString(keys::kValueKey, &tmp)) | |
48 result->value.reset(new std::string(tmp)); | |
49 return result.Pass(); | |
50 } | |
51 | |
52 scoped_ptr<helpers::ResponseCookie> ParseResponseCookie( | |
53 const DictionaryValue* dict) { | |
54 scoped_ptr<helpers::ResponseCookie> result(new helpers::ResponseCookie); | |
55 std::string tmp; | |
56 int int_tmp = 0; | |
57 bool bool_tmp = false; | |
58 if (dict->GetString(keys::kNameKey, &tmp)) | |
59 result->name.reset(new std::string(tmp)); | |
60 if (dict->GetString(keys::kValueKey, &tmp)) | |
61 result->value.reset(new std::string(tmp)); | |
62 if (dict->GetString(keys::kExpiresKey, &tmp)) | |
63 result->expires.reset(new std::string(tmp)); | |
64 if (dict->GetInteger(keys::kMaxAgeKey, &int_tmp)) | |
65 result->max_age.reset(new int(int_tmp)); | |
66 if (dict->GetString(keys::kDomainKey, &tmp)) | |
67 result->domain.reset(new std::string(tmp)); | |
68 if (dict->GetString(keys::kPathKey, &tmp)) | |
69 result->path.reset(new std::string(tmp)); | |
70 if (dict->GetBoolean(keys::kSecureKey, &bool_tmp)) | |
71 result->secure.reset(new bool(bool_tmp)); | |
72 if (dict->GetBoolean(keys::kHttpOnlyKey, &bool_tmp)) | |
73 result->http_only.reset(new bool(bool_tmp)); | |
74 return result.Pass(); | |
75 } | |
76 | |
40 // Helper function for WebRequestActions that can be instantiated by just | 77 // Helper function for WebRequestActions that can be instantiated by just |
41 // calling the constructor. | 78 // calling the constructor. |
42 template <class T> | 79 template <class T> |
43 scoped_ptr<WebRequestAction> CallConstructorFactoryMethod( | 80 scoped_ptr<WebRequestAction> CallConstructorFactoryMethod( |
44 const base::DictionaryValue* dict, | 81 const base::DictionaryValue* dict, |
45 std::string* error, | 82 std::string* error, |
46 bool* bad_message) { | 83 bool* bad_message) { |
47 return scoped_ptr<WebRequestAction>(new T); | 84 return scoped_ptr<WebRequestAction>(new T); |
48 } | 85 } |
49 | 86 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
134 const base::DictionaryValue* dict, | 171 const base::DictionaryValue* dict, |
135 std::string* error, | 172 std::string* error, |
136 bool* bad_message) { | 173 bool* bad_message) { |
137 int minium_priority; | 174 int minium_priority; |
138 INPUT_FORMAT_VALIDATE( | 175 INPUT_FORMAT_VALIDATE( |
139 dict->GetInteger(keys::kLowerPriorityThanKey, &minium_priority)); | 176 dict->GetInteger(keys::kLowerPriorityThanKey, &minium_priority)); |
140 return scoped_ptr<WebRequestAction>( | 177 return scoped_ptr<WebRequestAction>( |
141 new WebRequestIgnoreRulesAction(minium_priority)); | 178 new WebRequestIgnoreRulesAction(minium_priority)); |
142 } | 179 } |
143 | 180 |
181 scoped_ptr<WebRequestAction> CreateRequestCookieAction( | |
182 const base::DictionaryValue* dict, | |
183 std::string* error, | |
184 bool* bad_message) { | |
185 using extension_web_request_api_helpers::RequestCookieModification; | |
186 using extension_web_request_api_helpers::ResponseCookieModification; | |
187 | |
188 linked_ptr<RequestCookieModification> modification( | |
189 new RequestCookieModification); | |
190 | |
191 // Get modification type. | |
192 std::string instance_type; | |
193 INPUT_FORMAT_VALIDATE( | |
194 dict->GetString(keys::kInstanceTypeKey, &instance_type)); | |
195 if (instance_type == keys::kAddRequestCookieType) | |
196 modification->type = helpers::ADD; | |
197 else if (instance_type == keys::kEditRequestCookieType) | |
198 modification->type = helpers::EDIT; | |
199 else if (instance_type == keys::kRemoveRequestCookieType) | |
200 modification->type = helpers::REMOVE; | |
201 else | |
202 INPUT_FORMAT_VALIDATE(false); | |
203 | |
204 // Get filter. | |
205 if (modification->type == helpers::EDIT || | |
206 modification->type == helpers::REMOVE) { | |
207 DictionaryValue* filter = NULL; | |
208 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kFilterKey, &filter)); | |
209 modification->filter = ParseRequestCookie(filter); | |
210 } | |
211 | |
212 // Get new value. | |
213 if (modification->type == helpers::ADD) { | |
214 DictionaryValue* value = NULL; | |
215 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kCookieKey, &value)); | |
216 modification->modification = ParseRequestCookie(value); | |
217 } else if (modification->type == helpers::EDIT) { | |
218 DictionaryValue* value = NULL; | |
219 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kModificationKey, &value)); | |
220 modification->modification = ParseRequestCookie(value); | |
221 } | |
222 | |
223 return scoped_ptr<WebRequestAction>( | |
224 new WebRequestCookieAction(modification, | |
225 linked_ptr<ResponseCookieModification>())); | |
226 } | |
227 | |
228 scoped_ptr<WebRequestAction> CreateResponseCookieAction( | |
229 const base::DictionaryValue* dict, | |
230 std::string* error, | |
231 bool* bad_message) { | |
232 using extension_web_request_api_helpers::RequestCookieModification; | |
233 using extension_web_request_api_helpers::ResponseCookieModification; | |
234 | |
235 linked_ptr<ResponseCookieModification> modification( | |
236 new ResponseCookieModification); | |
237 | |
238 // Get modification type. | |
239 std::string instance_type; | |
240 INPUT_FORMAT_VALIDATE( | |
241 dict->GetString(keys::kInstanceTypeKey, &instance_type)); | |
242 if (instance_type == keys::kAddResponseCookieType) | |
243 modification->type = helpers::ADD; | |
244 else if (instance_type == keys::kEditResponseCookieType) | |
245 modification->type = helpers::EDIT; | |
246 else if (instance_type == keys::kRemoveResponseCookieType) | |
247 modification->type = helpers::REMOVE; | |
248 else | |
249 INPUT_FORMAT_VALIDATE(false); | |
250 | |
251 // Get filter. | |
252 if (modification->type == helpers::EDIT || | |
253 modification->type == helpers::REMOVE) { | |
254 DictionaryValue* filter = NULL; | |
255 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kFilterKey, &filter)); | |
256 modification->filter = ParseResponseCookie(filter); | |
257 } | |
258 | |
259 // Get new value. | |
260 if (modification->type == helpers::ADD) { | |
261 DictionaryValue* value = NULL; | |
262 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kCookieKey, &value)); | |
263 modification->modification = ParseResponseCookie(value); | |
264 } else if (modification->type == helpers::EDIT) { | |
265 DictionaryValue* value = NULL; | |
266 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kModificationKey, &value)); | |
267 modification->modification = ParseResponseCookie(value); | |
268 } | |
269 | |
270 return scoped_ptr<WebRequestAction>( | |
271 new WebRequestCookieAction(linked_ptr<RequestCookieModification>(), | |
272 modification)); | |
273 } | |
274 | |
144 struct WebRequestActionFactory { | 275 struct WebRequestActionFactory { |
145 // Factory methods for WebRequestAction instances. |dict| contains the json | 276 // Factory methods for WebRequestAction instances. |dict| contains the json |
146 // dictionary that describes the action. |error| is used to return error | 277 // dictionary that describes the action. |error| is used to return error |
147 // messages in case the extension passed an action that was syntactically | 278 // messages in case the extension passed an action that was syntactically |
148 // correct but semantically incorrect. |bad_message| is set to true in case | 279 // correct but semantically incorrect. |bad_message| is set to true in case |
149 // |dict| does not confirm to the validated JSON specification. | 280 // |dict| does not confirm to the validated JSON specification. |
150 typedef scoped_ptr<WebRequestAction> | 281 typedef scoped_ptr<WebRequestAction> |
151 (* FactoryMethod)(const base::DictionaryValue* /* dict */ , | 282 (* FactoryMethod)(const base::DictionaryValue* /* dict */ , |
152 std::string* /* error */, | 283 std::string* /* error */, |
153 bool* /* bad_message */); | 284 bool* /* bad_message */); |
154 std::map<std::string, FactoryMethod> factory_methods; | 285 std::map<std::string, FactoryMethod> factory_methods; |
155 | 286 |
156 WebRequestActionFactory() { | 287 WebRequestActionFactory() { |
288 factory_methods[keys::kAddRequestCookieType] = | |
289 &CreateRequestCookieAction; | |
290 factory_methods[keys::kAddResponseCookieType] = | |
291 &CreateResponseCookieAction; | |
157 factory_methods[keys::kAddResponseHeaderType] = | 292 factory_methods[keys::kAddResponseHeaderType] = |
158 &CreateAddResponseHeaderAction; | 293 &CreateAddResponseHeaderAction; |
159 factory_methods[keys::kCancelRequestType] = | 294 factory_methods[keys::kCancelRequestType] = |
160 &CallConstructorFactoryMethod<WebRequestCancelAction>; | 295 &CallConstructorFactoryMethod<WebRequestCancelAction>; |
296 factory_methods[keys::kEditRequestCookieType] = | |
297 &CreateRequestCookieAction; | |
298 factory_methods[keys::kEditResponseCookieType] = | |
299 &CreateResponseCookieAction; | |
161 factory_methods[keys::kRedirectByRegExType] = | 300 factory_methods[keys::kRedirectByRegExType] = |
162 &CreateRedirectRequestByRegExAction; | 301 &CreateRedirectRequestByRegExAction; |
163 factory_methods[keys::kRedirectRequestType] = | 302 factory_methods[keys::kRedirectRequestType] = |
164 &CreateRedirectRequestAction; | 303 &CreateRedirectRequestAction; |
165 factory_methods[keys::kRedirectToTransparentImageType] = | 304 factory_methods[keys::kRedirectToTransparentImageType] = |
166 &CallConstructorFactoryMethod< | 305 &CallConstructorFactoryMethod< |
167 WebRequestRedirectToTransparentImageAction>; | 306 WebRequestRedirectToTransparentImageAction>; |
168 factory_methods[keys::kRedirectToEmptyDocumentType] = | 307 factory_methods[keys::kRedirectToEmptyDocumentType] = |
169 &CallConstructorFactoryMethod<WebRequestRedirectToEmptyDocumentAction>; | 308 &CallConstructorFactoryMethod<WebRequestRedirectToEmptyDocumentAction>; |
309 factory_methods[keys::kRemoveRequestCookieType] = | |
310 &CreateRequestCookieAction; | |
311 factory_methods[keys::kRemoveResponseCookieType] = | |
312 &CreateResponseCookieAction; | |
170 factory_methods[keys::kSetRequestHeaderType] = | 313 factory_methods[keys::kSetRequestHeaderType] = |
171 &CreateSetRequestHeaderAction; | 314 &CreateSetRequestHeaderAction; |
172 factory_methods[keys::kRemoveRequestHeaderType] = | 315 factory_methods[keys::kRemoveRequestHeaderType] = |
173 &CreateRemoveRequestHeaderAction; | 316 &CreateRemoveRequestHeaderAction; |
174 factory_methods[keys::kRemoveResponseHeaderType] = | 317 factory_methods[keys::kRemoveResponseHeaderType] = |
175 &CreateRemoveResponseHeaderAction; | 318 &CreateRemoveResponseHeaderAction; |
176 factory_methods[keys::kIgnoreRulesType] = | 319 factory_methods[keys::kIgnoreRulesType] = |
177 &CreateIgnoreRulesAction; | 320 &CreateIgnoreRulesAction; |
178 } | 321 } |
179 }; | 322 }; |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
719 LinkedPtrEventResponseDelta WebRequestIgnoreRulesAction::CreateDelta( | 862 LinkedPtrEventResponseDelta WebRequestIgnoreRulesAction::CreateDelta( |
720 net::URLRequest* request, | 863 net::URLRequest* request, |
721 RequestStages request_stage, | 864 RequestStages request_stage, |
722 const WebRequestRule::OptionalRequestData& optional_request_data, | 865 const WebRequestRule::OptionalRequestData& optional_request_data, |
723 const std::string& extension_id, | 866 const std::string& extension_id, |
724 const base::Time& extension_install_time) const { | 867 const base::Time& extension_install_time) const { |
725 CHECK(request_stage & GetStages()); | 868 CHECK(request_stage & GetStages()); |
726 return LinkedPtrEventResponseDelta(NULL); | 869 return LinkedPtrEventResponseDelta(NULL); |
727 } | 870 } |
728 | 871 |
872 // | |
873 // WebRequestCookieAction | |
874 // | |
875 | |
876 WebRequestCookieAction::WebRequestCookieAction( | |
Matt Perry
2012/07/09 23:26:13
It looks like the logic for the 2 types of cookies
battre
2012/08/02 17:17:34
Just saving a couple of lines of builder plate cod
| |
877 linked_ptr<RequestCookieModification> request_cookie_modification, | |
878 linked_ptr<ResponseCookieModification> response_cookie_modification) | |
879 : request_cookie_modification_(request_cookie_modification), | |
880 response_cookie_modification_(response_cookie_modification) { | |
881 // Either one needs to be set. | |
882 CHECK(!!request_cookie_modification_.get() ^ | |
883 !!response_cookie_modification_.get()); | |
884 } | |
885 | |
886 WebRequestCookieAction::~WebRequestCookieAction() {} | |
887 | |
888 int WebRequestCookieAction::GetStages() const { | |
889 if (request_cookie_modification_.get()) { | |
890 return ON_BEFORE_SEND_HEADERS; | |
891 } else if (response_cookie_modification_.get()) { | |
892 return ON_HEADERS_RECEIVED; | |
893 } else { | |
894 NOTREACHED(); | |
895 return 0; | |
896 } | |
897 } | |
898 | |
899 WebRequestAction::Type WebRequestCookieAction::GetType() const { | |
900 return WebRequestAction::ACTION_MODIFY_COOKIE; | |
901 } | |
902 | |
903 LinkedPtrEventResponseDelta WebRequestCookieAction::CreateDelta( | |
904 net::URLRequest* request, | |
905 RequestStages request_stage, | |
906 const WebRequestRule::OptionalRequestData& optional_request_data, | |
907 const std::string& extension_id, | |
908 const base::Time& extension_install_time) const { | |
909 CHECK(request_stage & GetStages()); | |
910 LinkedPtrEventResponseDelta result( | |
911 new extension_web_request_api_helpers::EventResponseDelta( | |
912 extension_id, extension_install_time)); | |
913 if (request_cookie_modification_.get()) { | |
914 result->request_cookie_modifications.push_back( | |
915 request_cookie_modification_); | |
916 } | |
917 if (response_cookie_modification_.get()) { | |
918 result->response_cookie_modifications.push_back( | |
919 response_cookie_modification_); | |
920 } | |
921 return result; | |
922 } | |
923 | |
729 } // namespace extensions | 924 } // namespace extensions |
OLD | NEW |