| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | // Copyright (c) 2019 GitHub, Inc.
 | 
					
						
							|  |  |  | // Use of this source code is governed by the MIT license that can be
 | 
					
						
							|  |  |  | // found in the LICENSE file.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-04 12:19:40 -08:00
										 |  |  | #include "shell/browser/api/electron_api_protocol.h"
 | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-10 19:00:37 -06:00
										 |  |  | #include <string_view>
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | #include <vector>
 | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 22:34:34 -07:00
										 |  |  | #include "base/command_line.h"
 | 
					
						
							| 
									
										
										
										
											2025-02-21 17:33:43 -06:00
										 |  |  | #include "base/containers/contains.h"
 | 
					
						
							| 
									
										
										
										
											2021-03-24 00:16:53 +09:00
										 |  |  | #include "content/common/url_schemes.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | #include "content/public/browser/child_process_security_policy.h"
 | 
					
						
							| 
									
										
										
										
											2024-07-29 12:42:57 -05:00
										 |  |  | #include "gin/handle.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  | #include "gin/object_template_builder.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | #include "shell/browser/browser.h"
 | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  | #include "shell/browser/protocol_registry.h"
 | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  | #include "shell/common/gin_converters/callback_converter.h"
 | 
					
						
							|  |  |  | #include "shell/common/gin_converters/net_converter.h"
 | 
					
						
							|  |  |  | #include "shell/common/gin_helper/dictionary.h"
 | 
					
						
							|  |  |  | #include "shell/common/gin_helper/object_template_builder.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  | #include "shell/common/gin_helper/promise.h"
 | 
					
						
							| 
									
										
										
										
											2021-07-01 17:51:37 -07:00
										 |  |  | #include "shell/common/node_includes.h"
 | 
					
						
							| 
									
										
										
										
											2024-09-16 15:53:04 -05:00
										 |  |  | #include "shell/common/node_util.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | #include "shell/common/options_switches.h"
 | 
					
						
							| 
									
										
										
										
											2019-10-28 18:12:35 -04:00
										 |  |  | #include "url/url_util.h"
 | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // List of registered custom standard schemes.
 | 
					
						
							|  |  |  | std::vector<std::string> g_standard_schemes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 11:49:36 -05:00
										 |  |  | // List of registered custom streaming schemes.
 | 
					
						
							|  |  |  | std::vector<std::string> g_streaming_schemes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  | // Schemes that support V8 code cache.
 | 
					
						
							|  |  |  | std::vector<std::string> g_code_cache_schemes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | struct SchemeOptions { | 
					
						
							|  |  |  |   bool standard = false; | 
					
						
							|  |  |  |   bool secure = false; | 
					
						
							|  |  |  |   bool bypassCSP = false; | 
					
						
							|  |  |  |   bool allowServiceWorkers = false; | 
					
						
							|  |  |  |   bool supportFetchAPI = false; | 
					
						
							|  |  |  |   bool corsEnabled = false; | 
					
						
							| 
									
										
										
										
											2020-06-08 11:49:36 -05:00
										 |  |  |   bool stream = false; | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  |   bool codeCache = false; | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct CustomScheme { | 
					
						
							|  |  |  |   std::string scheme; | 
					
						
							|  |  |  |   SchemeOptions options; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  | namespace gin { | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | template <> | 
					
						
							|  |  |  | struct Converter<CustomScheme> { | 
					
						
							|  |  |  |   static bool FromV8(v8::Isolate* isolate, | 
					
						
							|  |  |  |                      v8::Local<v8::Value> val, | 
					
						
							|  |  |  |                      CustomScheme* out) { | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  |     gin::Dictionary dict(isolate); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |     if (!ConvertFromV8(isolate, val, &dict)) | 
					
						
							|  |  |  |       return false; | 
					
						
							|  |  |  |     if (!dict.Get("scheme", &(out->scheme))) | 
					
						
							|  |  |  |       return false; | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  |     gin::Dictionary opt(isolate); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |     // options are optional. Default values specified in SchemeOptions are used
 | 
					
						
							|  |  |  |     if (dict.Get("privileges", &opt)) { | 
					
						
							|  |  |  |       opt.Get("standard", &(out->options.standard)); | 
					
						
							|  |  |  |       opt.Get("secure", &(out->options.secure)); | 
					
						
							|  |  |  |       opt.Get("bypassCSP", &(out->options.bypassCSP)); | 
					
						
							|  |  |  |       opt.Get("allowServiceWorkers", &(out->options.allowServiceWorkers)); | 
					
						
							|  |  |  |       opt.Get("supportFetchAPI", &(out->options.supportFetchAPI)); | 
					
						
							|  |  |  |       opt.Get("corsEnabled", &(out->options.corsEnabled)); | 
					
						
							| 
									
										
										
										
											2020-06-08 11:49:36 -05:00
										 |  |  |       opt.Get("stream", &(out->options.stream)); | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  |       opt.Get("codeCache", &(out->options.codeCache)); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  | }  // namespace gin
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-29 12:55:47 -07:00
										 |  |  | namespace electron::api { | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  | gin::WrapperInfo Protocol::kWrapperInfo = {gin::kEmbedderNativeGin}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  | const std::vector<std::string>& GetStandardSchemes() { | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |   return g_standard_schemes; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  | const std::vector<std::string>& GetCodeCacheSchemes() { | 
					
						
							|  |  |  |   return g_code_cache_schemes; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-31 18:45:23 -07:00
										 |  |  | void AddServiceWorkerScheme(const std::string& scheme) { | 
					
						
							|  |  |  |   // There is no API to add service worker scheme, but there is an API to
 | 
					
						
							|  |  |  |   // return const reference to the schemes vector.
 | 
					
						
							|  |  |  |   // If in future the API is changed to return a copy instead of reference,
 | 
					
						
							|  |  |  |   // the compilation will fail, and we should add a patch at that time.
 | 
					
						
							|  |  |  |   auto& mutable_schemes = | 
					
						
							|  |  |  |       const_cast<std::vector<std::string>&>(content::GetServiceWorkerSchemes()); | 
					
						
							|  |  |  |   mutable_schemes.push_back(scheme); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  | void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower, | 
					
						
							|  |  |  |                                  v8::Local<v8::Value> val) { | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |   std::vector<CustomScheme> custom_schemes; | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  |   if (!gin::ConvertFromV8(thrower.isolate(), val, &custom_schemes)) { | 
					
						
							|  |  |  |     thrower.ThrowError("Argument must be an array of custom schemes."); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  |   for (const auto& custom_scheme : custom_schemes) { | 
					
						
							|  |  |  |     if (custom_scheme.options.codeCache && !custom_scheme.options.standard) { | 
					
						
							|  |  |  |       thrower.ThrowError( | 
					
						
							|  |  |  |           "Code cache can only be enabled when the custom scheme is registered " | 
					
						
							|  |  |  |           "as standard scheme."); | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |   std::vector<std::string> secure_schemes, cspbypassing_schemes, fetch_schemes, | 
					
						
							|  |  |  |       service_worker_schemes, cors_schemes; | 
					
						
							|  |  |  |   for (const auto& custom_scheme : custom_schemes) { | 
					
						
							|  |  |  |     // Register scheme to privileged list (https, wss, data, chrome-extension)
 | 
					
						
							|  |  |  |     if (custom_scheme.options.standard) { | 
					
						
							|  |  |  |       auto* policy = content::ChildProcessSecurityPolicy::GetInstance(); | 
					
						
							|  |  |  |       url::AddStandardScheme(custom_scheme.scheme.c_str(), | 
					
						
							|  |  |  |                              url::SCHEME_WITH_HOST); | 
					
						
							|  |  |  |       g_standard_schemes.push_back(custom_scheme.scheme); | 
					
						
							|  |  |  |       policy->RegisterWebSafeScheme(custom_scheme.scheme); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (custom_scheme.options.secure) { | 
					
						
							|  |  |  |       secure_schemes.push_back(custom_scheme.scheme); | 
					
						
							|  |  |  |       url::AddSecureScheme(custom_scheme.scheme.c_str()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (custom_scheme.options.bypassCSP) { | 
					
						
							|  |  |  |       cspbypassing_schemes.push_back(custom_scheme.scheme); | 
					
						
							|  |  |  |       url::AddCSPBypassingScheme(custom_scheme.scheme.c_str()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (custom_scheme.options.corsEnabled) { | 
					
						
							|  |  |  |       cors_schemes.push_back(custom_scheme.scheme); | 
					
						
							|  |  |  |       url::AddCorsEnabledScheme(custom_scheme.scheme.c_str()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (custom_scheme.options.supportFetchAPI) { | 
					
						
							|  |  |  |       fetch_schemes.push_back(custom_scheme.scheme); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (custom_scheme.options.allowServiceWorkers) { | 
					
						
							|  |  |  |       service_worker_schemes.push_back(custom_scheme.scheme); | 
					
						
							| 
									
										
										
										
											2021-05-31 18:45:23 -07:00
										 |  |  |       AddServiceWorkerScheme(custom_scheme.scheme); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-06-08 11:49:36 -05:00
										 |  |  |     if (custom_scheme.options.stream) { | 
					
						
							|  |  |  |       g_streaming_schemes.push_back(custom_scheme.scheme); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  |     if (custom_scheme.options.codeCache) { | 
					
						
							|  |  |  |       g_code_cache_schemes.push_back(custom_scheme.scheme); | 
					
						
							|  |  |  |       url::AddCodeCacheScheme(custom_scheme.scheme.c_str()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-04 12:27:49 -06:00
										 |  |  |   const auto AppendSchemesToCmdLine = [](const std::string_view switch_name, | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |                                          std::vector<std::string> schemes) { | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  |     if (schemes.empty()) | 
					
						
							|  |  |  |       return; | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |     // Add the schemes to command line switches, so child processes can also
 | 
					
						
							|  |  |  |     // register them.
 | 
					
						
							|  |  |  |     base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( | 
					
						
							|  |  |  |         switch_name, base::JoinString(schemes, ",")); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   AppendSchemesToCmdLine(electron::switches::kSecureSchemes, secure_schemes); | 
					
						
							|  |  |  |   AppendSchemesToCmdLine(electron::switches::kBypassCSPSchemes, | 
					
						
							|  |  |  |                          cspbypassing_schemes); | 
					
						
							|  |  |  |   AppendSchemesToCmdLine(electron::switches::kCORSSchemes, cors_schemes); | 
					
						
							|  |  |  |   AppendSchemesToCmdLine(electron::switches::kFetchSchemes, fetch_schemes); | 
					
						
							|  |  |  |   AppendSchemesToCmdLine(electron::switches::kServiceWorkerSchemes, | 
					
						
							|  |  |  |                          service_worker_schemes); | 
					
						
							|  |  |  |   AppendSchemesToCmdLine(electron::switches::kStandardSchemes, | 
					
						
							|  |  |  |                          g_standard_schemes); | 
					
						
							| 
									
										
										
										
											2020-06-08 11:49:36 -05:00
										 |  |  |   AppendSchemesToCmdLine(electron::switches::kStreamingSchemes, | 
					
						
							|  |  |  |                          g_streaming_schemes); | 
					
						
							| 
									
										
										
										
											2023-12-06 11:22:41 +09:00
										 |  |  |   AppendSchemesToCmdLine(electron::switches::kCodeCacheSchemes, | 
					
						
							|  |  |  |                          g_code_cache_schemes); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-01 17:51:52 -07:00
										 |  |  | const char* const kBuiltinSchemes[] = { | 
					
						
							| 
									
										
										
										
											2019-05-15 08:29:58 +09:00
										 |  |  |     "about", "file", "http", "https", "data", "filesystem", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Protocol::Protocol(ProtocolRegistry* protocol_registry) | 
					
						
							|  |  |  |     : protocol_registry_{protocol_registry} {} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | // Convert error code to string.
 | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  | // static
 | 
					
						
							|  |  |  | std::string_view Protocol::ErrorCodeToString(Error error) { | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |   switch (error) { | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |     case Error::kRegistered: | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |       return "The scheme has been registered"; | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |     case Error::kNotRegistered: | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |       return "The scheme has not been registered"; | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |     case Error::kIntercepted: | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |       return "The scheme has been intercepted"; | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |     case Error::kNotIntercepted: | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |       return "The scheme has not been intercepted"; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |       return "Unexpected error"; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  | Protocol::Error Protocol::RegisterProtocol(ProtocolType type, | 
					
						
							|  |  |  |                                            const std::string& scheme, | 
					
						
							|  |  |  |                                            const ProtocolHandler& handler) { | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  |   bool added = protocol_registry_->RegisterProtocol(type, scheme, handler); | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |   return added ? Error::kOK : Error::kRegistered; | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 09:46:18 -07:00
										 |  |  | bool Protocol::UnregisterProtocol(const std::string& scheme, | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                                   gin::Arguments* args) { | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  |   bool removed = protocol_registry_->UnregisterProtocol(scheme); | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |   HandleOptionalCallback(args, removed ? Error::kOK : Error::kNotRegistered); | 
					
						
							| 
									
										
										
										
											2020-06-02 09:46:18 -07:00
										 |  |  |   return removed; | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  | bool Protocol::IsProtocolRegistered(const std::string& scheme) { | 
					
						
							| 
									
										
										
										
											2024-05-09 08:53:09 -05:00
										 |  |  |   return protocol_registry_->FindRegistered(scheme) != nullptr; | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  | Protocol::Error Protocol::InterceptProtocol(ProtocolType type, | 
					
						
							|  |  |  |                                             const std::string& scheme, | 
					
						
							|  |  |  |                                             const ProtocolHandler& handler) { | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  |   bool added = protocol_registry_->InterceptProtocol(type, scheme, handler); | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |   return added ? Error::kOK : Error::kIntercepted; | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 09:46:18 -07:00
										 |  |  | bool Protocol::UninterceptProtocol(const std::string& scheme, | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                                    gin::Arguments* args) { | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  |   bool removed = protocol_registry_->UninterceptProtocol(scheme); | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |   HandleOptionalCallback(args, removed ? Error::kOK : Error::kNotIntercepted); | 
					
						
							| 
									
										
										
										
											2020-06-02 09:46:18 -07:00
										 |  |  |   return removed; | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  | bool Protocol::IsProtocolIntercepted(const std::string& scheme) { | 
					
						
							| 
									
										
										
										
											2024-05-09 08:53:09 -05:00
										 |  |  |   return protocol_registry_->FindIntercepted(scheme) != nullptr; | 
					
						
							| 
									
										
										
										
											2019-05-07 11:33:05 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  | v8::Local<v8::Promise> Protocol::IsProtocolHandled(const std::string& scheme, | 
					
						
							|  |  |  |                                                    gin::Arguments* args) { | 
					
						
							| 
									
										
										
										
											2024-09-16 15:53:04 -05:00
										 |  |  |   util::EmitWarning(args->isolate(), | 
					
						
							|  |  |  |                     "The protocol.isProtocolHandled API is deprecated, " | 
					
						
							|  |  |  |                     "use protocol.isProtocolRegistered " | 
					
						
							|  |  |  |                     "or protocol.isProtocolIntercepted instead.", | 
					
						
							|  |  |  |                     "ProtocolDeprecateIsProtocolHandled"); | 
					
						
							| 
									
										
										
										
											2019-11-01 15:10:32 +09:00
										 |  |  |   return gin_helper::Promise<bool>::ResolvedPromise( | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  |       args->isolate(), | 
					
						
							|  |  |  |       IsProtocolRegistered(scheme) || IsProtocolIntercepted(scheme) || | 
					
						
							|  |  |  |           // The |isProtocolHandled| should return true for builtin
 | 
					
						
							|  |  |  |           // schemes, however with NetworkService it is impossible to
 | 
					
						
							|  |  |  |           // know which schemes are registered until a real network
 | 
					
						
							|  |  |  |           // request is sent.
 | 
					
						
							|  |  |  |           // So we have to test against a hard-coded builtin schemes
 | 
					
						
							|  |  |  |           // list make it work with old code. We should deprecate
 | 
					
						
							|  |  |  |           // this API with the new |isProtocolRegistered| API.
 | 
					
						
							|  |  |  |           base::Contains(kBuiltinSchemes, scheme)); | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  | void Protocol::HandleOptionalCallback(gin::Arguments* args, Error error) { | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  |   base::RepeatingCallback<void(v8::Local<v8::Value>)> callback; | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |   if (args->GetNext(&callback)) { | 
					
						
							| 
									
										
										
										
											2024-09-16 15:53:04 -05:00
										 |  |  |     util::EmitWarning( | 
					
						
							|  |  |  |         args->isolate(), | 
					
						
							| 
									
										
										
										
											2019-06-28 16:25:30 +09:00
										 |  |  |         "The callback argument of protocol module APIs is no longer needed.", | 
					
						
							|  |  |  |         "ProtocolDeprecateCallback"); | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  |     if (error == Error::kOK) | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |       callback.Run(v8::Null(args->isolate())); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       callback.Run(v8::Exception::Error( | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  |           gin::StringToV8(args->isolate(), ErrorCodeToString(error)))); | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // static
 | 
					
						
							| 
									
										
										
										
											2025-03-21 07:33:25 -05:00
										 |  |  | gin::Handle<Protocol> Protocol::Create(v8::Isolate* isolate, | 
					
						
							|  |  |  |                                        ProtocolRegistry* protocol_registry) { | 
					
						
							|  |  |  |   return gin::CreateHandle(isolate, new Protocol{protocol_registry}); | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-27 10:00:55 -07:00
										 |  |  | // static
 | 
					
						
							|  |  |  | gin::Handle<Protocol> Protocol::New(gin_helper::ErrorThrower thrower) { | 
					
						
							|  |  |  |   thrower.ThrowError("Protocol cannot be created from JS"); | 
					
						
							| 
									
										
										
										
											2024-11-29 11:44:33 -06:00
										 |  |  |   return {}; | 
					
						
							| 
									
										
										
										
											2023-03-27 10:00:55 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // static
 | 
					
						
							|  |  |  | v8::Local<v8::ObjectTemplate> Protocol::FillObjectTemplate( | 
					
						
							|  |  |  |     v8::Isolate* isolate, | 
					
						
							|  |  |  |     v8::Local<v8::ObjectTemplate> tmpl) { | 
					
						
							| 
									
										
										
										
											2023-07-10 11:49:20 +02:00
										 |  |  |   return gin::ObjectTemplateBuilder(isolate, GetClassName(), tmpl) | 
					
						
							| 
									
										
										
										
											2019-04-29 11:37:45 +09:00
										 |  |  |       .SetMethod("registerStringProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::RegisterProtocolFor<ProtocolType::kString>) | 
					
						
							| 
									
										
										
										
											2019-04-29 11:37:45 +09:00
										 |  |  |       .SetMethod("registerBufferProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::RegisterProtocolFor<ProtocolType::kBuffer>) | 
					
						
							| 
									
										
										
										
											2019-04-29 11:37:45 +09:00
										 |  |  |       .SetMethod("registerFileProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::RegisterProtocolFor<ProtocolType::kFile>) | 
					
						
							| 
									
										
										
										
											2019-04-29 11:37:45 +09:00
										 |  |  |       .SetMethod("registerHttpProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::RegisterProtocolFor<ProtocolType::kHttp>) | 
					
						
							| 
									
										
										
										
											2019-04-29 11:37:45 +09:00
										 |  |  |       .SetMethod("registerStreamProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::RegisterProtocolFor<ProtocolType::kStream>) | 
					
						
							| 
									
										
										
										
											2019-05-03 09:48:51 +09:00
										 |  |  |       .SetMethod("registerProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::RegisterProtocolFor<ProtocolType::kFree>) | 
					
						
							|  |  |  |       .SetMethod("unregisterProtocol", &Protocol::UnregisterProtocol) | 
					
						
							|  |  |  |       .SetMethod("isProtocolRegistered", &Protocol::IsProtocolRegistered) | 
					
						
							|  |  |  |       .SetMethod("isProtocolHandled", &Protocol::IsProtocolHandled) | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  |       .SetMethod("interceptStringProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::InterceptProtocolFor<ProtocolType::kString>) | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  |       .SetMethod("interceptBufferProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::InterceptProtocolFor<ProtocolType::kBuffer>) | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  |       .SetMethod("interceptFileProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::InterceptProtocolFor<ProtocolType::kFile>) | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  |       .SetMethod("interceptHttpProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::InterceptProtocolFor<ProtocolType::kHttp>) | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  |       .SetMethod("interceptStreamProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::InterceptProtocolFor<ProtocolType::kStream>) | 
					
						
							| 
									
										
										
										
											2019-05-24 11:28:00 +09:00
										 |  |  |       .SetMethod("interceptProtocol", | 
					
						
							| 
									
										
										
										
											2019-10-23 17:51:06 -07:00
										 |  |  |                  &Protocol::InterceptProtocolFor<ProtocolType::kFree>) | 
					
						
							|  |  |  |       .SetMethod("uninterceptProtocol", &Protocol::UninterceptProtocol) | 
					
						
							| 
									
										
										
										
											2023-03-27 10:00:55 -07:00
										 |  |  |       .SetMethod("isProtocolIntercepted", &Protocol::IsProtocolIntercepted) | 
					
						
							|  |  |  |       .Build(); | 
					
						
							| 
									
										
										
										
											2019-04-24 06:39:21 +09:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  | const char* Protocol::GetTypeName() { | 
					
						
							| 
									
										
										
										
											2023-07-10 11:49:20 +02:00
										 |  |  |   return GetClassName(); | 
					
						
							| 
									
										
										
										
											2020-03-26 10:34:32 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-29 12:55:47 -07:00
										 |  |  | }  // namespace electron::api
 | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  | void RegisterSchemesAsPrivileged(gin_helper::ErrorThrower thrower, | 
					
						
							|  |  |  |                                  v8::Local<v8::Value> val) { | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |   if (electron::Browser::Get()->is_ready()) { | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  |     thrower.ThrowError( | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |         "protocol.registerSchemesAsPrivileged should be called before " | 
					
						
							|  |  |  |         "app is ready"); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  |   electron::api::RegisterSchemesAsPrivileged(thrower, val); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Initialize(v8::Local<v8::Object> exports, | 
					
						
							|  |  |  |                 v8::Local<v8::Value> unused, | 
					
						
							|  |  |  |                 v8::Local<v8::Context> context, | 
					
						
							|  |  |  |                 void* priv) { | 
					
						
							|  |  |  |   v8::Isolate* isolate = context->GetIsolate(); | 
					
						
							| 
									
										
										
										
											2019-10-15 10:15:23 +09:00
										 |  |  |   gin_helper::Dictionary dict(isolate, exports); | 
					
						
							| 
									
										
										
										
											2023-03-27 10:00:55 -07:00
										 |  |  |   dict.Set("Protocol", electron::api::Protocol::GetConstructor(context)); | 
					
						
							| 
									
										
										
										
											2019-08-02 16:56:46 -07:00
										 |  |  |   dict.SetMethod("registerSchemesAsPrivileged", &RegisterSchemesAsPrivileged); | 
					
						
							|  |  |  |   dict.SetMethod("getStandardSchemes", &electron::api::GetStandardSchemes); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 02:31:38 +01:00
										 |  |  | NODE_LINKED_BINDING_CONTEXT_AWARE(electron_browser_protocol, Initialize) |