Chromium Code Reviews| 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 |