Skip to content

Commit 3edde1f

Browse files
committed
CookieAPI: remove, set and refactoring
1 parent 3890361 commit 3edde1f

File tree

3 files changed

+171
-10
lines changed

3 files changed

+171
-10
lines changed

src/api/window/window.cc

Lines changed: 140 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,10 @@ void Window::Call(const std::string& method,
241241
CookieGet(arguments);
242242
} else if (method == "CookieGetAll") {
243243
CookieGet(arguments, true);
244+
} else if (method == "CookieRemove") {
245+
CookieRemove(arguments);
246+
} else if (method == "CookieSet") {
247+
CookieSet(arguments);
244248
} else {
245249
NOTREACHED() << "Invalid call to Window method:" << method
246250
<< " arguments:" << arguments;
@@ -270,28 +274,83 @@ void Window::CallSync(const std::string& method,
270274
}
271275
}
272276

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+
}
273286

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) {
275330
content::RenderProcessHost* render_process_host =
276-
dispatcher_host()->render_view_host()->GetProcess();
331+
dispatcher_host->render_view_host()->GetProcess();
277332
net::URLRequestContextGetter* context_getter =
278333
render_process_host->GetBrowserContext()->
279334
GetRequestContextForRenderProcess(render_process_host->GetID());
280335

281336
const base::DictionaryValue* details = NULL;
282337
std::string url;
283338

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_);
287341
arguments.GetDictionary(1, &details);
288342
if (details) {
289-
api_context->details_.reset(details->DeepCopyWithoutEmptyChildren());
343+
details_.reset(details->DeepCopyWithoutEmptyChildren());
290344
details->GetString("url", &url);
291345
}
292346

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);
295354

296355
if (get_all) {
297356
bool rv = BrowserThread::PostTask(
@@ -380,4 +439,77 @@ void Window::RespondOnUIThread(CookieAPIContext* api_context) {
380439
dispatcher_host()->SendEvent(this, base::StringPrintf("__nw_gotcookie%d", api_context->req_id_), ret);
381440
}
382441

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+
383515
} // namespace api

src/api/window/window.h

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,15 @@ namespace api {
3838

3939
class CookieAPIContext : public base::RefCountedThreadSafe<CookieAPIContext> {
4040
public:
41+
CookieAPIContext(DispatcherHost* dispatcher_host,
42+
const base::ListValue& arguments);
43+
4144
net::URLRequestContextGetter* store_context_;
4245
scoped_ptr<base::DictionaryValue> details_;
4346
scoped_ptr<base::ListValue> result_;
4447
GURL url_;
4548
int req_id_;
49+
bool success_;
4650
};
4751

4852

@@ -65,8 +69,15 @@ class Window : public Base {
6569
void GetCookieCallback(CookieAPIContext*, const net::CookieList& cookie_list);
6670
void GetAllCookieCallback(CookieAPIContext*, const net::CookieList& cookie_list);
6771
void RespondOnUIThread(CookieAPIContext*);
68-
69-
private:
72+
void RemoveCookieCallback(CookieAPIContext* api_context);
73+
void RemoveCookieOnIOThread(CookieAPIContext*);
74+
void CookieRemove(const base::ListValue& arguments);
75+
void CookieSet(const base::ListValue& arguments);
76+
void PullCookieCallback(CookieAPIContext* api_context,
77+
const net::CookieList& cookie_list);
78+
void PullCookie(CookieAPIContext* api_context, bool set_cookie_result);
79+
void SetCookieOnIOThread(CookieAPIContext* api_context);
80+
private:
7081

7182
content::Shell* shell_;
7283

src/api/window_bindings.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,24 @@ function Window(routing_id, nobind) {
4343
});
4444
}
4545
CallObjectMethod(that, 'CookieGetAll', [ this.req_id, details ]);
46+
},
47+
remove : function(details, cb) {
48+
this.req_id++;
49+
if (typeof cb == 'function') {
50+
that.once('__nw_gotcookie' + this.req_id, function(details) {
51+
cb(details);
52+
});
53+
}
54+
CallObjectMethod(that, 'CookieRemove', [ this.req_id, details ]);
55+
},
56+
set : function(details, cb) {
57+
this.req_id++;
58+
if (typeof cb == 'function') {
59+
that.once('__nw_gotcookie' + this.req_id, function(cookie) {
60+
cb(cookie);
61+
});
62+
}
63+
CallObjectMethod(that, 'CookieSet', [ this.req_id, details ]);
4664
}
4765
}
4866
}

0 commit comments

Comments
 (0)