summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/loader/threadable_loader.h
blob: be9ca749c2c1ac5cb006aff61bca53d0389472e5 (plain)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
 * Copyright (C) 2009, 2012 Google Inc. All rights reserved.
 * Copyright (C) 2013, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADER_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADER_H_

#include <memory>

#include "base/macros.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink-forward.h"
#include "third_party/blink/public/platform/web_url_loader.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/network/http_header_map.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"

namespace blink {

class ExecutionContext;
class ResourceRequest;
class ThreadableLoaderClient;

// Useful for doing loader operations from any thread (not threadsafe, just able
// to run on threads other than the main thread).
//
// Can perform requests either synchronously or asynchronously. Requests are
// asynchronous by default, and this behavior can be controlled by passing
// a ResourceLoaderOptions with synchronous_policy == kRequestSynchronously to
// the constructor.
// In either case, Start() must be called to actaully begin the request.
class CORE_EXPORT ThreadableLoader final
    : public GarbageCollected<ThreadableLoader>,
      private RawResourceClient {
 public:
  // ThreadableLoaderClient methods are never called before Start() call.
  //
  // Loading is separated into the constructor and the Start() method in order
  // to:
  // - reduce work done in a constructor
  // - not to ask the users to handle failures in the constructor and other
  //   async failures separately
  //
  // Loading completes when one of the following methods are called:
  // - DidFinishLoading()
  // - DidFail()
  // - DidFailRedirectCheck()
  // After any of these methods is called, the loader won't call any of the
  // ThreadableLoaderClient methods.
  //
  // When ThreadableLoader::Cancel() is called,
  // ThreadableLoaderClient::DidFail() is called with a ResourceError
  // with IsCancellation() returning true, if any of DidFinishLoading()
  // or DidFail.*() methods have not been called yet. (DidFail() may be
  // called with a ResourceError with IsCancellation() returning true
  // also for cancellation happened inside the loader.)
  //
  // ThreadableLoaderClient methods may call Cancel().
  //
  // The specified ResourceFetcher if non-null, or otherwise
  // ExecutionContext::Fetcher() is used.
  ThreadableLoader(ExecutionContext&,
                   ThreadableLoaderClient*,
                   const ResourceLoaderOptions&,
                   ResourceFetcher* = nullptr);
  ~ThreadableLoader() override;

  // Must be called to actually begin the request.
  void Start(ResourceRequest);

  // A ThreadableLoader may have a timeout specified. It is possible, in some
  // cases, for the timeout to be overridden after the request is sent (for
  // example, XMLHttpRequests may override their timeout setting after sending).
  //
  // If the request has already started, the new timeout will be relative to the
  // time the request started.
  //
  // Passing a timeout of zero means there should be no timeout.
  void SetTimeout(const base::TimeDelta& timeout);

  void Cancel();

  // Detach the loader from the request. This function is for "keepalive"
  // requests. No notification will be sent to the client, but the request
  // will be processed.
  void Detach();

  void SetDefersLoading(bool);

  void Trace(Visitor* visitor) const override;

 private:
  void Clear();

  void DidTimeout(TimerBase*);

  void DispatchDidFail(const ResourceError&);

  // ResourceClient implementation:
  void NotifyFinished(Resource*) override;
  String DebugName() const override { return "ThreadableLoader"; }

  // RawResourceClient implementation:
  void DataSent(Resource*,
                uint64_t bytes_sent,
                uint64_t total_bytes_to_be_sent) override;
  void ResponseReceived(Resource*, const ResourceResponse&) override;
  void ResponseBodyReceived(Resource*, BytesConsumer& body) override;
  void SetSerializedCachedMetadata(Resource*, const uint8_t*, size_t) override;
  void DataReceived(Resource*, const char* data, size_t data_length) override;
  bool RedirectReceived(Resource*,
                        const ResourceRequest&,
                        const ResourceResponse&) override;
  void RedirectBlocked() override;
  void DataDownloaded(Resource*, uint64_t) override;
  void DidDownloadToBlob(Resource*, scoped_refptr<BlobDataHandle>) override;

  Member<ThreadableLoaderClient> client_;
  Member<ExecutionContext> execution_context_;
  Member<ResourceFetcher> resource_fetcher_;

  const ResourceLoaderOptions resource_loader_options_;

  // Saved so that we can use the original mode in ResponseReceived() where
  // |resource| might be a reused one (e.g. preloaded resource) which can have a
  // different mode.
  network::mojom::RequestMode request_mode_;

  // Set via SetTimeout() by a user before Start().
  base::TimeDelta timeout_;
  // Used to detect |timeout_| is over.
  TaskRunnerTimer<ThreadableLoader> timeout_timer_;

  // Time an asynchronous fetch request is started
  base::TimeTicks request_started_;

  RawResourceClientStateChecker checker_;

  DISALLOW_COPY_AND_ASSIGN(ThreadableLoader);
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LOADER_THREADABLE_LOADER_H_