Browse Source

protocol: api to register schemes that can handle service worker

Robo 9 years ago
parent
commit
855d49100f

+ 28 - 6
atom/app/atom_content_client.cc

@@ -17,6 +17,7 @@
 #include "content/public/common/pepper_plugin_info.h"
 #include "content/public/common/user_agent.h"
 #include "ppapi/shared_impl/ppapi_permissions.h"
+#include "url/url_constants.h"
 
 namespace atom {
 
@@ -62,6 +63,17 @@ content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path,
   return plugin;
 }
 
+void ConvertStringWithSeparatorToVector(std::vector<std::string>* vec,
+                                        const char* separator,
+                                        const char* cmd_switch) {
+  auto command_line = base::CommandLine::ForCurrentProcess();
+  auto string_with_separator = command_line->GetSwitchValueASCII(cmd_switch);
+  if (!string_with_separator.empty())
+    *vec = base::SplitString(string_with_separator, separator,
+                             base::TRIM_WHITESPACE,
+                             base::SPLIT_WANT_NONEMPTY);
+}
+
 }  // namespace
 
 AtomContentClient::AtomContentClient() {
@@ -83,12 +95,10 @@ std::string AtomContentClient::GetUserAgent() const {
 void AtomContentClient::AddAdditionalSchemes(
     std::vector<url::SchemeWithType>* standard_schemes,
     std::vector<std::string>* savable_schemes) {
-  auto command_line = base::CommandLine::ForCurrentProcess();
-  auto custom_schemes = command_line->GetSwitchValueASCII(
-      switches::kRegisterStandardSchemes);
-  if (!custom_schemes.empty()) {
-    std::vector<std::string> schemes = base::SplitString(
-        custom_schemes, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+  std::vector<std::string> schemes;
+  ConvertStringWithSeparatorToVector(&schemes, ",",
+                                     switches::kRegisterStandardSchemes);
+  if (!schemes.empty()) {
     for (const std::string& scheme : schemes)
       standard_schemes->push_back({scheme.c_str(), url::SCHEME_WITHOUT_PORT});
   }
@@ -110,4 +120,16 @@ void AtomContentClient::AddPepperPlugins(
       CreatePepperFlashInfo(flash_path, flash_version));
 }
 
+void AtomContentClient::AddServiceWorkerSchemes(
+    std::set<std::string>* service_worker_schemes) {
+  std::vector<std::string> schemes;
+  ConvertStringWithSeparatorToVector(&schemes, ",",
+                                     switches::kRegisterServiceWorkerSchemes);
+  if (!schemes.empty()) {
+    for (const std::string& scheme : schemes)
+      service_worker_schemes->insert(scheme);
+  }
+  service_worker_schemes->insert(url::kFileScheme);
+}
+
 }  // namespace atom

+ 3 - 0
atom/app/atom_content_client.h

@@ -5,6 +5,7 @@
 #ifndef ATOM_APP_ATOM_CONTENT_CLIENT_H_
 #define ATOM_APP_ATOM_CONTENT_CLIENT_H_
 
+#include <set>
 #include <string>
 #include <vector>
 
@@ -26,6 +27,8 @@ class AtomContentClient : public brightray::ContentClient {
       std::vector<std::string>* savable_schemes) override;
   void AddPepperPlugins(
       std::vector<content::PepperPluginInfo>* plugins) override;
+  void AddServiceWorkerSchemes(
+      std::set<std::string>* service_worker_schemes) override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AtomContentClient);

+ 7 - 0
atom/browser/api/atom_api_protocol.cc

@@ -32,6 +32,8 @@ mate::ObjectTemplateBuilder Protocol::GetObjectTemplateBuilder(
     v8::Isolate* isolate) {
   return mate::ObjectTemplateBuilder(isolate)
       .SetMethod("registerStandardSchemes", &Protocol::RegisterStandardSchemes)
+      .SetMethod("registerServiceWorkerSchemes",
+                 &Protocol::RegisterServiceWorkerSchemes)
       .SetMethod("registerStringProtocol",
                  &Protocol::RegisterProtocol<URLRequestStringJob>)
       .SetMethod("registerBufferProtocol",
@@ -58,6 +60,11 @@ void Protocol::RegisterStandardSchemes(
   atom::AtomBrowserClient::SetCustomSchemes(schemes);
 }
 
+void Protocol::RegisterServiceWorkerSchemes(
+    const std::vector<std::string>& schemes) {
+  atom::AtomBrowserClient::SetCustomServiceWorkerSchemes(schemes);
+}
+
 void Protocol::UnregisterProtocol(
     const std::string& scheme, mate::Arguments* args) {
   CompletionCallback callback;

+ 3 - 0
atom/browser/api/atom_api_protocol.h

@@ -92,6 +92,9 @@ class Protocol : public mate::Wrappable {
   // Register schemes to standard scheme list.
   void RegisterStandardSchemes(const std::vector<std::string>& schemes);
 
+  // Register schemes that can handle service worker.
+  void RegisterServiceWorkerSchemes(const std::vector<std::string>& schemes);
+
   // Register the protocol with certain request job.
   template<typename RequestJob>
   void RegisterProtocol(const std::string& scheme,

+ 12 - 0
atom/browser/atom_browser_client.cc

@@ -54,6 +54,8 @@ bool g_suppress_renderer_process_restart = false;
 
 // Custom schemes to be registered to standard.
 std::string g_custom_schemes = "";
+// Custom schemes to be registered to handle service worker.
+std::string g_custom_service_worker_schemes = "";
 
 scoped_refptr<net::X509Certificate> ImportCertFromFile(
     const base::FilePath& path) {
@@ -87,6 +89,11 @@ void AtomBrowserClient::SetCustomSchemes(
   g_custom_schemes = base::JoinString(schemes, ",");
 }
 
+void AtomBrowserClient::SetCustomServiceWorkerSchemes(
+    const std::vector<std::string>& schemes) {
+  g_custom_service_worker_schemes = base::JoinString(schemes, ",");
+}
+
 AtomBrowserClient::AtomBrowserClient() : delegate_(nullptr) {
 }
 
@@ -172,6 +179,11 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
     command_line->AppendSwitchASCII(switches::kRegisterStandardSchemes,
                                     g_custom_schemes);
 
+  // The registered service worker schemes.
+  if (!g_custom_service_worker_schemes.empty())
+    command_line->AppendSwitchASCII(switches::kRegisterServiceWorkerSchemes,
+                                    g_custom_service_worker_schemes);
+
 #if defined(OS_WIN)
   // Append --app-user-model-id.
   PWSTR current_app_id;

+ 3 - 0
atom/browser/atom_browser_client.h

@@ -38,6 +38,9 @@ class AtomBrowserClient : public brightray::BrowserClient,
   static void SuppressRendererProcessRestartForOnce();
   // Custom schemes to be registered to standard.
   static void SetCustomSchemes(const std::vector<std::string>& schemes);
+  // Custom schemes to be registered to handle service worker.
+  static void SetCustomServiceWorkerSchemes(
+      const std::vector<std::string>& schemes);
 
  protected:
   // content::ContentBrowserClient:

+ 16 - 2
atom/browser/net/asar/url_request_asar_job.cc

@@ -7,13 +7,14 @@
 #include <string>
 #include <vector>
 
+#include "atom/common/asar/archive.h"
+#include "atom/common/asar/asar_util.h"
+#include "atom/common/atom_constants.h"
 #include "base/bind.h"
 #include "base/files/file_util.h"
 #include "base/strings/string_util.h"
 #include "base/synchronization/lock.h"
 #include "base/task_runner.h"
-#include "atom/common/asar/archive.h"
-#include "atom/common/asar/asar_util.h"
 #include "net/base/file_stream.h"
 #include "net/base/filename_util.h"
 #include "net/base/io_buffer.h"
@@ -227,6 +228,19 @@ void URLRequestAsarJob::SetExtraRequestHeaders(
   }
 }
 
+int URLRequestAsarJob::GetResponseCode() const {
+  // Request Job gets created only if path exists.
+  return 200;
+}
+
+void URLRequestAsarJob::GetResponseInfo(net::HttpResponseInfo* info) {
+  std::string status("HTTP/1.1 200 OK");
+  net::HttpResponseHeaders* headers = new net::HttpResponseHeaders(status);
+
+  headers->AddHeader(atom::kCORSHeader);
+  info->headers = headers;
+}
+
 void URLRequestAsarJob::FetchMetaInfo(const base::FilePath& file_path,
                                       FileMetaInfo* meta_info) {
   base::File::Info file_info;

+ 2 - 0
atom/browser/net/asar/url_request_asar_job.h

@@ -61,6 +61,8 @@ class URLRequestAsarJob : public net::URLRequestJob {
   net::Filter* SetupFilter() const override;
   bool GetMimeType(std::string* mime_type) const override;
   void SetExtraRequestHeaders(const net::HttpRequestHeaders& headers) override;
+  int GetResponseCode() const override;
+  void GetResponseInfo(net::HttpResponseInfo* info) override;
 
  private:
   // Meta information about the file. It's used as a member in the

+ 3 - 0
atom/common/options_switches.cc

@@ -119,6 +119,9 @@ const char kDisableHttpCache[] = "disable-http-cache";
 // Register schemes to standard.
 const char kRegisterStandardSchemes[] = "register-standard-schemes";
 
+// Register schemes to handle service worker.
+const char kRegisterServiceWorkerSchemes[] = "register-service-worker-schemes";
+
 // The minimum SSL/TLS version ("tls1", "tls1.1", or "tls1.2") that
 // TLS fallback will accept.
 const char kSSLVersionFallbackMin[] = "ssl-version-fallback-min";

+ 1 - 0
atom/common/options_switches.h

@@ -66,6 +66,7 @@ extern const char kPpapiFlashVersion[];
 extern const char kClientCertificate[];
 extern const char kDisableHttpCache[];
 extern const char kRegisterStandardSchemes[];
+extern const char kRegisterServiceWorkerSchemes[];
 extern const char kSSLVersionFallbackMin[];
 extern const char kCipherSuiteBlacklist[];
 extern const char kAppUserModelId[];

+ 4 - 0
atom/renderer/atom_renderer_client.cc

@@ -27,6 +27,7 @@
 #include "third_party/WebKit/public/web/WebLocalFrame.h"
 #include "third_party/WebKit/public/web/WebPluginParams.h"
 #include "third_party/WebKit/public/web/WebKit.h"
+#include "third_party/WebKit/public/web/WebSecurityPolicy.h"
 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
 #include "third_party/WebKit/public/web/WebView.h"
 
@@ -129,6 +130,9 @@ void AtomRendererClient::RenderFrameCreated(
     content::RenderFrame* render_frame) {
   new PepperHelper(render_frame);
   new AtomRenderFrameObserver(render_frame, this);
+
+  // Allow file scheme to handle service worker by default.
+  blink::WebSecurityPolicy::registerURLSchemeAsAllowingServiceWorkers("file");
 }
 
 void AtomRendererClient::RenderViewCreated(content::RenderView* render_view) {

+ 4 - 0
docs/api/protocol.md

@@ -38,6 +38,10 @@ A standard `scheme` adheres to what RFC 3986 calls
 [generic URI syntax](https://tools.ietf.org/html/rfc3986#section-3). This
 includes `file:` and `filesystem:`.
 
+### `protocol.registerServiceWorkerSchemes(schemes)`
+
+* `schemes` Array - Custom schemes to be registered to handle service workers.
+
 ### `protocol.registerFileProtocol(scheme, handler[, completion])`
 
 * `scheme` String