chrome_cookie_policy.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/chrome_cookie_policy.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_list.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chrome_thread.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/host_content_settings_map.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/static_cookie_policy.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// If we queue up more than this number of completions, then switch from ASK to
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// BLOCK.  More than this number of requests at once seems like it could be a
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// sign of trouble anyways.
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const size_t kMaxCompletionsPerHost = 10000;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ----------------------------------------------------------------------------
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochChromeCookiePolicy::ChromeCookiePolicy(HostContentSettingsMap* map)
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : host_content_settings_map_(map) {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochChromeCookiePolicy::~ChromeCookiePolicy() {
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(host_completions_map_.empty());
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ChromeCookiePolicy::CanGetCookies(const GURL& url,
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      const GURL& first_party,
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      net::CompletionCallback* callback) {
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (host_content_settings_map_->BlockThirdPartyCookies()) {
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::StaticCookiePolicy policy(
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = policy.CanGetCookies(url, first_party, NULL);
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (rv != net::OK)
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return rv;
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int policy = CheckPolicy(url);
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (policy != net::ERR_IO_PENDING)
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return policy;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(callback);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If we are currently prompting the user for a 'set-cookie' matching this
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // host, then we need to defer reading cookies.
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  HostCompletionsMap::iterator it = host_completions_map_.find(url.host());
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (it == host_completions_map_.end()) {
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    policy = net::OK;
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (it->second.size() >= kMaxCompletionsPerHost) {
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    policy = net::ERR_ACCESS_DENIED;
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    it->second.push_back(Completion::ForGetCookies(callback));
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    policy = net::ERR_IO_PENDING;
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return policy;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ChromeCookiePolicy::CanSetCookie(const GURL& url,
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     const GURL& first_party,
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     const std::string& cookie_line,
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     net::CompletionCallback* callback) {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (host_content_settings_map_->BlockThirdPartyCookies()) {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    net::StaticCookiePolicy policy(
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        net::StaticCookiePolicy::BLOCK_THIRD_PARTY_COOKIES);
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int rv = policy.CanSetCookie(url, first_party, cookie_line, NULL);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (rv != net::OK)
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return rv;
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int policy = CheckPolicy(url);
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (policy != net::ERR_IO_PENDING)
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return policy;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(callback);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Completions& completions = host_completions_map_[url.host()];
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (completions.size() >= kMaxCompletionsPerHost) {
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LOG(ERROR) << "Would exceed kMaxCompletionsPerHost";
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    policy = net::ERR_ACCESS_DENIED;
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    completions.push_back(Completion::ForSetCookie(callback));
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    policy = net::ERR_IO_PENDING;
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return policy;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint ChromeCookiePolicy::CheckPolicy(const GURL& url) const {
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ContentSetting setting = host_content_settings_map_->GetContentSetting(
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      url, CONTENT_SETTINGS_TYPE_COOKIES, "");
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (setting == CONTENT_SETTING_BLOCK)
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::ERR_ACCESS_DENIED;
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (setting == CONTENT_SETTING_ALLOW)
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::OK;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (setting == CONTENT_SETTING_SESSION_ONLY)
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return net::OK_FOR_SESSION_ONLY;
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return net::ERR_IO_PENDING;  // Need to prompt.
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107