• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2015 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 "libcef/browser/iothread_state.h"
6 
7 #include "libcef/browser/net/scheme_handler.h"
8 #include "libcef/browser/thread_util.h"
9 #include "libcef/common/net/scheme_registration.h"
10 
11 #include "base/i18n/case_conversion.h"
12 #include "base/logging.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "content/browser/resource_context_impl.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/global_routing_id.h"
18 
CefIOThreadState()19 CefIOThreadState::CefIOThreadState() {
20   // Using base::Unretained() is safe because both this callback and possible
21   // deletion of |this| will execute on the IO thread, and this callback will
22   // be executed first.
23   CEF_POST_TASK(CEF_IOT, base::BindOnce(&CefIOThreadState::InitOnIOThread,
24                                         base::Unretained(this)));
25 }
26 
~CefIOThreadState()27 CefIOThreadState::~CefIOThreadState() {
28   CEF_REQUIRE_IOT();
29 }
30 
AddHandler(const content::GlobalRenderFrameHostId & global_id,CefRefPtr<CefRequestContextHandler> handler)31 void CefIOThreadState::AddHandler(
32     const content::GlobalRenderFrameHostId& global_id,
33     CefRefPtr<CefRequestContextHandler> handler) {
34   CEF_REQUIRE_IOT();
35   handler_map_.AddHandler(global_id, handler);
36 }
37 
RemoveHandler(const content::GlobalRenderFrameHostId & global_id)38 void CefIOThreadState::RemoveHandler(
39     const content::GlobalRenderFrameHostId& global_id) {
40   CEF_REQUIRE_IOT();
41   handler_map_.RemoveHandler(global_id);
42 }
43 
GetHandler(const content::GlobalRenderFrameHostId & global_id,bool require_frame_match) const44 CefRefPtr<CefRequestContextHandler> CefIOThreadState::GetHandler(
45     const content::GlobalRenderFrameHostId& global_id,
46     bool require_frame_match) const {
47   CEF_REQUIRE_IOT();
48   return handler_map_.GetHandler(global_id, require_frame_match);
49 }
50 
RegisterSchemeHandlerFactory(const std::string & scheme_name,const std::string & domain_name,CefRefPtr<CefSchemeHandlerFactory> factory)51 void CefIOThreadState::RegisterSchemeHandlerFactory(
52     const std::string& scheme_name,
53     const std::string& domain_name,
54     CefRefPtr<CefSchemeHandlerFactory> factory) {
55   CEF_REQUIRE_IOT();
56 
57   const std::string& scheme_lower = base::ToLowerASCII(scheme_name);
58   std::string domain_lower;
59 
60   // Hostname is only supported for standard schemes.
61   if (scheme::IsStandardScheme(scheme_lower)) {
62     // Hostname might contain Unicode characters.
63     domain_lower =
64         base::UTF16ToUTF8(base::i18n::ToLower(base::UTF8ToUTF16(domain_name)));
65   }
66 
67   const auto key = std::make_pair(scheme_lower, domain_lower);
68 
69   if (factory) {
70     // Add or replace the factory.
71     scheme_handler_factory_map_[key] = factory;
72   } else {
73     // Remove the existing factory, if any.
74     auto it = scheme_handler_factory_map_.find(key);
75     if (it != scheme_handler_factory_map_.end())
76       scheme_handler_factory_map_.erase(it);
77   }
78 }
79 
ClearSchemeHandlerFactories()80 void CefIOThreadState::ClearSchemeHandlerFactories() {
81   CEF_REQUIRE_IOT();
82 
83   scheme_handler_factory_map_.clear();
84 
85   // Restore the default internal handlers.
86   scheme::RegisterInternalHandlers(this);
87 }
88 
GetSchemeHandlerFactory(const GURL & url)89 CefRefPtr<CefSchemeHandlerFactory> CefIOThreadState::GetSchemeHandlerFactory(
90     const GURL& url) {
91   CEF_REQUIRE_IOT();
92 
93   if (scheme_handler_factory_map_.empty())
94     return nullptr;
95 
96   const std::string& scheme_lower = url.scheme();
97   const std::string& domain_lower =
98       url.IsStandard() ? url.host() : std::string();
99 
100   if (!domain_lower.empty()) {
101     // Sanity check.
102     DCHECK(scheme::IsStandardScheme(scheme_lower)) << scheme_lower;
103 
104     // Try for a match with hostname first.
105     const auto it = scheme_handler_factory_map_.find(
106         std::make_pair(scheme_lower, domain_lower));
107     if (it != scheme_handler_factory_map_.end())
108       return it->second;
109   }
110 
111   // Try for a match with no specified hostname.
112   const auto it = scheme_handler_factory_map_.find(
113       std::make_pair(scheme_lower, std::string()));
114   if (it != scheme_handler_factory_map_.end())
115     return it->second;
116 
117   return nullptr;
118 }
119 
InitOnIOThread()120 void CefIOThreadState::InitOnIOThread() {
121   CEF_REQUIRE_IOT();
122 
123   // Add the default internal handlers.
124   scheme::RegisterInternalHandlers(this);
125 }
126