@@ -241,6 +241,10 @@ void Window::Call(const std::string& method,
241
241
CookieGet (arguments);
242
242
} else if (method == " CookieGetAll" ) {
243
243
CookieGet (arguments, true );
244
+ } else if (method == " CookieRemove" ) {
245
+ CookieRemove (arguments);
246
+ } else if (method == " CookieSet" ) {
247
+ CookieSet (arguments);
244
248
} else {
245
249
NOTREACHED () << " Invalid call to Window method:" << method
246
250
<< " arguments:" << arguments;
@@ -270,28 +274,83 @@ void Window::CallSync(const std::string& method,
270
274
}
271
275
}
272
276
277
+ void Window::CookieRemove (const base::ListValue& arguments) {
278
+ CookieAPIContext* api_context = new CookieAPIContext (dispatcher_host (), arguments);
279
+ bool rv = BrowserThread::PostTask (
280
+ BrowserThread::IO, FROM_HERE,
281
+ base::Bind (&Window::RemoveCookieOnIOThread,
282
+ base::Unretained (this ),
283
+ make_scoped_refptr (api_context)));
284
+ DCHECK (rv);
285
+ }
273
286
274
- void Window::CookieGet (const base::ListValue& arguments, bool get_all) {
287
+ void Window::CookieSet (const base::ListValue& arguments) {
288
+ CookieAPIContext* api_context = new CookieAPIContext (dispatcher_host (), arguments);
289
+ bool rv = BrowserThread::PostTask (
290
+ BrowserThread::IO, FROM_HERE,
291
+ base::Bind (&Window::SetCookieOnIOThread,
292
+ base::Unretained (this ),
293
+ make_scoped_refptr (api_context)));
294
+ DCHECK (rv);
295
+ }
296
+
297
+ void Window::RemoveCookieOnIOThread (CookieAPIContext* api_context) {
298
+ DCHECK (BrowserThread::CurrentlyOn (BrowserThread::IO));
299
+
300
+ // Remove the cookie
301
+ net::CookieStore* cookie_store =
302
+ api_context->store_context_ ->GetURLRequestContext ()->cookie_store ();
303
+ std::string name;
304
+ api_context->details_ ->GetString (" name" , &name);
305
+ cookie_store->DeleteCookieAsync (
306
+ api_context->url_ , name,
307
+ base::Bind (&Window::RemoveCookieCallback, base::Unretained (this ),
308
+ make_scoped_refptr (api_context)));
309
+ }
310
+
311
+ void Window::RemoveCookieCallback (CookieAPIContext* api_context) {
312
+ std::string name;
313
+ api_context->details_ ->GetString (" name" , &name);
314
+
315
+ base::DictionaryValue* result = new base::DictionaryValue ();
316
+ result->SetString (" name" , name);
317
+ result->SetString (" url" , api_context->url_ .spec ());
318
+ api_context->result_ ->Append (result);
319
+
320
+ // Return to UI thread
321
+ bool rv = BrowserThread::PostTask (
322
+ BrowserThread::UI, FROM_HERE,
323
+ base::Bind (&Window::RespondOnUIThread, base::Unretained (this ),
324
+ make_scoped_refptr (api_context)));
325
+ DCHECK (rv);
326
+ }
327
+
328
+ CookieAPIContext::CookieAPIContext (DispatcherHost* dispatcher_host,
329
+ const base::ListValue& arguments) {
275
330
content::RenderProcessHost* render_process_host =
276
- dispatcher_host () ->render_view_host ()->GetProcess ();
331
+ dispatcher_host->render_view_host ()->GetProcess ();
277
332
net::URLRequestContextGetter* context_getter =
278
333
render_process_host->GetBrowserContext ()->
279
334
GetRequestContextForRenderProcess (render_process_host->GetID ());
280
335
281
336
const base::DictionaryValue* details = NULL ;
282
337
std::string url;
283
338
284
- CookieAPIContext* api_context = new CookieAPIContext;
285
- api_context->store_context_ = context_getter;
286
- arguments.GetInteger (0 , &api_context->req_id_ );
339
+ store_context_ = context_getter;
340
+ arguments.GetInteger (0 , &req_id_);
287
341
arguments.GetDictionary (1 , &details);
288
342
if (details) {
289
- api_context-> details_ .reset (details->DeepCopyWithoutEmptyChildren ());
343
+ details_.reset (details->DeepCopyWithoutEmptyChildren ());
290
344
details->GetString (" url" , &url);
291
345
}
292
346
293
- api_context->url_ = GURL (url);
294
- api_context->result_ .reset (new base::ListValue);
347
+ url_ = GURL (url);
348
+ result_.reset (new base::ListValue);
349
+ }
350
+
351
+ void Window::CookieGet (const base::ListValue& arguments, bool get_all) {
352
+
353
+ CookieAPIContext* api_context = new CookieAPIContext (dispatcher_host (), arguments);
295
354
296
355
if (get_all) {
297
356
bool rv = BrowserThread::PostTask (
@@ -380,4 +439,77 @@ void Window::RespondOnUIThread(CookieAPIContext* api_context) {
380
439
dispatcher_host ()->SendEvent (this , base::StringPrintf (" __nw_gotcookie%d" , api_context->req_id_ ), ret);
381
440
}
382
441
442
+ void Window::SetCookieOnIOThread (CookieAPIContext* api_context) {
443
+ DCHECK (BrowserThread::CurrentlyOn (BrowserThread::IO));
444
+ net::CookieMonster* cookie_monster =
445
+ api_context->store_context_ ->GetURLRequestContext ()->cookie_store ()->
446
+ GetCookieMonster ();
447
+
448
+ base::Time expiration_time;
449
+ double expiration_date;
450
+
451
+ if (api_context->details_ ->GetDouble (" expirationDate" , &expiration_date)) {
452
+ // Time::FromDoubleT converts double time 0 to empty Time object. So we need
453
+ // to do special handling here.
454
+ expiration_time = (expiration_date == 0 ) ?
455
+ base::Time::UnixEpoch () :
456
+ base::Time::FromDoubleT (expiration_date);
457
+ }
458
+
459
+ const base::DictionaryValue* details = api_context->details_ .get ();
460
+ std::string name, value, domain, path;
461
+ details->GetString (" name" , &name);
462
+ details->GetString (" value" , &value);
463
+ details->GetString (" domain" , &domain);
464
+ details->GetString (" path" , &path);
465
+
466
+ bool secure = false , http_only = false ;
467
+ details->GetBoolean (" httpOnly" , &http_only);
468
+ details->GetBoolean (" secure" , &secure);
469
+
470
+ cookie_monster->SetCookieWithDetailsAsync (
471
+ api_context->url_ ,
472
+ name, value, domain, path,
473
+ expiration_time,
474
+ secure, http_only,
475
+ net::COOKIE_PRIORITY_DEFAULT,
476
+ base::Bind (&Window::PullCookie, base::Unretained (this ),
477
+ make_scoped_refptr (api_context)));
478
+ }
479
+
480
+ void Window::PullCookie (CookieAPIContext* api_context, bool set_cookie_result) {
481
+ // Pull the newly set cookie.
482
+ net::CookieMonster* cookie_monster =
483
+ api_context->store_context_ ->GetURLRequestContext ()->cookie_store ()->
484
+ GetCookieMonster ();
485
+ api_context->success_ = set_cookie_result;
486
+ GetCookieListFromStore (
487
+ cookie_monster, api_context->url_ ,
488
+ base::Bind (&Window::PullCookieCallback,
489
+ base::Unretained (this ),
490
+ make_scoped_refptr (api_context)));
491
+ }
492
+
493
+ void Window::PullCookieCallback (CookieAPIContext* api_context,
494
+ const net::CookieList& cookie_list) {
495
+ net::CookieList::const_iterator it;
496
+ for (it = cookie_list.begin (); it != cookie_list.end (); ++it) {
497
+ // Return the first matching cookie. Relies on the fact that the
498
+ // CookieMonster returns them in canonical order (longest path, then
499
+ // earliest creation time).
500
+ std::string name;
501
+ api_context->details_ ->GetString (" name" , &name);
502
+ if (it->Name () == name) {
503
+ api_context->result_ ->Append (PopulateCookieObject (*it));
504
+ break ;
505
+ }
506
+ }
507
+
508
+ bool rv = BrowserThread::PostTask (
509
+ BrowserThread::UI, FROM_HERE,
510
+ base::Bind (&Window::RespondOnUIThread, base::Unretained (this ),
511
+ make_scoped_refptr (api_context)));
512
+ DCHECK (rv);
513
+ }
514
+
383
515
} // namespace api
0 commit comments