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

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

Issue 2623063003: DevTools: Fix getCookies to report for all resources (Closed)
Patch Set: more 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/barrier_closure.h"
9 #include "base/containers/hash_tables.h" 10 #include "base/containers/hash_tables.h"
10 #include "base/strings/stringprintf.h" 11 #include "base/strings/stringprintf.h"
11 #include "base/time/time.h" 12 #include "base/time/time.h"
12 #include "content/browser/devtools/devtools_session.h" 13 #include "content/browser/devtools/devtools_session.h"
13 #include "content/browser/frame_host/frame_tree_node.h" 14 #include "content/browser/frame_host/frame_tree_node.h"
14 #include "content/browser/frame_host/render_frame_host_impl.h" 15 #include "content/browser/frame_host/render_frame_host_impl.h"
15 #include "content/public/browser/browser_context.h" 16 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/content_browser_client.h" 18 #include "content/public/browser/content_browser_client.h"
18 #include "content/public/browser/render_process_host.h" 19 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/resource_context.h" 20 #include "content/public/browser/resource_context.h"
20 #include "content/public/browser/site_instance.h" 21 #include "content/public/browser/site_instance.h"
21 #include "content/public/browser/storage_partition.h" 22 #include "content/public/browser/storage_partition.h"
22 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
23 #include "content/public/common/content_client.h" 24 #include "content/public/common/content_client.h"
24 #include "net/cookies/cookie_store.h" 25 #include "net/cookies/cookie_store.h"
25 #include "net/url_request/url_request_context.h" 26 #include "net/url_request/url_request_context.h"
26 #include "net/url_request/url_request_context_getter.h" 27 #include "net/url_request/url_request_context_getter.h"
27 28
28 namespace content { 29 namespace content {
29 namespace protocol { 30 namespace protocol {
30 namespace { 31 namespace {
31 32
33 using ProtocolCookieArray = protocol::Array<Network::Cookie>;
32 using GetCookiesCallback = protocol::Network::Backend::GetCookiesCallback; 34 using GetCookiesCallback = protocol::Network::Backend::GetCookiesCallback;
33 using GetAllCookiesCallback = protocol::Network::Backend::GetAllCookiesCallback; 35 using GetAllCookiesCallback = protocol::Network::Backend::GetAllCookiesCallback;
34 using SetCookieCallback = protocol::Network::Backend::SetCookieCallback; 36 using SetCookieCallback = protocol::Network::Backend::SetCookieCallback;
35 using DeleteCookieCallback = protocol::Network::Backend::DeleteCookieCallback; 37 using DeleteCookieCallback = protocol::Network::Backend::DeleteCookieCallback;
36 38
37 net::URLRequestContext* GetRequestContextOnIO( 39 net::URLRequestContext* GetRequestContextOnIO(
38 ResourceContext* resource_context, 40 ResourceContext* resource_context,
39 net::URLRequestContextGetter* context_getter, 41 net::URLRequestContextGetter* context_getter,
40 const GURL& url) { 42 const GURL& url) {
41 DCHECK_CURRENTLY_ON(BrowserThread::IO); 43 DCHECK_CURRENTLY_ON(BrowserThread::IO);
42 net::URLRequestContext* context = 44 net::URLRequestContext* context =
43 GetContentClient()->browser()->OverrideRequestContextForURL( 45 GetContentClient()->browser()->OverrideRequestContextForURL(
44 url, resource_context); 46 url, resource_context);
45 if (!context) 47 if (!context)
46 context = context_getter->GetURLRequestContext(); 48 context = context_getter->GetURLRequestContext();
47 return context; 49 return context;
48 } 50 }
49 51
50 void GotCookiesOnIO( 52 class CookieRetriever : public base::RefCountedThreadSafe<CookieRetriever> {
51 const net::CookieStore::GetCookieListCallback& callback, 53 public:
52 const net::CookieList& cookie_list) { 54 CookieRetriever(std::unique_ptr<GetCookiesCallback> callback)
53 DCHECK_CURRENTLY_ON(BrowserThread::IO); 55 : callback_(std::move(callback)),
54 BrowserThread::PostTask( 56 all_callback_(nullptr),
55 BrowserThread::UI, 57 callback_count_(0) {}
56 FROM_HERE,
57 base::Bind(callback, cookie_list));
58 }
59 58
60 void GetCookiesForURLOnIO( 59 CookieRetriever(std::unique_ptr<GetAllCookiesCallback> callback)
61 ResourceContext* resource_context, 60 : callback_(nullptr),
62 net::URLRequestContextGetter* context_getter, 61 all_callback_(std::move(callback)),
63 const GURL& url, 62 callback_count_(0) {}
64 const net::CookieStore::GetCookieListCallback& callback) {
65 DCHECK_CURRENTLY_ON(BrowserThread::IO);
66 net::URLRequestContext* request_context =
67 GetRequestContextOnIO(resource_context, context_getter, url);
68 request_context->cookie_store()->GetAllCookiesForURLAsync(
69 url, base::Bind(&GotCookiesOnIO, callback));
70 }
71 63
72 void GetAllCookiesOnIO( 64 void RetrieveCookiesOnIO(
73 ResourceContext* resource_context, 65 ResourceContext* resource_context,
74 net::URLRequestContextGetter* context_getter, 66 net::URLRequestContextGetter* context_getter,
75 const net::CookieStore::GetCookieListCallback& callback) { 67 const std::vector<GURL>& urls) {
76 DCHECK_CURRENTLY_ON(BrowserThread::IO); 68 DCHECK_CURRENTLY_ON(BrowserThread::IO);
77 net::URLRequestContext* request_context = 69 callback_count_ = urls.size();
78 context_getter->GetURLRequestContext(); 70
79 request_context->cookie_store()->GetAllCookiesAsync( 71 if (callback_count_ == 0) {
pfeldman 2017/01/19 18:58:35 nit: some would say !callback_count_.
phulce 2017/01/19 21:18:57 Acknowledged.
80 base::Bind(&GotCookiesOnIO, callback)); 72 GotAllCookies();
81 } 73 return;
74 }
75
76 for (const GURL& url : urls) {
77 net::URLRequestContext* request_context =
78 GetRequestContextOnIO(resource_context, context_getter, url);
79 request_context->cookie_store()->GetAllCookiesForURLAsync(url,
80 base::Bind(&CookieRetriever::GotCookies, this));
81 }
82 }
83
84 void RetrieveAllCookiesOnIO(
85 ResourceContext* resource_context,
86 net::URLRequestContextGetter* context_getter) {
87 DCHECK_CURRENTLY_ON(BrowserThread::IO);
88 callback_count_ = 1;
89
90 net::URLRequestContext* request_context =
91 context_getter->GetURLRequestContext();
92 request_context->cookie_store()->GetAllCookiesAsync(
93 base::Bind(&CookieRetriever::GotCookies, this));
94 }
95 protected:
96 virtual ~CookieRetriever() {}
97
98 void GotCookies(const net::CookieList& cookie_list) {
99 DCHECK_CURRENTLY_ON(BrowserThread::IO);
100 for (const net::CanonicalCookie& cookie : cookie_list) {
101 std::string key = base::StringPrintf(
102 "%s::%s::%s::%d", cookie.Name().c_str(), cookie.Domain().c_str(),
103 cookie.Path().c_str(), cookie.IsSecure());
104 cookies_[key] = cookie;
105 }
106
107 --callback_count_;
108 if (callback_count_ == 0) {
pfeldman 2017/01/19 18:58:35 nit: some would drop {} and inline --callback_coun
phulce 2017/01/19 21:18:58 Done.
109 GotAllCookies();
110 }
111 }
112
113 void GotAllCookies() {
114 net::CookieList master_cookie_list;
115 for (const auto& pair : cookies_) {
pfeldman 2017/01/19 18:58:35 nit: ditto
phulce 2017/01/19 21:18:57 Done.
116 master_cookie_list.push_back(pair.second);
117 }
118
119 BrowserThread::PostTask(
120 BrowserThread::UI,
121 FROM_HERE,
122 base::Bind(&CookieRetriever::SendCookiesResponseOnUI,
123 this,
124 master_cookie_list));
125 }
126
127 void SendCookiesResponseOnUI(const net::CookieList& cookie_list) {
128 DCHECK_CURRENTLY_ON(BrowserThread::UI);
129 std::unique_ptr<ProtocolCookieArray> cookies =
130 ProtocolCookieArray::create();
131
132 for (const net::CanonicalCookie& cookie : cookie_list) {
133 std::unique_ptr<Network::Cookie> devtools_cookie =
134 Network::Cookie::Create()
135 .SetName(cookie.Name())
136 .SetValue(cookie.Value())
137 .SetDomain(cookie.Domain())
138 .SetPath(cookie.Path())
139 .SetExpires(cookie.ExpiryDate().ToDoubleT() * 1000)
140 .SetSize(cookie.Name().length() + cookie.Value().length())
141 .SetHttpOnly(cookie.IsHttpOnly())
142 .SetSecure(cookie.IsSecure())
143 .SetSession(!cookie.IsPersistent())
144 .Build();
145
146 switch (cookie.SameSite()) {
147 case net::CookieSameSite::STRICT_MODE:
148 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Strict);
149 break;
150 case net::CookieSameSite::LAX_MODE:
151 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Lax);
152 break;
153 case net::CookieSameSite::NO_RESTRICTION:
154 break;
155 }
156
157 cookies->addItem(std::move(devtools_cookie));
158 }
159
160 if (callback_ != nullptr) {
pfeldman 2017/01/19 18:58:35 if (callback_)
phulce 2017/01/19 21:18:57 Done.
161 callback_->sendSuccess(std::move(cookies));
162 } else if (all_callback_ != nullptr) {
pfeldman 2017/01/19 18:58:35 } else { DCHECK(all_callback_); ... }
phulce 2017/01/19 21:18:57 Done.
163 all_callback_->sendSuccess(std::move(cookies));
164 }
165 }
166
167 std::unique_ptr<GetCookiesCallback> callback_;
168 std::unique_ptr<GetAllCookiesCallback> all_callback_;
169 int callback_count_;
pfeldman 2017/01/19 18:58:35 in the new c++ you can say int callback_count_ = 0
phulce 2017/01/19 21:18:57 Done.
170 base::hash_map<std::string, net::CanonicalCookie> cookies_;
pfeldman 2017/01/19 18:58:35 use std::unordered_map (hash_map is just an alias)
phulce 2017/01/19 21:18:57 Done.
171
172 private:
173 friend class base::RefCountedThreadSafe<CookieRetriever>;
174 };
82 175
83 void DeletedCookieOnIO(std::unique_ptr<DeleteCookieCallback> callback) { 176 void DeletedCookieOnIO(std::unique_ptr<DeleteCookieCallback> callback) {
84 DCHECK_CURRENTLY_ON(BrowserThread::IO); 177 DCHECK_CURRENTLY_ON(BrowserThread::IO);
85 BrowserThread::PostTask( 178 BrowserThread::PostTask(
86 BrowserThread::UI, 179 BrowserThread::UI,
87 FROM_HERE, 180 FROM_HERE,
88 base::Bind(&DeleteCookieCallback::sendSuccess, 181 base::Bind(&DeleteCookieCallback::sendSuccess,
89 base::Passed(std::move(callback)))); 182 base::Passed(std::move(callback))));
90 } 183 }
91 184
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 expires, 233 expires,
141 base::Time(), 234 base::Time(),
142 secure, 235 secure,
143 http_only, 236 http_only,
144 same_site, 237 same_site,
145 are_experimental_cookie_features_enabled, 238 are_experimental_cookie_features_enabled,
146 net::COOKIE_PRIORITY_DEFAULT, 239 net::COOKIE_PRIORITY_DEFAULT,
147 base::Bind(&CookieSetOnIO, base::Passed(std::move(callback)))); 240 base::Bind(&CookieSetOnIO, base::Passed(std::move(callback))));
148 } 241 }
149 242
150 template <typename Callback>
151 class GetCookiesCommandBase {
152 public:
153 GetCookiesCommandBase(std::unique_ptr<Callback> callback)
154 : callback_(std::move(callback)), request_count_(0) {}
155
156 protected:
157 void GotCookiesForURL(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 =
174 protocol::Array<Network::Cookie>::create();
175 for (const auto& pair : cookies_) {
176 const net::CanonicalCookie& cookie = pair.second;
177 std::unique_ptr<Network::Cookie> devtools_cookie =
178 Network::Cookie::Create()
179 .SetName(cookie.Name())
180 .SetValue(cookie.Value())
181 .SetDomain(cookie.Domain())
182 .SetPath(cookie.Path())
183 .SetExpires(cookie.ExpiryDate().ToDoubleT() * 1000)
184 .SetSize(cookie.Name().length() + cookie.Value().length())
185 .SetHttpOnly(cookie.IsHttpOnly())
186 .SetSecure(cookie.IsSecure())
187 .SetSession(!cookie.IsPersistent())
188 .Build();
189
190 switch (cookie.SameSite()) {
191 case net::CookieSameSite::STRICT_MODE:
192 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Strict);
193 break;
194 case net::CookieSameSite::LAX_MODE:
195 devtools_cookie->SetSameSite(Network::CookieSameSiteEnum::Lax);
196 break;
197 case net::CookieSameSite::NO_RESTRICTION:
198 break;
199 }
200 cookies->addItem(std::move(devtools_cookie));
201 }
202 callback_->sendSuccess(std::move(cookies));
203 }
204
205 std::unique_ptr<Callback> callback_;
206 int request_count_;
207 base::hash_map<std::string, net::CanonicalCookie> cookies_;
208 };
209
210 class GetCookiesCommand : public GetCookiesCommandBase<GetCookiesCallback> {
211 public:
212 GetCookiesCommand(RenderFrameHostImpl* frame_host,
213 std::unique_ptr<GetCookiesCallback> callback)
214 : GetCookiesCommandBase(std::move(callback)) {
215 net::CookieStore::GetCookieListCallback got_cookies_callback = base::Bind(
216 &GetCookiesCommand::GotCookiesForURL, base::Unretained(this));
217
218 std::queue<FrameTreeNode*> queue;
219 queue.push(frame_host->frame_tree_node());
220 while (!queue.empty()) {
221 FrameTreeNode* node = queue.front();
222 queue.pop();
223
224 // Only traverse nodes with the same local root.
225 if (node->current_frame_host()->IsCrossProcessSubframe())
226 continue;
227 ++request_count_;
228 BrowserThread::PostTask(
229 BrowserThread::IO, FROM_HERE,
230 base::Bind(&GetCookiesForURLOnIO,
231 base::Unretained(frame_host->GetSiteInstance()
232 ->GetBrowserContext()
233 ->GetResourceContext()),
234 base::Unretained(frame_host->GetProcess()
235 ->GetStoragePartition()
236 ->GetURLRequestContext()),
237 node->current_url(), got_cookies_callback));
238
239 for (size_t i = 0; i < node->child_count(); ++i)
240 queue.push(node->child_at(i));
241 }
242 }
243 };
244
245 class GetAllCookiesCommand
246 : public GetCookiesCommandBase<GetAllCookiesCallback> {
247 public:
248 GetAllCookiesCommand(RenderFrameHostImpl* frame_host,
249 std::unique_ptr<GetAllCookiesCallback> callback)
250 : GetCookiesCommandBase(std::move(callback)) {
251 net::CookieStore::GetCookieListCallback got_cookies_callback = base::Bind(
252 &GetAllCookiesCommand::GotCookiesForURL, base::Unretained(this));
253
254 request_count_ = 1;
255 BrowserThread::PostTask(
256 BrowserThread::IO, FROM_HERE,
257 base::Bind(&GetAllCookiesOnIO,
258 base::Unretained(frame_host->GetSiteInstance()
259 ->GetBrowserContext()
260 ->GetResourceContext()),
261 base::Unretained(frame_host->GetProcess()
262 ->GetStoragePartition()
263 ->GetURLRequestContext()),
264 got_cookies_callback));
265 }
266 };
267
268 } // namespace 243 } // namespace
269 244
270 NetworkHandler::NetworkHandler() 245 NetworkHandler::NetworkHandler()
271 : DevToolsDomainHandler(Network::Metainfo::domainName), 246 : DevToolsDomainHandler(Network::Metainfo::domainName),
272 host_(nullptr), 247 host_(nullptr),
273 enabled_(false) { 248 enabled_(false) {
274 } 249 }
275 250
276 NetworkHandler::~NetworkHandler() { 251 NetworkHandler::~NetworkHandler() {
277 } 252 }
(...skipping 29 matching lines...) Expand all
307 GetContentClient()->browser()->ClearCache(host_); 282 GetContentClient()->browser()->ClearCache(host_);
308 return Response::OK(); 283 return Response::OK();
309 } 284 }
310 285
311 Response NetworkHandler::ClearBrowserCookies() { 286 Response NetworkHandler::ClearBrowserCookies() {
312 if (host_) 287 if (host_)
313 GetContentClient()->browser()->ClearCookies(host_); 288 GetContentClient()->browser()->ClearCookies(host_);
314 return Response::OK(); 289 return Response::OK();
315 } 290 }
316 291
292 static std::vector<GURL> ComputeCookieURLs(
pfeldman 2017/01/19 18:58:35 nit: since you have anonymous namespace declared f
phulce 2017/01/19 21:18:57 Done.
293 RenderFrameHostImpl* frame_host,
294 Maybe<protocol::Array<String>>& protocol_urls) {
295 std::vector<GURL> urls;
296
297 if (protocol_urls.isJust()) {
298 std::unique_ptr<protocol::Array<std::string>> actual_urls =
299 protocol_urls.takeJust();
300
301 for (size_t i = 0; i < actual_urls->length(); i++)
302 urls.push_back(GURL(actual_urls->get(i)));
303 } else {
304 std::queue<FrameTreeNode*> queue;
305 queue.push(frame_host->frame_tree_node());
306 while (!queue.empty()) {
307 FrameTreeNode* node = queue.front();
308 queue.pop();
309
310 // Only traverse nodes with the same local root.
311 if (node->current_frame_host()->IsCrossProcessSubframe())
pfeldman 2017/01/19 18:58:35 nit: you don't need this check, we can report cros
phulce 2017/01/19 21:18:57 Done.
312 continue;
313
314 urls.push_back(node->current_url());
315 for (size_t i = 0; i < node->child_count(); ++i)
316 queue.push(node->child_at(i));
317 }
318 }
319
320 return urls;
321 }
322
317 void NetworkHandler::GetCookies( 323 void NetworkHandler::GetCookies(
324 Maybe<protocol::Array<String>> protocol_urls,
318 std::unique_ptr<GetCookiesCallback> callback) { 325 std::unique_ptr<GetCookiesCallback> callback) {
319 if (!host_) 326 if (!host_) {
320 callback->sendFailure(Response::InternalError()); 327 callback->sendFailure(Response::InternalError());
321 else 328 return;
322 new GetCookiesCommand(host_, std::move(callback)); 329 }
330
331 std::vector<GURL> urls = ComputeCookieURLs(host_, protocol_urls);
332 scoped_refptr<CookieRetriever> retriever =
333 new CookieRetriever(std::move(callback));
334
335 BrowserThread::PostTask(
336 BrowserThread::IO, FROM_HERE,
337 base::Bind(&CookieRetriever::RetrieveCookiesOnIO,
338 retriever,
339 base::Unretained(host_->GetSiteInstance()
340 ->GetBrowserContext()
341 ->GetResourceContext()),
342 base::Unretained(host_->GetProcess()
343 ->GetStoragePartition()
344 ->GetURLRequestContext()),
345 urls));
323 } 346 }
324 347
325 void NetworkHandler::GetAllCookies( 348 void NetworkHandler::GetAllCookies(
326 std::unique_ptr<GetAllCookiesCallback> callback) { 349 std::unique_ptr<GetAllCookiesCallback> callback) {
327 if (!host_) 350 if (!host_) {
328 callback->sendFailure(Response::InternalError()); 351 callback->sendFailure(Response::InternalError());
329 else 352 return;
330 new GetAllCookiesCommand(host_, std::move(callback)); 353 }
354
355 scoped_refptr<CookieRetriever> retriever =
356 new CookieRetriever(std::move(callback));
357
358 BrowserThread::PostTask(
359 BrowserThread::IO, FROM_HERE,
360 base::Bind(&CookieRetriever::RetrieveAllCookiesOnIO,
361 retriever,
362 base::Unretained(host_->GetSiteInstance()
363 ->GetBrowserContext()
364 ->GetResourceContext()),
365 base::Unretained(host_->GetProcess()
366 ->GetStoragePartition()
367 ->GetURLRequestContext())));
331 } 368 }
332 369
333 void NetworkHandler::SetCookie( 370 void NetworkHandler::SetCookie(
334 const std::string& url, 371 const std::string& url,
335 const std::string& name, 372 const std::string& name,
336 const std::string& value, 373 const std::string& value,
337 Maybe<std::string> domain, 374 Maybe<std::string> domain,
338 Maybe<std::string> path, 375 Maybe<std::string> path,
339 Maybe<bool> secure, 376 Maybe<bool> secure,
340 Maybe<bool> http_only, 377 Maybe<bool> http_only,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 *result = false; 442 *result = false;
406 return Response::OK(); 443 return Response::OK();
407 } 444 }
408 445
409 std::string NetworkHandler::UserAgentOverride() const { 446 std::string NetworkHandler::UserAgentOverride() const {
410 return enabled_ ? user_agent_ : std::string(); 447 return enabled_ ? user_agent_ : std::string();
411 } 448 }
412 449
413 } // namespace protocol 450 } // namespace protocol
414 } // namespace content 451 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698