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

Side by Side Diff: chrome/browser/extensions/api/cookies/cookies_api.cc

Issue 10702088: Refactor chrome.cookies API to use JSON schema compiler. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Cookies helpers, unit tests, other nits 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
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 // Implements the Chrome Extensions Cookies API. 5 // Implements the Chrome Extensions Cookies API.
6 6
7 #include "chrome/browser/extensions/api/cookies/cookies_api.h" 7 #include "chrome/browser/extensions/api/cookies/cookies_api.h"
8 8
9 #include <vector>
10
9 #include "base/bind.h" 11 #include "base/bind.h"
10 #include "base/json/json_writer.h" 12 #include "base/json/json_writer.h"
13 #include "base/memory/linked_ptr.h"
14 #include "base/memory/scoped_ptr.h"
11 #include "base/values.h" 15 #include "base/values.h"
12 #include "chrome/browser/extensions/api/cookies/cookies_api_constants.h" 16 #include "chrome/browser/extensions/api/cookies/cookies_api_constants.h"
13 #include "chrome/browser/extensions/api/cookies/cookies_helpers.h" 17 #include "chrome/browser/extensions/api/cookies/cookies_helpers.h"
14 #include "chrome/browser/extensions/extension_event_router.h" 18 #include "chrome/browser/extensions/extension_event_router.h"
15 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h" 20 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_list.h" 21 #include "chrome/browser/ui/browser_list.h"
18 #include "chrome/common/chrome_notification_types.h" 22 #include "chrome/common/chrome_notification_types.h"
23 #include "chrome/common/extensions/api/cookies.h"
19 #include "chrome/common/extensions/extension.h" 24 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/extensions/extension_error_utils.h" 25 #include "chrome/common/extensions/extension_error_utils.h"
21 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/notification_service.h" 27 #include "content/public/browser/notification_service.h"
23 #include "net/cookies/cookie_monster.h" 28 #include "net/cookies/cookie_monster.h"
24 #include "net/url_request/url_request_context.h" 29 #include "net/url_request/url_request_context.h"
25 #include "net/url_request/url_request_context_getter.h" 30 #include "net/url_request/url_request_context_getter.h"
26 31
27 using content::BrowserThread; 32 using content::BrowserThread;
33 using extensions::api::cookies::Cookie;
34 using extensions::api::cookies::CookieStore;
35
36 namespace Get = extensions::api::cookies::Get;
37 namespace GetAll = extensions::api::cookies::GetAll;
38 namespace GetAllCookieStores = extensions::api::cookies::GetAllCookieStores;
39 namespace Remove = extensions::api::cookies::Remove;
40 namespace Set = extensions::api::cookies::Set;
28 41
29 namespace extensions { 42 namespace extensions {
30 namespace keys = cookies_api_constants; 43 namespace keys = cookies_api_constants;
31 44
32 ExtensionCookiesEventRouter::ExtensionCookiesEventRouter(Profile* profile) 45 ExtensionCookiesEventRouter::ExtensionCookiesEventRouter(Profile* profile)
33 : profile_(profile) {} 46 : profile_(profile) {
47 }
34 48
35 ExtensionCookiesEventRouter::~ExtensionCookiesEventRouter() {} 49 ExtensionCookiesEventRouter::~ExtensionCookiesEventRouter() {
50 }
36 51
37 void ExtensionCookiesEventRouter::Init() { 52 void ExtensionCookiesEventRouter::Init() {
38 CHECK(registrar_.IsEmpty()); 53 CHECK(registrar_.IsEmpty());
39 registrar_.Add(this, 54 registrar_.Add(this,
40 chrome::NOTIFICATION_COOKIE_CHANGED, 55 chrome::NOTIFICATION_COOKIE_CHANGED,
41 content::NotificationService::AllBrowserContextsAndSources()); 56 content::NotificationService::AllBrowserContextsAndSources());
42 } 57 }
43 58
44 void ExtensionCookiesEventRouter::Observe( 59 void ExtensionCookiesEventRouter::Observe(
45 int type, 60 int type,
(...skipping 14 matching lines...) Expand all
60 NOTREACHED(); 75 NOTREACHED();
61 } 76 }
62 } 77 }
63 78
64 void ExtensionCookiesEventRouter::CookieChanged( 79 void ExtensionCookiesEventRouter::CookieChanged(
65 Profile* profile, 80 Profile* profile,
66 ChromeCookieDetails* details) { 81 ChromeCookieDetails* details) {
67 ListValue args; 82 ListValue args;
68 DictionaryValue* dict = new DictionaryValue(); 83 DictionaryValue* dict = new DictionaryValue();
69 dict->SetBoolean(keys::kRemovedKey, details->removed); 84 dict->SetBoolean(keys::kRemovedKey, details->removed);
70 dict->Set( 85
71 keys::kCookieKey, 86 scoped_ptr<Cookie> cookie(
72 cookies_helpers::CreateCookieValue(*details->cookie, 87 cookies_helpers::CreateCookie(*details->cookie,
73 cookies_helpers::GetStoreIdFromProfile(profile))); 88 cookies_helpers::GetStoreIdFromProfile(profile)));
89 dict->Set(keys::kCookieKey, cookie->ToValue().release());
74 90
75 // Map the interal cause to an external string. 91 // Map the interal cause to an external string.
76 std::string cause; 92 std::string cause;
77 switch (details->cause) { 93 switch (details->cause) {
78 case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPLICIT: 94 case net::CookieMonster::Delegate::CHANGE_COOKIE_EXPLICIT:
79 cause = keys::kExplicitChangeCause; 95 cause = keys::kExplicitChangeCause;
80 break; 96 break;
81 97
82 case net::CookieMonster::Delegate::CHANGE_COOKIE_OVERWRITE: 98 case net::CookieMonster::Delegate::CHANGE_COOKIE_OVERWRITE:
83 cause = keys::kOverwriteChangeCause; 99 cause = keys::kOverwriteChangeCause;
(...skipping 28 matching lines...) Expand all
112 void ExtensionCookiesEventRouter::DispatchEvent(Profile* profile, 128 void ExtensionCookiesEventRouter::DispatchEvent(Profile* profile,
113 const char* event_name, 129 const char* event_name,
114 const std::string& json_args, 130 const std::string& json_args,
115 GURL& cookie_domain) { 131 GURL& cookie_domain) {
116 if (profile && profile->GetExtensionEventRouter()) { 132 if (profile && profile->GetExtensionEventRouter()) {
117 profile->GetExtensionEventRouter()->DispatchEventToRenderers( 133 profile->GetExtensionEventRouter()->DispatchEventToRenderers(
118 event_name, json_args, profile, cookie_domain, EventFilteringInfo()); 134 event_name, json_args, profile, cookie_domain, EventFilteringInfo());
119 } 135 }
120 } 136 }
121 137
122 bool CookiesFunction::ParseUrl(const DictionaryValue* details, GURL* url, 138 bool CookiesFunction::ParseUrl(const std::string& url_string, GURL* url,
123 bool check_host_permissions) { 139 bool check_host_permissions) {
124 DCHECK(details && url);
125 std::string url_string;
126 // Get the URL string or return false.
127 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kUrlKey, &url_string));
128 *url = GURL(url_string); 140 *url = GURL(url_string);
129 if (!url->is_valid()) { 141 if (!url->is_valid()) {
130 error_ = ExtensionErrorUtils::FormatErrorMessage( 142 error_ = ExtensionErrorUtils::FormatErrorMessage(
131 keys::kInvalidUrlError, url_string); 143 keys::kInvalidUrlError, url_string);
132 return false; 144 return false;
133 } 145 }
134 // Check against host permissions if needed. 146 // Check against host permissions if needed.
135 if (check_host_permissions && 147 if (check_host_permissions &&
136 !GetExtension()->HasHostPermission(*url)) { 148 !GetExtension()->HasHostPermission(*url)) {
137 error_ = ExtensionErrorUtils::FormatErrorMessage( 149 error_ = ExtensionErrorUtils::FormatErrorMessage(
138 keys::kNoHostPermissionsError, url->spec()); 150 keys::kNoHostPermissionsError, url->spec());
139 return false; 151 return false;
140 } 152 }
141 return true; 153 return true;
142 } 154 }
143 155
144 bool CookiesFunction::ParseStoreContext(const DictionaryValue* details, 156 bool CookiesFunction::ParseStoreContext(net::URLRequestContextGetter** context,
145 net::URLRequestContextGetter** context,
146 std::string* store_id) { 157 std::string* store_id) {
147 DCHECK(details && (context || store_id)); 158 DCHECK((context || store_id->empty()));
148 Profile* store_profile = NULL; 159 Profile* store_profile = NULL;
149 if (details->HasKey(keys::kStoreIdKey)) { 160 if (!store_id->empty()) {
150 // The store ID was explicitly specified in the details dictionary.
151 // Retrieve its corresponding cookie store.
152 std::string store_id_value;
153 // Get the store ID string or return false.
154 EXTENSION_FUNCTION_VALIDATE(
155 details->GetString(keys::kStoreIdKey, &store_id_value));
156 store_profile = cookies_helpers::ChooseProfileFromStoreId( 161 store_profile = cookies_helpers::ChooseProfileFromStoreId(
157 store_id_value, profile(), include_incognito()); 162 *store_id, profile(), include_incognito());
158 if (!store_profile) { 163 if (!store_profile) {
159 error_ = ExtensionErrorUtils::FormatErrorMessage( 164 error_ = ExtensionErrorUtils::FormatErrorMessage(
160 keys::kInvalidStoreIdError, store_id_value); 165 keys::kInvalidStoreIdError, *store_id);
161 return false; 166 return false;
162 } 167 }
163 } else { 168 } else {
164 // The store ID was not specified; use the current execution context's 169 // The store ID was not specified; use the current execution context's
165 // cookie store by default. 170 // cookie store by default.
166 // GetCurrentBrowser() already takes into account incognito settings. 171 // GetCurrentBrowser() already takes into account incognito settings.
167 Browser* current_browser = GetCurrentBrowser(); 172 Browser* current_browser = GetCurrentBrowser();
168 if (!current_browser) { 173 if (!current_browser) {
169 error_ = keys::kNoCookieStoreFoundError; 174 error_ = keys::kNoCookieStoreFoundError;
170 return false; 175 return false;
171 } 176 }
172 store_profile = current_browser->profile(); 177 store_profile = current_browser->profile();
178 *store_id = cookies_helpers::GetStoreIdFromProfile(store_profile);
173 } 179 }
174 DCHECK(store_profile);
175 180
176 if (context) 181 if (context)
177 *context = store_profile->GetRequestContext(); 182 *context = store_profile->GetRequestContext();
178 if (store_id) 183 DCHECK(context);
179 *store_id = cookies_helpers::GetStoreIdFromProfile(store_profile);
180 184
181 return true; 185 return true;
182 } 186 }
183 187
184 GetCookieFunction::GetCookieFunction() {} 188 GetCookieFunction::GetCookieFunction() {
189 }
185 190
186 GetCookieFunction::~GetCookieFunction() {} 191 GetCookieFunction::~GetCookieFunction() {
192 }
187 193
188 bool GetCookieFunction::RunImpl() { 194 bool GetCookieFunction::RunImpl() {
189 // Return false if the arguments are malformed. 195 parsed_args_ = Get::Params::Create(*args_);
190 DictionaryValue* details; 196 EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
191 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
192 DCHECK(details);
193 197
194 // Read/validate input parameters. 198 // Read/validate input parameters.
195 if (!ParseUrl(details, &url_, true)) 199 if (!ParseUrl(parsed_args_->details.url, &url_, true))
196 return false; 200 return false;
197 201
198 // Get the cookie name string or return false. 202 net::URLRequestContextGetter* store_context = NULL;
199 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_)); 203 std::string* store_id = parsed_args_->details.store_id.get() ?
204 parsed_args_->details.store_id.get() : new std::string("");
205 if (!ParseStoreContext(&store_context, store_id))
206 return false;
207 store_context_ = store_context;
208 if (!parsed_args_->details.store_id.get())
209 parsed_args_->details.store_id.reset(store_id);
210 DCHECK(parsed_args_->details.store_id.get());
Aaron Boodman 2012/07/09 17:34:48 Looks like you always expect this value to get pas
mitchellwrosen 2012/07/09 19:36:12 I realized there's definitely no way for this chec
200 211
201 net::URLRequestContextGetter* store_context = NULL; 212 DCHECK(store_context && !parsed_args_->details.store_id->empty());
Aaron Boodman 2012/07/09 17:34:49 I don't think it's necessary to DCHECK either of t
mitchellwrosen 2012/07/09 19:36:12 Done.
202 if (!ParseStoreContext(details, &store_context, &store_id_))
203 return false;
204
205 DCHECK(store_context && !store_id_.empty());
206 store_context_ = store_context; 213 store_context_ = store_context;
207 214
208 bool rv = BrowserThread::PostTask( 215 bool rv = BrowserThread::PostTask(
209 BrowserThread::IO, FROM_HERE, 216 BrowserThread::IO, FROM_HERE,
210 base::Bind(&GetCookieFunction::GetCookieOnIOThread, this)); 217 base::Bind(&GetCookieFunction::GetCookieOnIOThread, this));
211 DCHECK(rv); 218 DCHECK(rv);
212 219
213 // Will finish asynchronously. 220 // Will finish asynchronously.
214 return true; 221 return true;
215 } 222 }
216 223
217 void GetCookieFunction::GetCookieOnIOThread() { 224 void GetCookieFunction::GetCookieOnIOThread() {
218 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 225 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
219 net::CookieStore* cookie_store = 226 net::CookieStore* cookie_store =
220 store_context_->GetURLRequestContext()->cookie_store(); 227 store_context_->GetURLRequestContext()->cookie_store();
221 cookies_helpers::GetCookieListFromStore( 228 cookies_helpers::GetCookieListFromStore(
222 cookie_store, url_, 229 cookie_store, url_,
223 base::Bind(&GetCookieFunction::GetCookieCallback, this)); 230 base::Bind(&GetCookieFunction::GetCookieCallback, this));
224 } 231 }
225 232
226 void GetCookieFunction::GetCookieCallback(const net::CookieList& cookie_list) { 233 void GetCookieFunction::GetCookieCallback(const net::CookieList& cookie_list) {
227 net::CookieList::const_iterator it; 234 net::CookieList::const_iterator it;
228 for (it = cookie_list.begin(); it != cookie_list.end(); ++it) { 235 for (it = cookie_list.begin(); it != cookie_list.end(); ++it) {
229 // Return the first matching cookie. Relies on the fact that the 236 // Return the first matching cookie. Relies on the fact that the
230 // CookieMonster returns them in canonical order (longest path, then 237 // CookieMonster returns them in canonical order (longest path, then
231 // earliest creation time). 238 // earliest creation time).
232 if (it->Name() == name_) { 239 if (it->Name() == parsed_args_->details.name) {
233 result_.reset( 240 scoped_ptr<Cookie> cookie(
234 cookies_helpers::CreateCookieValue(*it, store_id_)); 241 cookies_helpers::CreateCookie(*it, *parsed_args_->details.store_id));
242 result_.reset(Get::Result::Create(*cookie));
235 break; 243 break;
236 } 244 }
237 } 245 }
238 246
239 // The cookie doesn't exist; return null. 247 // The cookie doesn't exist; return null.
240 if (it == cookie_list.end()) 248 if (it == cookie_list.end())
241 result_.reset(Value::CreateNullValue()); 249 result_.reset(Value::CreateNullValue());
242 250
243 bool rv = BrowserThread::PostTask( 251 bool rv = BrowserThread::PostTask(
244 BrowserThread::UI, FROM_HERE, 252 BrowserThread::UI, FROM_HERE,
245 base::Bind(&GetCookieFunction::RespondOnUIThread, this)); 253 base::Bind(&GetCookieFunction::RespondOnUIThread, this));
246 DCHECK(rv); 254 DCHECK(rv);
247 } 255 }
248 256
249 void GetCookieFunction::RespondOnUIThread() { 257 void GetCookieFunction::RespondOnUIThread() {
250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
251 SendResponse(true); 259 SendResponse(true);
252 } 260 }
253 261
254 GetAllCookiesFunction::GetAllCookiesFunction() : details_(NULL) {} 262 GetAllCookiesFunction::GetAllCookiesFunction() {
263 }
255 264
256 GetAllCookiesFunction::~GetAllCookiesFunction() {} 265 GetAllCookiesFunction::~GetAllCookiesFunction() {
266 }
257 267
258 bool GetAllCookiesFunction::RunImpl() { 268 bool GetAllCookiesFunction::RunImpl() {
259 // Return false if the arguments are malformed. 269 parsed_args_ = GetAll::Params::Create(*args_);
260 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details_)); 270 EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
261 DCHECK(details_);
262 271
263 // Read/validate input parameters. 272 // Read/validate input parameters.
264 if (details_->HasKey(keys::kUrlKey) && !ParseUrl(details_, &url_, false)) 273 scoped_ptr<GetAll::Params> params(GetAll::Params::Create(*args_));
Aaron Boodman 2012/07/09 17:34:49 Why are you creating another instance of this? Isn
mitchellwrosen 2012/07/09 19:36:12 Sorry, I re-factored a couple times and forgot to
265 return false; 274 if (params->details.url.get()) {
275 if (!ParseUrl(*params->details.url, &url_, false))
276 return false;
277 }
266 278
267 net::URLRequestContextGetter* store_context = NULL; 279 net::URLRequestContextGetter* store_context = NULL;
268 if (!ParseStoreContext(details_, &store_context, &store_id_)) 280 std::string* store_id = parsed_args_->details.store_id.get() ?
281 parsed_args_->details.store_id.get() :
282 new std::string(""); // Wrapped in a scoped_ptr below.
283 if (!ParseStoreContext(&store_context, store_id))
269 return false; 284 return false;
Aaron Boodman 2012/07/09 17:34:49 The new string leaks here. I think safer/easier to
mitchellwrosen 2012/07/09 19:36:12 Done.
270 DCHECK(store_context);
271 store_context_ = store_context; 285 store_context_ = store_context;
286 if (!parsed_args_->details.store_id.get())
287 parsed_args_->details.store_id.reset(store_id);
272 288
273 bool rv = BrowserThread::PostTask( 289 bool rv = BrowserThread::PostTask(
274 BrowserThread::IO, FROM_HERE, 290 BrowserThread::IO, FROM_HERE,
275 base::Bind(&GetAllCookiesFunction::GetAllCookiesOnIOThread, this)); 291 base::Bind(&GetAllCookiesFunction::GetAllCookiesOnIOThread, this));
276 DCHECK(rv); 292 DCHECK(rv);
277 293
278 // Will finish asynchronously. 294 // Will finish asynchronously.
279 return true; 295 return true;
280 } 296 }
281 297
282 void GetAllCookiesFunction::GetAllCookiesOnIOThread() { 298 void GetAllCookiesFunction::GetAllCookiesOnIOThread() {
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
284 net::CookieStore* cookie_store = 300 net::CookieStore* cookie_store =
285 store_context_->GetURLRequestContext()->cookie_store(); 301 store_context_->GetURLRequestContext()->cookie_store();
286 cookies_helpers::GetCookieListFromStore( 302 cookies_helpers::GetCookieListFromStore(
287 cookie_store, url_, 303 cookie_store, url_,
288 base::Bind(&GetAllCookiesFunction::GetAllCookiesCallback, this)); 304 base::Bind(&GetAllCookiesFunction::GetAllCookiesCallback, this));
289 } 305 }
290 306
291 void GetAllCookiesFunction::GetAllCookiesCallback( 307 void GetAllCookiesFunction::GetAllCookiesCallback(
292 const net::CookieList& cookie_list) { 308 const net::CookieList& cookie_list) {
293 const extensions::Extension* extension = GetExtension(); 309 const extensions::Extension* extension = GetExtension();
294 if (extension) { 310 if (extension) {
295 ListValue* matching_list = new ListValue(); 311 std::vector<linked_ptr<Cookie> > match_vector;
296 cookies_helpers::AppendMatchingCookiesToList( 312 cookies_helpers::AppendMatchingCookiesToVector(
297 cookie_list, store_id_, url_, details_, 313 cookie_list, url_, &parsed_args_->details,
298 GetExtension(), matching_list); 314 GetExtension(), &match_vector);
299 result_.reset(matching_list); 315 result_.reset(GetAll::Result::Create(match_vector));
300 } 316 }
301 bool rv = BrowserThread::PostTask( 317 bool rv = BrowserThread::PostTask(
302 BrowserThread::UI, FROM_HERE, 318 BrowserThread::UI, FROM_HERE,
303 base::Bind(&GetAllCookiesFunction::RespondOnUIThread, this)); 319 base::Bind(&GetAllCookiesFunction::RespondOnUIThread, this));
304 DCHECK(rv); 320 DCHECK(rv);
305 } 321 }
306 322
307 void GetAllCookiesFunction::RespondOnUIThread() { 323 void GetAllCookiesFunction::RespondOnUIThread() {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
309 SendResponse(true); 325 SendResponse(true);
310 } 326 }
311 327
312 SetCookieFunction::SetCookieFunction() 328 SetCookieFunction::SetCookieFunction() {
313 : secure_(false),
314 http_only_(false),
315 success_(false) {
316 } 329 }
317 330
318 SetCookieFunction::~SetCookieFunction() { 331 SetCookieFunction::~SetCookieFunction() {
319 } 332 }
320 333
321 bool SetCookieFunction::RunImpl() { 334 bool SetCookieFunction::RunImpl() {
322 // Return false if the arguments are malformed. 335 parsed_args_ = Set::Params::Create(*args_);
323 DictionaryValue* details; 336 EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
324 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
325 DCHECK(details);
326 337
327 // Read/validate input parameters. 338 // Read/validate input parameters.
328 if (!ParseUrl(details, &url_, true)) 339 if (!ParseUrl(parsed_args_->details.url, &url_, true))
329 return false; 340 return false;
330 // The macros below return false if argument types are not as expected.
331 if (details->HasKey(keys::kNameKey))
332 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_));
333 if (details->HasKey(keys::kValueKey))
334 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kValueKey, &value_));
335 if (details->HasKey(keys::kDomainKey))
336 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kDomainKey, &domain_));
337 if (details->HasKey(keys::kPathKey))
338 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kPathKey, &path_));
339
340 if (details->HasKey(keys::kSecureKey)) {
341 EXTENSION_FUNCTION_VALIDATE(
342 details->GetBoolean(keys::kSecureKey, &secure_));
343 }
344 if (details->HasKey(keys::kHttpOnlyKey)) {
345 EXTENSION_FUNCTION_VALIDATE(
346 details->GetBoolean(keys::kHttpOnlyKey, &http_only_));
347 }
348 if (details->HasKey(keys::kExpirationDateKey)) {
349 Value* expiration_date_value;
350 EXTENSION_FUNCTION_VALIDATE(details->Get(keys::kExpirationDateKey,
351 &expiration_date_value));
352 double expiration_date;
353 if (expiration_date_value->IsType(Value::TYPE_INTEGER)) {
354 int expiration_date_int;
355 EXTENSION_FUNCTION_VALIDATE(
356 expiration_date_value->GetAsInteger(&expiration_date_int));
357 expiration_date = static_cast<double>(expiration_date_int);
358 } else {
359 EXTENSION_FUNCTION_VALIDATE(
360 expiration_date_value->GetAsDouble(&expiration_date));
361 }
362 // Time::FromDoubleT converts double time 0 to empty Time object. So we need
363 // to do special handling here.
364 expiration_time_ = (expiration_date == 0) ?
365 base::Time::UnixEpoch() : base::Time::FromDoubleT(expiration_date);
366 }
367 341
368 net::URLRequestContextGetter* store_context = NULL; 342 net::URLRequestContextGetter* store_context = NULL;
369 if (!ParseStoreContext(details, &store_context, NULL)) 343 std::string* store_id = parsed_args_->details.store_id.get() ?
344 parsed_args_->details.store_id.get() : new std::string("");
345 if (!ParseStoreContext(&store_context, store_id))
370 return false; 346 return false;
371 DCHECK(store_context);
372 store_context_ = store_context; 347 store_context_ = store_context;
348 if (!parsed_args_->details.store_id.get())
349 parsed_args_->details.store_id.reset(store_id);
373 350
374 bool rv = BrowserThread::PostTask( 351 bool rv = BrowserThread::PostTask(
375 BrowserThread::IO, FROM_HERE, 352 BrowserThread::IO, FROM_HERE,
376 base::Bind(&SetCookieFunction::SetCookieOnIOThread, this)); 353 base::Bind(&SetCookieFunction::SetCookieOnIOThread, this));
377 DCHECK(rv); 354 DCHECK(rv);
378 355
379 // Will finish asynchronously. 356 // Will finish asynchronously.
380 return true; 357 return true;
381 } 358 }
382 359
383 void SetCookieFunction::SetCookieOnIOThread() { 360 void SetCookieFunction::SetCookieOnIOThread() {
384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
385 net::CookieMonster* cookie_monster = 362 net::CookieMonster* cookie_monster =
386 store_context_->GetURLRequestContext()->cookie_store()-> 363 store_context_->GetURLRequestContext()->cookie_store()->
387 GetCookieMonster(); 364 GetCookieMonster();
365
366 base::Time expiration_time;
367 if (parsed_args_->details.expiration_date.get()) {
368 // Time::FromDoubleT converts double time 0 to empty Time object. So we need
369 // to do special handling here.
370 expiration_time = (*parsed_args_->details.expiration_date == 0) ?
371 base::Time::UnixEpoch() :
372 base::Time::FromDoubleT(*parsed_args_->details.expiration_date);
373 }
374
375 if (parsed_args_->details.name.get())
376 LOG(INFO) << "Cookie name: " << *parsed_args_->details.name;
377
388 cookie_monster->SetCookieWithDetailsAsync( 378 cookie_monster->SetCookieWithDetailsAsync(
389 url_, name_, value_, domain_, path_, expiration_time_, 379 url_,
390 secure_, http_only_, base::Bind(&SetCookieFunction::PullCookie, this)); 380 parsed_args_->details.name.get() ? *parsed_args_->details.name : "",
381 parsed_args_->details.value.get() ? *parsed_args_->details.value : "",
382 parsed_args_->details.domain.get() ? *parsed_args_->details.domain : "",
383 parsed_args_->details.path.get() ? *parsed_args_->details.path : "",
384 expiration_time,
385 parsed_args_->details.secure.get() ?
386 *parsed_args_->details.secure.get() :
387 false,
388 parsed_args_->details.http_only.get() ?
389 *parsed_args_->details.http_only :
390 false,
391 base::Bind(&SetCookieFunction::PullCookie, this));
391 } 392 }
392 393
393 void SetCookieFunction::PullCookie(bool set_cookie_result) { 394 void SetCookieFunction::PullCookie(bool set_cookie_result) {
394 // Pull the newly set cookie. 395 // Pull the newly set cookie.
395 net::CookieMonster* cookie_monster = 396 net::CookieMonster* cookie_monster =
396 store_context_->GetURLRequestContext()->cookie_store()-> 397 store_context_->GetURLRequestContext()->cookie_store()->
397 GetCookieMonster(); 398 GetCookieMonster();
398 success_ = set_cookie_result; 399 success_ = set_cookie_result;
399 cookies_helpers::GetCookieListFromStore( 400 cookies_helpers::GetCookieListFromStore(
400 cookie_monster, url_, 401 cookie_monster, url_,
401 base::Bind(&SetCookieFunction::PullCookieCallback, this)); 402 base::Bind(&SetCookieFunction::PullCookieCallback, this));
402 } 403 }
403 404
404 void SetCookieFunction::PullCookieCallback(const net::CookieList& cookie_list) { 405 void SetCookieFunction::PullCookieCallback(const net::CookieList& cookie_list) {
405 net::CookieList::const_iterator it; 406 net::CookieList::const_iterator it;
406 for (it = cookie_list.begin(); it != cookie_list.end(); ++it) { 407 for (it = cookie_list.begin(); it != cookie_list.end(); ++it) {
407 // Return the first matching cookie. Relies on the fact that the 408 // Return the first matching cookie. Relies on the fact that the
408 // CookieMonster returns them in canonical order (longest path, then 409 // CookieMonster returns them in canonical order (longest path, then
409 // earliest creation time). 410 // earliest creation time).
410 if (it->Name() == name_) { 411 std::string name = parsed_args_->details.name.get() ?
411 result_.reset( 412 *parsed_args_->details.name : "";
412 cookies_helpers::CreateCookieValue(*it, store_id_)); 413 if (it->Name() == name) {
414 scoped_ptr<Cookie> cookie(
415 cookies_helpers::CreateCookie(*it, *parsed_args_->details.store_id));
416 result_.reset(Set::Result::Create(*cookie));
413 break; 417 break;
414 } 418 }
415 } 419 }
416 420
417 bool rv = BrowserThread::PostTask( 421 bool rv = BrowserThread::PostTask(
418 BrowserThread::UI, FROM_HERE, 422 BrowserThread::UI, FROM_HERE,
419 base::Bind(&SetCookieFunction::RespondOnUIThread, this)); 423 base::Bind(&SetCookieFunction::RespondOnUIThread, this));
420 DCHECK(rv); 424 DCHECK(rv);
421 } 425 }
422 426
423 void SetCookieFunction::RespondOnUIThread() { 427 void SetCookieFunction::RespondOnUIThread() {
424 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 428 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
425 if (!success_) { 429 if (!success_) {
430 std::string name = parsed_args_->details.name.get() ?
431 *parsed_args_->details.name : "";
426 error_ = ExtensionErrorUtils::FormatErrorMessage( 432 error_ = ExtensionErrorUtils::FormatErrorMessage(
427 keys::kCookieSetFailedError, name_); 433 keys::kCookieSetFailedError, name);
428 } 434 }
429 SendResponse(success_); 435 SendResponse(success_);
430 } 436 }
431 437
432 RemoveCookieFunction::RemoveCookieFunction() : success_(false) { 438 RemoveCookieFunction::RemoveCookieFunction() {
433 } 439 }
434 440
435 RemoveCookieFunction::~RemoveCookieFunction() { 441 RemoveCookieFunction::~RemoveCookieFunction() {
436 } 442 }
437 443
438 bool RemoveCookieFunction::RunImpl() { 444 bool RemoveCookieFunction::RunImpl() {
439 // Return false if the arguments are malformed. 445 parsed_args_ = Remove::Params::Create(*args_);
440 DictionaryValue* details; 446 EXTENSION_FUNCTION_VALIDATE(parsed_args_.get());
441 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &details));
442 DCHECK(details);
443 447
444 // Read/validate input parameters. 448 // Read/validate input parameters.
445 if (!ParseUrl(details, &url_, true)) 449 if (!ParseUrl(parsed_args_->details.url, &url_, true))
446 return false; 450 return false;
447 451
448 // Get the cookie name string or return false.
449 EXTENSION_FUNCTION_VALIDATE(details->GetString(keys::kNameKey, &name_));
450
451 net::URLRequestContextGetter* store_context = NULL; 452 net::URLRequestContextGetter* store_context = NULL;
452 if (!ParseStoreContext(details, &store_context, &store_id_)) 453 std::string* store_id = parsed_args_->details.store_id.get() ?
454 parsed_args_->details.store_id.get() : new std::string("");
455 if (!ParseStoreContext(&store_context, store_id))
453 return false; 456 return false;
454 DCHECK(store_context);
455 store_context_ = store_context; 457 store_context_ = store_context;
458 if (!parsed_args_->details.store_id.get())
459 parsed_args_->details.store_id.reset(store_id);
456 460
457 // Pass the work off to the IO thread. 461 // Pass the work off to the IO thread.
458 bool rv = BrowserThread::PostTask( 462 bool rv = BrowserThread::PostTask(
459 BrowserThread::IO, FROM_HERE, 463 BrowserThread::IO, FROM_HERE,
460 base::Bind(&RemoveCookieFunction::RemoveCookieOnIOThread, this)); 464 base::Bind(&RemoveCookieFunction::RemoveCookieOnIOThread, this));
461 DCHECK(rv); 465 DCHECK(rv);
462 466
463 // Will return asynchronously. 467 // Will return asynchronously.
464 return true; 468 return true;
465 } 469 }
466 470
467 void RemoveCookieFunction::RemoveCookieOnIOThread() { 471 void RemoveCookieFunction::RemoveCookieOnIOThread() {
468 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 472 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
469 473
470 // Remove the cookie 474 // Remove the cookie
471 net::CookieStore* cookie_store = 475 net::CookieStore* cookie_store =
472 store_context_->GetURLRequestContext()->cookie_store(); 476 store_context_->GetURLRequestContext()->cookie_store();
473 cookie_store->DeleteCookieAsync( 477 cookie_store->DeleteCookieAsync(
474 url_, name_, 478 url_, parsed_args_->details.name,
475 base::Bind(&RemoveCookieFunction::RemoveCookieCallback, this)); 479 base::Bind(&RemoveCookieFunction::RemoveCookieCallback, this));
476 } 480 }
477 481
478 void RemoveCookieFunction::RemoveCookieCallback() { 482 void RemoveCookieFunction::RemoveCookieCallback() {
479 // Build the callback result 483 // Build the callback result
480 DictionaryValue* resultDictionary = new DictionaryValue(); 484 Remove::Result::Details details;
481 resultDictionary->SetString(keys::kNameKey, name_); 485 details.name = parsed_args_->details.name;
482 resultDictionary->SetString(keys::kUrlKey, url_.spec()); 486 details.url = url_.spec();
483 resultDictionary->SetString(keys::kStoreIdKey, store_id_); 487 details.store_id = *parsed_args_->details.store_id;
484 result_.reset(resultDictionary); 488 result_.reset(Remove::Result::Create(details));
485 489
486 // Return to UI thread 490 // Return to UI thread
487 bool rv = BrowserThread::PostTask( 491 bool rv = BrowserThread::PostTask(
488 BrowserThread::UI, FROM_HERE, 492 BrowserThread::UI, FROM_HERE,
489 base::Bind(&RemoveCookieFunction::RespondOnUIThread, this)); 493 base::Bind(&RemoveCookieFunction::RespondOnUIThread, this));
490 DCHECK(rv); 494 DCHECK(rv);
491 } 495 }
492 496
493 void RemoveCookieFunction::RespondOnUIThread() { 497 void RemoveCookieFunction::RespondOnUIThread() {
494 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 498 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(...skipping 13 matching lines...) Expand all
508 } 512 }
509 DCHECK(original_profile != incognito_profile); 513 DCHECK(original_profile != incognito_profile);
510 514
511 // Iterate through all browser instances, and for each browser, 515 // Iterate through all browser instances, and for each browser,
512 // add its tab IDs to either the regular or incognito tab ID list depending 516 // add its tab IDs to either the regular or incognito tab ID list depending
513 // whether the browser is regular or incognito. 517 // whether the browser is regular or incognito.
514 for (BrowserList::const_iterator iter = BrowserList::begin(); 518 for (BrowserList::const_iterator iter = BrowserList::begin();
515 iter != BrowserList::end(); ++iter) { 519 iter != BrowserList::end(); ++iter) {
516 Browser* browser = *iter; 520 Browser* browser = *iter;
517 if (browser->profile() == original_profile) { 521 if (browser->profile() == original_profile) {
518 cookies_helpers::AppendToTabIdList(browser, 522 cookies_helpers::AppendToTabIdList(browser, original_tab_ids.get());
519 original_tab_ids.get());
520 } else if (incognito_tab_ids.get() && 523 } else if (incognito_tab_ids.get() &&
521 browser->profile() == incognito_profile) { 524 browser->profile() == incognito_profile) {
522 cookies_helpers::AppendToTabIdList(browser, 525 cookies_helpers::AppendToTabIdList(browser, incognito_tab_ids.get());
523 incognito_tab_ids.get());
524 } 526 }
525 } 527 }
526 // Return a list of all cookie stores with at least one open tab. 528 // Return a list of all cookie stores with at least one open tab.
527 ListValue* cookie_store_list = new ListValue(); 529 std::vector<linked_ptr<CookieStore> > cookie_stores;
528 if (original_tab_ids->GetSize() > 0) { 530 if (original_tab_ids->GetSize() > 0) {
529 cookie_store_list->Append( 531 linked_ptr<CookieStore> cookie_store(
530 cookies_helpers::CreateCookieStoreValue( 532 cookies_helpers::CreateCookieStore(
531 original_profile, original_tab_ids.release())); 533 original_profile, original_tab_ids.release()));
534 cookie_stores.push_back(cookie_store);
532 } 535 }
533 if (incognito_tab_ids.get() && incognito_tab_ids->GetSize() > 0 && 536 if (incognito_tab_ids.get() && incognito_tab_ids->GetSize() > 0 &&
534 incognito_profile) { 537 incognito_profile) {
535 cookie_store_list->Append( 538 linked_ptr<CookieStore> cookie_store(
536 cookies_helpers::CreateCookieStoreValue( 539 cookies_helpers::CreateCookieStore(
537 incognito_profile, incognito_tab_ids.release())); 540 incognito_profile, incognito_tab_ids.release()));
541 cookie_stores.push_back(cookie_store);
538 } 542 }
539 result_.reset(cookie_store_list); 543 result_.reset(GetAllCookieStores::Result::Create(cookie_stores));
540 return true; 544 return true;
541 } 545 }
542 546
543 void GetAllCookieStoresFunction::Run() { 547 void GetAllCookieStoresFunction::Run() {
544 SendResponse(RunImpl()); 548 SendResponse(RunImpl());
545 } 549 }
546 550
547 } // namespace extensions 551 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698