Skip to content

Commit 448e74c

Browse files
committed
implement Window.cookie.getAll
1 parent 2ee8b6d commit 448e74c

File tree

3 files changed

+136
-30
lines changed

3 files changed

+136
-30
lines changed

src/api/window/window.cc

Lines changed: 121 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,82 @@ void GetCookieListFromStore(
5353
}
5454
}
5555

56+
bool MatchesDomain(base::DictionaryValue* details, const std::string& domain) {
57+
std::string val;
58+
if (!details->GetString("domain", &val))
59+
return true;
60+
61+
// Add a leading '.' character to the filter domain if it doesn't exist.
62+
if (net::cookie_util::DomainIsHostOnly(val))
63+
val.insert(0, ".");
64+
65+
std::string sub_domain(domain);
66+
// Strip any leading '.' character from the input cookie domain.
67+
if (!net::cookie_util::DomainIsHostOnly(sub_domain))
68+
sub_domain = sub_domain.substr(1);
69+
70+
// Now check whether the domain argument is a subdomain of the filter domain.
71+
for (sub_domain.insert(0, ".");
72+
sub_domain.length() >= val.length();) {
73+
if (sub_domain == val)
74+
return true;
75+
const size_t next_dot = sub_domain.find('.', 1); // Skip over leading dot.
76+
sub_domain.erase(0, next_dot);
77+
}
78+
return false;
79+
}
80+
81+
bool MatchesCookie(base::DictionaryValue* details,
82+
const net::CanonicalCookie& cookie) {
83+
std::string val;
84+
85+
bool flag;
86+
if (details->GetString("name", &val))
87+
if (val != cookie.Name())
88+
return false;
89+
90+
if (!MatchesDomain(details, cookie.Domain()))
91+
return false;
92+
93+
if (details->GetString("path", &val))
94+
if (val != cookie.Path())
95+
return false;
96+
97+
if (details->GetBoolean("secure", &flag))
98+
if (flag != cookie.IsSecure())
99+
return false;
100+
101+
if (details->GetBoolean("session", &flag))
102+
if (flag != cookie.IsPersistent())
103+
return false;
104+
105+
return true;
106+
}
107+
108+
base::DictionaryValue*
109+
PopulateCookieObject(const net::CanonicalCookie& canonical_cookie) {
110+
111+
base::DictionaryValue* result = new base::DictionaryValue();
112+
// A cookie is a raw byte sequence. By explicitly parsing it as UTF-8, we
113+
// apply error correction, so the string can be safely passed to the renderer.
114+
result->SetString("name", UTF16ToUTF8(UTF8ToUTF16(canonical_cookie.Name())));
115+
result->SetString("value", UTF16ToUTF8(UTF8ToUTF16(canonical_cookie.Value())));
116+
result->SetString("domain", canonical_cookie.Domain());
117+
result->SetBoolean("host_only", net::cookie_util::DomainIsHostOnly(
118+
canonical_cookie.Domain()));
119+
// A non-UTF8 path is invalid, so we just replace it with an empty string.
120+
result->SetString("path", IsStringUTF8(canonical_cookie.Path()) ? canonical_cookie.Path()
121+
: std::string());
122+
result->SetBoolean("secure", canonical_cookie.IsSecure());
123+
result->SetBoolean("http_only", canonical_cookie.IsHttpOnly());
124+
result->SetBoolean("session", !canonical_cookie.IsPersistent());
125+
if (canonical_cookie.IsPersistent()) {
126+
result->SetDouble("expiration_date",
127+
canonical_cookie.ExpiryDate().ToDoubleT());
128+
}
129+
return result;
130+
}
131+
56132
} // namespace
57133

58134
namespace api {
@@ -66,6 +142,8 @@ Window::Window(int id,
66142
DVLOG(1) << "Window::Window(" << id << ")";
67143
// Set ID for Shell
68144
shell_->set_id(id);
145+
146+
result_.reset(new base::ListValue);
69147
}
70148

71149
Window::~Window() {
@@ -161,6 +239,8 @@ void Window::Call(const std::string& method,
161239
shell_->window()->CapturePage(image_format_str);
162240
} else if (method == "CookieGet") {
163241
CookieGet(arguments);
242+
} else if (method == "CookieGetAll") {
243+
CookieGet(arguments, true);
164244
} else {
165245
NOTREACHED() << "Invalid call to Window method:" << method
166246
<< " arguments:" << arguments;
@@ -191,7 +271,7 @@ void Window::CallSync(const std::string& method,
191271
}
192272

193273

194-
void Window::CookieGet(const base::ListValue& arguments) {
274+
void Window::CookieGet(const base::ListValue& arguments, bool get_all) {
195275
content::RenderProcessHost* render_process_host =
196276
dispatcher_host()->render_view_host()->GetProcess();
197277
net::URLRequestContextGetter* context_getter =
@@ -202,16 +282,33 @@ void Window::CookieGet(const base::ListValue& arguments) {
202282
std::string url;
203283

204284
store_context_ = context_getter;
285+
arguments.GetDictionary(0, &details);
205286
if (details) {
206287
details_.reset(details->DeepCopyWithoutEmptyChildren());
207288
details->GetString("url", &url);
208289
}
209290
url_ = GURL(url);
210291

211-
bool rv = BrowserThread::PostTask(
212-
BrowserThread::IO, FROM_HERE,
213-
base::Bind(&Window::GetCookieOnIOThread, base::Unretained(this)));
214-
DCHECK(rv);
292+
if (get_all) {
293+
bool rv = BrowserThread::PostTask(
294+
BrowserThread::IO, FROM_HERE,
295+
base::Bind(&Window::GetAllCookieOnIOThread, base::Unretained(this)));
296+
DCHECK(rv);
297+
}else{
298+
bool rv = BrowserThread::PostTask(
299+
BrowserThread::IO, FROM_HERE,
300+
base::Bind(&Window::GetCookieOnIOThread, base::Unretained(this)));
301+
DCHECK(rv);
302+
}
303+
}
304+
305+
void Window::GetAllCookieOnIOThread() {
306+
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
307+
net::CookieStore* cookie_store =
308+
store_context_->GetURLRequestContext()->cookie_store();
309+
GetCookieListFromStore(
310+
cookie_store, url_,
311+
base::Bind(&Window::GetAllCookieCallback, base::Unretained(this)));
215312
}
216313

217314
void Window::GetCookieOnIOThread() {
@@ -223,13 +320,26 @@ void Window::GetCookieOnIOThread() {
223320
base::Bind(&Window::GetCookieCallback, base::Unretained(this)));
224321
}
225322

323+
void Window::GetAllCookieCallback(const net::CookieList& cookie_list) {
324+
net::CookieList::const_iterator it;
325+
result_->Clear();
326+
for (it = cookie_list.begin(); it != cookie_list.end(); ++it) {
327+
if (MatchesCookie(details_.get(), *it)) {
328+
result_->Append(PopulateCookieObject(*it));
329+
}
330+
}
331+
332+
bool rv = BrowserThread::PostTask(
333+
BrowserThread::UI, FROM_HERE,
334+
base::Bind(&Window::RespondOnUIThread, base::Unretained(this)));
335+
DCHECK(rv);
336+
}
337+
226338
void Window::GetCookieCallback(const net::CookieList& cookie_list) {
227339
net::CookieList::const_iterator it;
228340
std::string name;
229341
details_->GetString("name", &name);
230342

231-
if (!result_)
232-
result_.reset(new base::DictionaryValue);
233343
result_->Clear();
234344

235345
for (it = cookie_list.begin(); it != cookie_list.end(); ++it) {
@@ -238,24 +348,7 @@ void Window::GetCookieCallback(const net::CookieList& cookie_list) {
238348
// earliest creation time).
239349

240350
if (it->Name() == name) {
241-
const net::CanonicalCookie& canonical_cookie = *it;
242-
// A cookie is a raw byte sequence. By explicitly parsing it as UTF-8, we
243-
// apply error correction, so the string can be safely passed to the renderer.
244-
result_->SetString("name", UTF16ToUTF8(UTF8ToUTF16(canonical_cookie.Name())));
245-
result_->SetString("value", UTF16ToUTF8(UTF8ToUTF16(canonical_cookie.Value())));
246-
result_->SetString("domain", canonical_cookie.Domain());
247-
result_->SetBoolean("host_only", net::cookie_util::DomainIsHostOnly(
248-
canonical_cookie.Domain()));
249-
// A non-UTF8 path is invalid, so we just replace it with an empty string.
250-
result_->SetString("path", IsStringUTF8(canonical_cookie.Path()) ? canonical_cookie.Path()
251-
: std::string());
252-
result_->SetBoolean("secure", canonical_cookie.IsSecure());
253-
result_->SetBoolean("http_only", canonical_cookie.IsHttpOnly());
254-
result_->SetBoolean("session", !canonical_cookie.IsPersistent());
255-
if (canonical_cookie.IsPersistent()) {
256-
result_->SetDouble("expiration_date",
257-
canonical_cookie.ExpiryDate().ToDoubleT());
258-
}
351+
result_->Append(PopulateCookieObject(*it));
259352
break;
260353
}
261354
}
@@ -268,9 +361,9 @@ void Window::GetCookieCallback(const net::CookieList& cookie_list) {
268361

269362
void Window::RespondOnUIThread() {
270363
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
271-
base::ListValue args;
272-
args.Append(result_.release());
273-
dispatcher_host()->SendEvent(this, "__nw_gotcookie", args);
364+
base::ListValue ret;
365+
ret.Append(result_.release());
366+
dispatcher_host()->SendEvent(this, "__nw_gotcookie", ret);
274367
}
275368

276369
} // namespace api

src/api/window/window.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,19 @@ class Window : public Base {
4949
const base::ListValue& arguments,
5050
base::ListValue* result) OVERRIDE;
5151

52-
void CookieGet(const base::ListValue& arguments);
52+
void CookieGet(const base::ListValue& arguments, bool get_all = false);
5353
void GetCookieOnIOThread();
54+
void GetAllCookieOnIOThread();
5455
void GetCookieCallback(const net::CookieList& cookie_list);
56+
void GetAllCookieCallback(const net::CookieList& cookie_list);
5557
void RespondOnUIThread();
5658

5759
private:
5860

5961
content::Shell* shell_;
6062
net::URLRequestContextGetter* store_context_;
6163
scoped_ptr<base::DictionaryValue> details_;
62-
scoped_ptr<base::DictionaryValue> result_;
64+
scoped_ptr<base::ListValue> result_;
6365
GURL url_;
6466

6567
DISALLOW_COPY_AND_ASSIGN(Window);

src/api/window_bindings.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ function Window(routing_id, nobind) {
2424
this.cookies = {
2525
get : function(details, cb) {
2626
CallObjectMethod(that, 'CookieGet', [ details ]);
27+
if (typeof cb == 'function') {
28+
that.once('__nw_gotcookie', function(cookie) {
29+
if (cookie.length > 0)
30+
cb(cookie[0]);
31+
else
32+
cb(null);
33+
});
34+
}
35+
},
36+
getAll : function(details, cb) {
37+
CallObjectMethod(that, 'CookieGetAll', [ details ]);
2738
if (typeof cb == 'function') {
2839
that.once('__nw_gotcookie', function(cookie) {
2940
cb(cookie);

0 commit comments

Comments
 (0)