Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |