1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132

content / browser / service_worker / service_worker_script_loader_factory.h [blame]

// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_LOADER_FACTORY_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_LOADER_FACTORY_H_

#include <memory>

#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "net/base/net_errors.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"

class GURL;

namespace network {
class SharedURLLoaderFactory;
}  // namespace network

namespace content {

class ServiceWorkerCacheWriter;
class ServiceWorkerContextCore;
class ServiceWorkerHost;

// Created per one running service worker for loading its scripts. This is kept
// alive while the WebServiceWorkerNetworkProvider in the renderer process is
// alive.
//
// This factory handles requests for scripts from service workers that were new
// (non-installed) when they started. For service workers that were already
// installed when they started, ServiceWorkerInstalledScriptsManager is used
// instead.
//
// This factory creates either a ServiceWorkerNewScriptLoader or a
// ServiceWorkerInstalledScriptLoader to load a script.
class CONTENT_EXPORT ServiceWorkerScriptLoaderFactory
    : public network::mojom::URLLoaderFactory {
 public:
  // |loader_factory_for_new_scripts| is used to load scripts. Typically
  // a new script will be loaded from the NetworkService. However,
  // |loader_factory_for_new_scripts| may internally contain non-NetworkService
  // factories used for non-http(s) URLs, e.g., a chrome-extension:// URL.
  //
  // |loader_factory_for_new_scripts| is null if this factory is created for an
  // installed service worker, which is expected to load its scripts via
  // ServiceWorkerInstalledScriptsManager, and only uses this factory for
  // loading non-installed scripts, in which case this factory returns network
  // error.
  ServiceWorkerScriptLoaderFactory(
      base::WeakPtr<ServiceWorkerContextCore> context,
      base::WeakPtr<ServiceWorkerHost> worker_host,
      scoped_refptr<network::SharedURLLoaderFactory>
          loader_factory_for_new_scripts);

  ServiceWorkerScriptLoaderFactory(const ServiceWorkerScriptLoaderFactory&) =
      delete;
  ServiceWorkerScriptLoaderFactory& operator=(
      const ServiceWorkerScriptLoaderFactory&) = delete;

  ~ServiceWorkerScriptLoaderFactory() override;

  // network::mojom::URLLoaderFactory:
  void CreateLoaderAndStart(
      mojo::PendingReceiver<network::mojom::URLLoader> receiver,
      int32_t request_id,
      uint32_t options,
      const network::ResourceRequest& resource_request,
      mojo::PendingRemote<network::mojom::URLLoaderClient> client,
      const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
      override;
  void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
      override;

  void Update(scoped_refptr<network::SharedURLLoaderFactory> loader_factory);

 private:
  bool CheckIfScriptRequestIsValid(
      const network::ResourceRequest& resource_request);

  // The callback is called once the copy is done. It normally runs
  // asynchronously, and would be synchronous if the operation completes
  // synchronously. The first parameter of the callback is the new resource id
  // and the second parameter is the result of the operation. net::OK means
  // success.
  void CopyScript(const GURL& url,
                  int64_t resource_id,
                  base::OnceCallback<void(int64_t, net::Error)> callback,
                  int64_t new_resource_id);

  // This method is called to notify that the operation triggered by
  // CopyScript() completed.
  //
  // If the copy operation is successful, a ServiceWorkerInstalledScriptLoader
  // would be created to load the new copy.
  void OnCopyScriptFinished(
      mojo::PendingReceiver<network::mojom::URLLoader> receiver,
      uint32_t options,
      const network::ResourceRequest& resource_request,
      mojo::PendingRemote<network::mojom::URLLoaderClient> client,
      int64_t new_resource_id,
      net::Error error);

  void OnResourceIdAssignedForNewScriptLoader(
      mojo::PendingReceiver<network::mojom::URLLoader> receiver,
      int32_t request_id,
      uint32_t options,
      const network::ResourceRequest& resource_request,
      mojo::PendingRemote<network::mojom::URLLoaderClient> client,
      const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
      int64_t resource_id);

  base::WeakPtr<ServiceWorkerContextCore> context_;
  base::WeakPtr<ServiceWorkerHost> worker_host_;
  // Can be null if this factory is for an installed service worker.
  scoped_refptr<network::SharedURLLoaderFactory>
      loader_factory_for_new_scripts_;

  mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;

  // Used to copy script started at CopyScript().
  std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_;

  base::WeakPtrFactory<ServiceWorkerScriptLoaderFactory> weak_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_SCRIPT_LOADER_FACTORY_H_