1/*
2 * Copyright (C) 2005-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#pragma once
30
31#include "LoadTiming.h"
32#include "ResourceHandleClient.h"
33#include "ResourceLoaderOptions.h"
34#include "ResourceLoaderTypes.h"
35#include "ResourceRequest.h"
36#include "ResourceResponse.h"
37#include <wtf/Forward.h>
38#include <wtf/WeakPtr.h>
39
40#if ENABLE(CONTENT_EXTENSIONS)
41#include "ResourceLoadInfo.h"
42#endif
43
44namespace WTF {
45class SchedulePair;
46}
47
48namespace WebCore {
49
50class AuthenticationChallenge;
51class DocumentLoader;
52class Frame;
53class FrameLoader;
54class NetworkLoadMetrics;
55class PreviewLoader;
56
57class ResourceLoader : public CanMakeWeakPtr<ResourceLoader>, public RefCounted<ResourceLoader>, protected ResourceHandleClient {
58public:
59 virtual ~ResourceLoader() = 0;
60
61 WEBCORE_EXPORT void cancel();
62
63 virtual void init(ResourceRequest&&, CompletionHandler<void(bool)>&&);
64
65 void deliverResponseAndData(const ResourceResponse&, RefPtr<SharedBuffer>&&);
66
67#if PLATFORM(IOS_FAMILY)
68 virtual void startLoading()
69 {
70 start();
71 }
72
73 virtual const ResourceRequest& iOSOriginalRequest() const { return request(); }
74#endif
75
76 WEBCORE_EXPORT FrameLoader* frameLoader() const;
77 DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
78 const ResourceRequest& originalRequest() const { return m_originalRequest; }
79
80 WEBCORE_EXPORT void start();
81 WEBCORE_EXPORT void cancel(const ResourceError&);
82 WEBCORE_EXPORT ResourceError cancelledError();
83 ResourceError blockedError();
84 ResourceError blockedByContentBlockerError();
85 ResourceError cannotShowURLError();
86
87 virtual void setDefersLoading(bool);
88 bool defersLoading() const { return m_defersLoading; }
89
90 unsigned long identifier() const { return m_identifier; }
91
92 bool wasAuthenticationChallengeBlocked() const { return m_wasAuthenticationChallengeBlocked; }
93
94 virtual void releaseResources();
95 const ResourceResponse& response() const { return m_response; }
96
97 SharedBuffer* resourceData() const { return m_resourceData.get(); }
98 void clearResourceData();
99
100 virtual bool isSubresourceLoader() const;
101
102 virtual void willSendRequest(ResourceRequest&&, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& callback);
103 virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
104 virtual void didReceiveResponse(const ResourceResponse&, CompletionHandler<void()>&& policyCompletionHandler);
105 virtual void didReceiveData(const char*, unsigned, long long encodedDataLength, DataPayloadType);
106 virtual void didReceiveBuffer(Ref<SharedBuffer>&&, long long encodedDataLength, DataPayloadType);
107 virtual void didFinishLoading(const NetworkLoadMetrics&);
108 virtual void didFail(const ResourceError&);
109
110 WEBCORE_EXPORT void didBlockAuthenticationChallenge();
111
112 virtual bool shouldUseCredentialStorage();
113#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
114 virtual bool canAuthenticateAgainstProtectionSpace(const ProtectionSpace&);
115#endif
116 virtual void receivedCancellation(const AuthenticationChallenge&);
117
118#if USE(QUICK_LOOK)
119 bool isQuickLookResource() const;
120#endif
121
122 const URL& url() const { return m_request.url(); }
123 ResourceHandle* handle() const { return m_handle.get(); }
124 bool shouldSendResourceLoadCallbacks() const { return m_options.sendLoadCallbacks == SendCallbackPolicy::SendCallbacks; }
125 void setSendCallbackPolicy(SendCallbackPolicy sendLoadCallbacks) { m_options.sendLoadCallbacks = sendLoadCallbacks; }
126 bool shouldSniffContent() const { return m_options.sniffContent == ContentSniffingPolicy::SniffContent; }
127 bool shouldSniffContentEncoding() const { return m_options.sniffContentEncoding == ContentEncodingSniffingPolicy::Sniff; }
128 WEBCORE_EXPORT bool isAllowedToAskUserForCredentials() const;
129 WEBCORE_EXPORT bool shouldIncludeCertificateInfo() const;
130
131 bool reachedTerminalState() const { return m_reachedTerminalState; }
132
133
134 const ResourceRequest& request() const { return m_request; }
135 void setRequest(ResourceRequest&& request) { m_request = WTFMove(request); }
136
137 void setDataBufferingPolicy(DataBufferingPolicy);
138
139 void willSwitchToSubstituteResource();
140
141 const LoadTiming& loadTiming() { return m_loadTiming; }
142
143#if PLATFORM(COCOA)
144 void schedule(WTF::SchedulePair&);
145 void unschedule(WTF::SchedulePair&);
146#endif
147
148 const Frame* frame() const { return m_frame.get(); }
149 WEBCORE_EXPORT bool isAlwaysOnLoggingAllowed() const;
150
151 const ResourceLoaderOptions& options() const { return m_options; }
152
153 const ResourceRequest& deferredRequest() const { return m_deferredRequest; }
154 ResourceRequest takeDeferredRequest() { return std::exchange(m_deferredRequest, { }); }
155
156protected:
157 ResourceLoader(Frame&, ResourceLoaderOptions);
158
159 void didFinishLoadingOnePart(const NetworkLoadMetrics&);
160 void cleanupForError(const ResourceError&);
161
162 bool wasCancelled() const { return m_cancellationStatus >= Cancelled; }
163
164 void didReceiveDataOrBuffer(const char*, unsigned, RefPtr<SharedBuffer>&&, long long encodedDataLength, DataPayloadType);
165
166 void setReferrerPolicy(ReferrerPolicy referrerPolicy) { m_options.referrerPolicy = referrerPolicy; }
167 ReferrerPolicy referrerPolicy() const { return m_options.referrerPolicy; }
168
169#if PLATFORM(COCOA)
170 void willCacheResponseAsync(ResourceHandle*, NSCachedURLResponse*, CompletionHandler<void(NSCachedURLResponse *)>&&) override;
171#endif
172
173 virtual void willSendRequestInternal(ResourceRequest&&, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&&);
174
175 RefPtr<ResourceHandle> m_handle;
176 RefPtr<Frame> m_frame;
177 RefPtr<DocumentLoader> m_documentLoader;
178 ResourceResponse m_response;
179 LoadTiming m_loadTiming;
180#if USE(QUICK_LOOK)
181 std::unique_ptr<PreviewLoader> m_previewLoader;
182#endif
183 bool m_canCrossOriginRequestsAskUserForCredentials { true };
184
185private:
186 virtual void willCancel(const ResourceError&) = 0;
187 virtual void didCancel(const ResourceError&) = 0;
188
189 void addDataOrBuffer(const char*, unsigned, SharedBuffer*, DataPayloadType);
190 void loadDataURL();
191 void finishNetworkLoad();
192
193 bool shouldAllowResourceToAskForCredentials() const;
194
195 // ResourceHandleClient
196 void didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
197 void didReceiveResponseAsync(ResourceHandle*, ResourceResponse&&, CompletionHandler<void()>&&) override;
198 void willSendRequestAsync(ResourceHandle*, ResourceRequest&&, ResourceResponse&&, CompletionHandler<void(ResourceRequest&&)>&&) override;
199 void didReceiveData(ResourceHandle*, const char*, unsigned, int encodedDataLength) override;
200 void didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&&, int encodedDataLength) override;
201 void didFinishLoading(ResourceHandle*) override;
202 void didFail(ResourceHandle*, const ResourceError&) override;
203 void wasBlocked(ResourceHandle*) override;
204 void cannotShowURL(ResourceHandle*) override;
205 bool shouldUseCredentialStorage(ResourceHandle*) override { return shouldUseCredentialStorage(); }
206 void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge&) override;
207#if USE(PROTECTION_SPACE_AUTH_CALLBACK)
208 void canAuthenticateAgainstProtectionSpaceAsync(ResourceHandle*, const ProtectionSpace&, CompletionHandler<void(bool)>&&) override;
209#endif
210 void receivedCancellation(ResourceHandle*, const AuthenticationChallenge& challenge) override { receivedCancellation(challenge); }
211#if PLATFORM(IOS_FAMILY)
212 RetainPtr<CFDictionaryRef> connectionProperties(ResourceHandle*) override;
213#endif
214#if USE(CFURLCONNECTION)
215 // FIXME: Windows should use willCacheResponse - <https://bugs.webkit.org/show_bug.cgi?id=57257>.
216 bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef) override;
217#endif
218
219#if USE(SOUP)
220 void loadGResource();
221#endif
222
223 ResourceRequest m_request;
224 ResourceRequest m_originalRequest; // Before redirects.
225 RefPtr<SharedBuffer> m_resourceData;
226
227 unsigned long m_identifier { 0 };
228
229 bool m_reachedTerminalState { false };
230 bool m_notifiedLoadComplete { false };
231
232 enum CancellationStatus {
233 NotCancelled,
234 CalledWillCancel,
235 Cancelled,
236 FinishedCancel
237 };
238 CancellationStatus m_cancellationStatus { NotCancelled };
239
240 bool m_defersLoading;
241 bool m_wasAuthenticationChallengeBlocked { false };
242 ResourceRequest m_deferredRequest;
243 ResourceLoaderOptions m_options;
244
245#if ENABLE(CONTENT_EXTENSIONS)
246protected:
247 ContentExtensions::ResourceType m_resourceType { ContentExtensions::ResourceType::Invalid };
248#endif
249};
250
251} // namespace WebCore
252