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

Side by Side Diff: chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc

Issue 10447090: Support Cookie modifications in Declarative WebRequest API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Split some parts into separate CLs Created 8 years, 5 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/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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698