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

Side by Side Diff: content/browser/devtools/protocol/network_handler.cc

Issue 2623063003: DevTools: Fix getCookies to report for all resources (Closed)
Patch Set: feedback Created 3 years, 11 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "content/browser/devtools/protocol/network_handler.h" 5 #include "content/browser/devtools/protocol/network_handler.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/containers/hash_tables.h" 9 #include "base/containers/hash_tables.h"
10 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
(...skipping 16 matching lines...) Expand all
27 27
28 namespace content { 28 namespace content {
29 namespace protocol { 29 namespace protocol {
30 namespace { 30 namespace {
31 31
32 using GetCookiesCallback = protocol::Network::Backend::GetCookiesCallback; 32 using GetCookiesCallback = protocol::Network::Backend::GetCookiesCallback;
33 using GetAllCookiesCallback = protocol::Network::Backend::GetAllCookiesCallback; 33 using GetAllCookiesCallback = protocol::Network::Backend::GetAllCookiesCallback;
34 using SetCookieCallback = protocol::Network::Backend::SetCookieCallback; 34 using SetCookieCallback = protocol::Network::Backend::SetCookieCallback;
35 using DeleteCookieCallback = protocol::Network::Backend::DeleteCookieCallback; 35 using DeleteCookieCallback = protocol::Network::Backend::DeleteCookieCallback;
36 36
37 class CookieReceiver {
pfeldman 2017/01/18 01:41:11 nit: inherit from base::NonThreadSafe and DCHECK(C
38 public:
39 CookieReceiver(const net::CookieStore::GetCookieListCallback& callback)
40 : callback_(callback), request_count_(0) {}
41
42 void increment(int count) {
43 request_count_ += count;
pfeldman 2017/01/18 01:41:11 nit: use base::BarrierClosure instead - your callb
44 }
45
46 net::CookieStore::GetCookieListCallback bound() {
47 return base::Bind(&CookieReceiver::GotCookies, base::Unretained(this));
48 }
49
50 protected:
51 void GotCookies(const net::CookieList& cookie_list) {
52 DCHECK_CURRENTLY_ON(BrowserThread::IO);
53 for (const net::CanonicalCookie& cookie : cookie_list) {
54 std::string key = base::StringPrintf(
55 "%s::%s::%s::%d", cookie.Name().c_str(), cookie.Domain().c_str(),
56 cookie.Path().c_str(), cookie.IsSecure());
57 cookies_[key] = cookie;
58 }
59 --request_count_;
60 if (!request_count_) {
61 SendResponse();
62 delete this;
63 }
64 }
65
66 void SendResponse() {
67 net::CookieList master_cookie_list;
68 for (const auto& pair : cookies_) {
69 master_cookie_list.push_back(pair.second);
70 }
71
72 BrowserThread::PostTask(
73 BrowserThread::UI,
74 FROM_HERE,
75 base::Bind(callback_, master_cookie_list));
76 }
77
78 const net::CookieStore::GetCookieListCallback& callback_;
79 int request_count_;
80 base::hash_map<std::string, net::CanonicalCookie> cookies_;
81 };
82
37 net::URLRequestContext* GetRequestContextOnIO( 83 net::URLRequestContext* GetRequestContextOnIO(
38 ResourceContext* resource_context, 84 ResourceContext* resource_context,
39 net::URLRequestContextGetter* context_getter, 85 net::URLRequestContextGetter* context_getter,
40 const GURL& url) { 86 const GURL& url) {
41 DCHECK_CURRENTLY_ON(BrowserThread::IO); 87 DCHECK_CURRENTLY_ON(BrowserThread::IO);
42 net::URLRequestContext* context = 88 net::URLRequestContext* context =
43 GetContentClient()->browser()->OverrideRequestContextForURL( 89 GetContentClient()->browser()->OverrideRequestContextForURL(
44 url, resource_context); 90 url, resource_context);
45 if (!context) 91 if (!context)
46 context = context_getter->GetURLRequestContext(); 92 context = context_getter->GetURLRequestContext();
47 return context; 93 return context;
48 } 94 }
49 95
50 void GotCookiesOnIO( 96 void GetCookiesForURLsOnIO(
51 const net::CookieStore::GetCookieListCallback& callback,
52 const net::CookieList& cookie_list) {
53 DCHECK_CURRENTLY_ON(BrowserThread::IO);
54 BrowserThread::PostTask(
55 BrowserThread::UI,
56 FROM_HERE,
57 base::Bind(callback, cookie_list));
58 }
59
60 void GetCookiesForURLOnIO(
61 ResourceContext* resource_context, 97 ResourceContext* resource_context,
62 net::URLRequestContextGetter* context_getter, 98 net::URLRequestContextGetter* context_getter,
63 const GURL& url, 99 const std::vector<GURL>& urls,
64 const net::CookieStore::GetCookieListCallback& callback) { 100 const net::CookieStore::GetCookieListCallback& finished_callback) {
65 DCHECK_CURRENTLY_ON(BrowserThread::IO); 101 DCHECK_CURRENTLY_ON(BrowserThread::IO);
66 net::URLRequestContext* request_context = 102 CookieReceiver* receiver = new CookieReceiver(finished_callback);
67 GetRequestContextOnIO(resource_context, context_getter, url); 103 receiver->increment(urls.size());
68 request_context->cookie_store()->GetAllCookiesForURLAsync( 104
69 url, base::Bind(&GotCookiesOnIO, callback)); 105 net::CookieStore::GetCookieListCallback callback = receiver->bound();
106
107 for (const GURL& url : urls) {
108 net::URLRequestContext* request_context =
109 GetRequestContextOnIO(resource_context, context_getter, url);
110 request_context->cookie_store()->GetAllCookiesForURLAsync(url, callback);
111 }
70 } 112 }
71 113
72 void GetAllCookiesOnIO( 114 void GetAllCookiesOnIO(
73 ResourceContext* resource_context, 115 ResourceContext* resource_context,
74 net::URLRequestContextGetter* context_getter, 116 net::URLRequestContextGetter* context_getter,
75 const net::CookieStore::GetCookieListCallback& callback) { 117 const net::CookieStore::GetCookieListCallback& finished_callback) {
76 DCHECK_CURRENTLY_ON(BrowserThread::IO); 118 DCHECK_CURRENTLY_ON(BrowserThread::IO);
119 CookieReceiver* receiver = new CookieReceiver(finished_callback);
120 receiver->increment(1);
121
122 net::CookieStore::GetCookieListCallback callback = receiver->bound();
77 net::URLRequestContext* request_context = 123 net::URLRequestContext* request_context =
78 context_getter->GetURLRequestContext(); 124 context_getter->GetURLRequestContext();
79 request_context->cookie_store()->GetAllCookiesAsync( 125 request_context->cookie_store()->GetAllCookiesAsync(callback);
80 base::Bind(&GotCookiesOnIO, callback));
81 } 126 }
82 127
83 void DeletedCookieOnIO(std::unique_ptr<DeleteCookieCallback> callback) { 128 void DeletedCookieOnIO(std::unique_ptr<DeleteCookieCallback> callback) {
84 DCHECK_CURRENTLY_ON(BrowserThread::IO); 129 DCHECK_CURRENTLY_ON(BrowserThread::IO);
85 BrowserThread::PostTask( 130 BrowserThread::PostTask(
86 BrowserThread::UI, 131 BrowserThread::UI,
87 FROM_HERE, 132 FROM_HERE,
88 base::Bind(&DeleteCookieCallback::sendSuccess, 133 base::Bind(&DeleteCookieCallback::sendSuccess,
89 base::Passed(std::move(callback)))); 134 base::Passed(std::move(callback))));
90 } 135 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 same_site, 189 same_site,
145 are_experimental_cookie_features_enabled, 190 are_experimental_cookie_features_enabled,
146 net::COOKIE_PRIORITY_DEFAULT, 191 net::COOKIE_PRIORITY_DEFAULT,
147 base::Bind(&CookieSetOnIO, base::Passed(std::move(callback)))); 192 base::Bind(&CookieSetOnIO, base::Passed(std::move(callback))));
148 } 193 }
149 194
150 template <typename Callback> 195 template <typename Callback>
151 class GetCookiesCommandBase { 196 class GetCookiesCommandBase {
152 public: 197 public:
153 GetCookiesCommandBase(std::unique_ptr<Callback> callback) 198 GetCookiesCommandBase(std::unique_ptr<Callback> callback)
154 : callback_(std::move(callback)), request_count_(0) {} 199 : callback_(std::move(callback)) {}
155 200
156 protected: 201 protected:
157 void GotCookiesForURL(const net::CookieList& cookie_list) { 202 void SendResponse(const net::CookieList& cookie_list) {
158 DCHECK_CURRENTLY_ON(BrowserThread::UI);
159 for (const net::CanonicalCookie& cookie : cookie_list) {
160 std::string key = base::StringPrintf(
161 "%s::%s::%s::%d", cookie.Name().c_str(), cookie.Domain().c_str(),
162 cookie.Path().c_str(), cookie.IsSecure());
163 cookies_[key] = cookie;
164 }
165 --request_count_;
166 if (!request_count_) {
167 SendResponse();
168 delete this;
169 }
170 }
171
172 void SendResponse() {
173 std::unique_ptr<protocol::Array<Network::Cookie>> cookies = 203 std::unique_ptr<protocol::Array<Network::Cookie>> cookies =
174 protocol::Array<Network::Cookie>::create(); 204 protocol::Array<Network::Cookie>::create();
175 for (const auto& pair : cookies_) { 205 for (const auto& cookie : cookie_list) {
176 const net::CanonicalCookie& cookie = pair.second;
177 std::unique_ptr<Network::Cookie> devtools_cookie = 206 std::unique_ptr<Network::Cookie> devtools_cookie =
178 Network::Cookie::Create() 207 Network::Cookie::Create()
179 .SetName(cookie.Name()) 208 .SetName(cookie.Name())
180 .SetValue(cookie.Value()) 209 .SetValue(cookie.Value())
181 .SetDomain(cookie.Domain()) 210 .SetDomain(cookie.Domain())
182 .SetPath(cookie.Path()) 211 .SetPath(cookie.Path())
183 .SetExpires(cookie.ExpiryDate().ToDoubleT() * 1000) 212 .SetExpires(cookie.ExpiryDate().ToDoubleT() * 1000)
184 .SetSize(cookie.Name().length() + cookie.Value().length()) 213 .SetSize(cookie.Name().length() + cookie.Value().length())
185 .SetHttpOnly(cookie.IsHttpOnly()) 214 .SetHttpOnly(cookie.IsHttpOnly())
186 .SetSecure(cookie.IsSecure()) 215 .SetSecure(cookie.IsSecure())
187 .SetSession(!cookie.IsPersistent()) 216 .SetSession(!cookie.IsPersistent())
188 .Build(); 217 .Build();
189 218
190 switch (cookie.SameSite()) { 219 switch (cookie.SameSite()) {
191 case net::CookieSameSite::STRICT_MODE: 220 case net::CookieSameSite::STRICT_MODE:
192 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Strict); 221 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Strict);
193 break; 222 break;
194 case net::CookieSameSite::LAX_MODE: 223 case net::CookieSameSite::LAX_MODE:
195 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Lax); 224 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Lax);
196 break; 225 break;
197 case net::CookieSameSite::NO_RESTRICTION: 226 case net::CookieSameSite::NO_RESTRICTION:
198 break; 227 break;
199 } 228 }
200 cookies->addItem(std::move(devtools_cookie)); 229 cookies->addItem(std::move(devtools_cookie));
201 } 230 }
202 callback_->sendSuccess(std::move(cookies)); 231 callback_->sendSuccess(std::move(cookies));
203 } 232 }
204 233
205 std::unique_ptr<Callback> callback_; 234 std::unique_ptr<Callback> callback_;
206 int request_count_;
207 base::hash_map<std::string, net::CanonicalCookie> cookies_;
208 }; 235 };
209 236
210 class GetCookiesCommand : public GetCookiesCommandBase<GetCookiesCallback> { 237 class GetCookiesCommand : public GetCookiesCommandBase<GetCookiesCallback> {
211 public: 238 public:
212 GetCookiesCommand(RenderFrameHostImpl* frame_host, 239 GetCookiesCommand(RenderFrameHostImpl* frame_host,
240 Maybe<protocol::Array<std::string>>& maybe_urls,
213 std::unique_ptr<GetCookiesCallback> callback) 241 std::unique_ptr<GetCookiesCallback> callback)
214 : GetCookiesCommandBase(std::move(callback)) { 242 : GetCookiesCommandBase(std::move(callback)) {
243 std::vector<GURL> urls_to_fetch;
215 net::CookieStore::GetCookieListCallback got_cookies_callback = base::Bind( 244 net::CookieStore::GetCookieListCallback got_cookies_callback = base::Bind(
216 &GetCookiesCommand::GotCookiesForURL, base::Unretained(this)); 245 &GetCookiesCommand::SendResponse, base::Unretained(this));
pfeldman 2017/01/18 01:41:11 This is dangerous - when your callback triggers, t
217 246
218 std::queue<FrameTreeNode*> queue; 247 if (maybe_urls.isJust()) {
219 queue.push(frame_host->frame_tree_node()); 248 std::unique_ptr<protocol::Array<std::string>> urls =
220 while (!queue.empty()) { 249 maybe_urls.takeJust();
221 FrameTreeNode* node = queue.front();
222 queue.pop();
223 250
224 // Only traverse nodes with the same local root. 251 for (size_t i = 0; i < urls->length(); i++)
225 if (node->current_frame_host()->IsCrossProcessSubframe()) 252 urls_to_fetch.push_back(GURL(urls->get(i)));
226 continue; 253 } else {
227 ++request_count_; 254 std::queue<FrameTreeNode*> queue;
228 BrowserThread::PostTask( 255 queue.push(frame_host->frame_tree_node());
229 BrowserThread::IO, FROM_HERE, 256 while (!queue.empty()) {
230 base::Bind(&GetCookiesForURLOnIO, 257 FrameTreeNode* node = queue.front();
231 base::Unretained(frame_host->GetSiteInstance() 258 queue.pop();
232 ->GetBrowserContext()
233 ->GetResourceContext()),
234 base::Unretained(frame_host->GetProcess()
235 ->GetStoragePartition()
236 ->GetURLRequestContext()),
237 node->current_url(), got_cookies_callback));
238 259
239 for (size_t i = 0; i < node->child_count(); ++i) 260 // Only traverse nodes with the same local root.
240 queue.push(node->child_at(i)); 261 if (node->current_frame_host()->IsCrossProcessSubframe())
262 continue;
263
264 urls_to_fetch.push_back(node->current_url());
265 for (size_t i = 0; i < node->child_count(); ++i)
266 queue.push(node->child_at(i));
267 }
241 } 268 }
269
270 if (urls_to_fetch.size() == 0) {
271 got_cookies_callback();
272 return;
273 }
274
275 BrowserThread::PostTask(
276 BrowserThread::IO, FROM_HERE,
277 base::Bind(&GetCookiesForURLsOnIO,
278 base::Unretained(frame_host->GetSiteInstance()
279 ->GetBrowserContext()
280 ->GetResourceContext()),
281 base::Unretained(frame_host->GetProcess()
282 ->GetStoragePartition()
283 ->GetURLRequestContext()),
284 urls_to_fetch, got_cookies_callback));
242 } 285 }
243 }; 286 };
244 287
245 class GetAllCookiesCommand 288 class GetAllCookiesCommand
246 : public GetCookiesCommandBase<GetAllCookiesCallback> { 289 : public GetCookiesCommandBase<GetAllCookiesCallback> {
247 public: 290 public:
248 GetAllCookiesCommand(RenderFrameHostImpl* frame_host, 291 GetAllCookiesCommand(RenderFrameHostImpl* frame_host,
249 std::unique_ptr<GetAllCookiesCallback> callback) 292 std::unique_ptr<GetAllCookiesCallback> callback)
250 : GetCookiesCommandBase(std::move(callback)) { 293 : GetCookiesCommandBase(std::move(callback)) {
251 net::CookieStore::GetCookieListCallback got_cookies_callback = base::Bind( 294 net::CookieStore::GetCookieListCallback got_cookies_callback = base::Bind(
252 &GetAllCookiesCommand::GotCookiesForURL, base::Unretained(this)); 295 &GetAllCookiesCommand::SendResponse, base::Unretained(this));
253 296
254 request_count_ = 1;
255 BrowserThread::PostTask( 297 BrowserThread::PostTask(
256 BrowserThread::IO, FROM_HERE, 298 BrowserThread::IO, FROM_HERE,
257 base::Bind(&GetAllCookiesOnIO, 299 base::Bind(&GetAllCookiesOnIO,
258 base::Unretained(frame_host->GetSiteInstance() 300 base::Unretained(frame_host->GetSiteInstance()
259 ->GetBrowserContext() 301 ->GetBrowserContext()
260 ->GetResourceContext()), 302 ->GetResourceContext()),
261 base::Unretained(frame_host->GetProcess() 303 base::Unretained(frame_host->GetProcess()
262 ->GetStoragePartition() 304 ->GetStoragePartition()
263 ->GetURLRequestContext()), 305 ->GetURLRequestContext()),
264 got_cookies_callback)); 306 got_cookies_callback));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 return Response::OK(); 350 return Response::OK();
309 } 351 }
310 352
311 Response NetworkHandler::ClearBrowserCookies() { 353 Response NetworkHandler::ClearBrowserCookies() {
312 if (host_) 354 if (host_)
313 GetContentClient()->browser()->ClearCookies(host_); 355 GetContentClient()->browser()->ClearCookies(host_);
314 return Response::OK(); 356 return Response::OK();
315 } 357 }
316 358
317 void NetworkHandler::GetCookies( 359 void NetworkHandler::GetCookies(
360 Maybe<protocol::Array<String>> urls,
318 std::unique_ptr<GetCookiesCallback> callback) { 361 std::unique_ptr<GetCookiesCallback> callback) {
319 if (!host_) 362 if (!host_)
320 callback->sendFailure(Response::InternalError()); 363 callback->sendFailure(Response::InternalError());
321 else 364 else
322 new GetCookiesCommand(host_, std::move(callback)); 365 new GetCookiesCommand(host_, urls, std::move(callback));
323 } 366 }
324 367
325 void NetworkHandler::GetAllCookies( 368 void NetworkHandler::GetAllCookies(
326 std::unique_ptr<GetAllCookiesCallback> callback) { 369 std::unique_ptr<GetAllCookiesCallback> callback) {
327 if (!host_) 370 if (!host_)
328 callback->sendFailure(Response::InternalError()); 371 callback->sendFailure(Response::InternalError());
329 else 372 else
330 new GetAllCookiesCommand(host_, std::move(callback)); 373 new GetAllCookiesCommand(host_, std::move(callback));
331 } 374 }
332 375
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 *result = false; 448 *result = false;
406 return Response::OK(); 449 return Response::OK();
407 } 450 }
408 451
409 std::string NetworkHandler::UserAgentOverride() const { 452 std::string NetworkHandler::UserAgentOverride() const {
410 return enabled_ ? user_agent_ : std::string(); 453 return enabled_ ? user_agent_ : std::string();
411 } 454 }
412 455
413 } // namespace protocol 456 } // namespace protocol
414 } // namespace content 457 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/devtools/protocol/network_handler.h ('k') | third_party/WebKit/Source/core/inspector/browser_protocol.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698