1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "android_webview/browser/aw_cookie_access_policy.h"
6
7#include "android_webview/browser/aw_contents_io_thread_client.h"
8
9#include "base/logging.h"
10#include "base/memory/scoped_ptr.h"
11#include "content/public/browser/browser_thread.h"
12#include "content/public/browser/resource_request_info.h"
13#include "net/base/net_errors.h"
14
15using base::AutoLock;
16using content::BrowserThread;
17using content::ResourceRequestInfo;
18using net::StaticCookiePolicy;
19
20namespace android_webview {
21
22namespace {
23base::LazyInstance<AwCookieAccessPolicy>::Leaky g_lazy_instance;
24}  // namespace
25
26AwCookieAccessPolicy::~AwCookieAccessPolicy() {
27}
28
29AwCookieAccessPolicy::AwCookieAccessPolicy()
30    : accept_cookies_(true) {
31}
32
33AwCookieAccessPolicy* AwCookieAccessPolicy::GetInstance() {
34  return g_lazy_instance.Pointer();
35}
36
37bool AwCookieAccessPolicy::GetShouldAcceptCookies() {
38  AutoLock lock(lock_);
39  return accept_cookies_;
40}
41
42void AwCookieAccessPolicy::SetShouldAcceptCookies(bool allow) {
43  AutoLock lock(lock_);
44  accept_cookies_ = allow;
45}
46
47bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies(
48    int render_process_id,
49    int render_frame_id) {
50  scoped_ptr<AwContentsIoThreadClient> io_thread_client =
51      AwContentsIoThreadClient::FromID(render_process_id, render_frame_id);
52  if (!io_thread_client) {
53    return false;
54  }
55  return io_thread_client->ShouldAcceptThirdPartyCookies();
56}
57
58bool AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies(
59    const net::URLRequest& request) {
60  const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(&request);
61  if (!info) {
62    return false;
63  }
64  return GetShouldAcceptThirdPartyCookies(info->GetChildID(),
65                                          info->GetRenderFrameID());
66}
67
68bool AwCookieAccessPolicy::OnCanGetCookies(const net::URLRequest& request,
69                                           const net::CookieList& cookie_list) {
70  bool global = GetShouldAcceptCookies();
71  bool thirdParty = GetShouldAcceptThirdPartyCookies(request);
72  return AwStaticCookiePolicy(global, thirdParty)
73      .AllowGet(request.url(), request.first_party_for_cookies());
74}
75
76bool AwCookieAccessPolicy::OnCanSetCookie(const net::URLRequest& request,
77                                          const std::string& cookie_line,
78                                          net::CookieOptions* options) {
79  bool global = GetShouldAcceptCookies();
80  bool thirdParty = GetShouldAcceptThirdPartyCookies(request);
81  return AwStaticCookiePolicy(global, thirdParty)
82      .AllowSet(request.url(), request.first_party_for_cookies());
83}
84
85bool AwCookieAccessPolicy::AllowGetCookie(const GURL& url,
86                                          const GURL& first_party,
87                                          const net::CookieList& cookie_list,
88                                          content::ResourceContext* context,
89                                          int render_process_id,
90                                          int render_frame_id) {
91  bool global = GetShouldAcceptCookies();
92  bool thirdParty =
93      GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id);
94  return AwStaticCookiePolicy(global, thirdParty).AllowGet(url, first_party);
95}
96
97bool AwCookieAccessPolicy::AllowSetCookie(const GURL& url,
98                                          const GURL& first_party,
99                                          const std::string& cookie_line,
100                                          content::ResourceContext* context,
101                                          int render_process_id,
102                                          int render_frame_id,
103                                          net::CookieOptions* options) {
104  bool global = GetShouldAcceptCookies();
105  bool thirdParty =
106      GetShouldAcceptThirdPartyCookies(render_process_id, render_frame_id);
107  return AwStaticCookiePolicy(global, thirdParty).AllowSet(url, first_party);
108}
109
110AwStaticCookiePolicy::AwStaticCookiePolicy(bool accept_cookies,
111                                           bool accept_third_party_cookies)
112    : accept_cookies_(accept_cookies),
113      accept_third_party_cookies_(accept_third_party_cookies) {
114}
115
116StaticCookiePolicy::Type AwStaticCookiePolicy::GetPolicy(const GURL& url)
117    const {
118  // File URLs are a special case. We want file URLs to be able to set cookies
119  // but (for the purpose of cookies) Chrome considers different file URLs to
120  // come from different origins so we use the 'allow all' cookie policy for
121  // file URLs.
122  bool isFile = url.SchemeIsFile();
123  if (!accept_cookies()) {
124    return StaticCookiePolicy::BLOCK_ALL_COOKIES;
125  }
126  if (accept_third_party_cookies() || isFile) {
127    return StaticCookiePolicy::ALLOW_ALL_COOKIES;
128  }
129  return StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES;
130}
131
132bool AwStaticCookiePolicy::AllowSet(const GURL& url,
133                                    const GURL& first_party) const {
134
135  return StaticCookiePolicy(GetPolicy(url)).CanSetCookie(url, first_party) ==
136         net::OK;
137}
138
139bool AwStaticCookiePolicy::AllowGet(const GURL& url,
140                                    const GURL& first_party) const {
141  return StaticCookiePolicy(GetPolicy(url)).CanGetCookies(url, first_party) ==
142         net::OK;
143}
144
145}  // namespace android_webview
146