[Resource Timing] Gather timing information with reliable responseEnd time
[WebKit-https.git] / Source / WebCore / loader / ResourceLoader.h
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
39 #if ENABLE(CONTENT_EXTENSIONS)
40 #include "ResourceLoadInfo.h"
41 #endif
42
43 namespace WTF {
44 class SchedulePair;
45 }
46
47 namespace WebCore {
48
49 class AuthenticationChallenge;
50 class DocumentLoader;
51 class Frame;
52 class FrameLoader;
53 class NetworkLoadMetrics;
54 class QuickLookHandle;
55 class URL;
56
57 class ResourceLoader : public RefCounted<ResourceLoader>, protected ResourceHandleClient {
58 public:
59     virtual ~ResourceLoader() = 0;
60
61     WEBCORE_EXPORT void cancel();
62
63     virtual bool init(const ResourceRequest&);
64
65     void deliverResponseAndData(const ResourceResponse&, RefPtr<SharedBuffer>&&);
66
67 #if PLATFORM(IOS)
68     virtual bool startLoading()
69     {
70         start();
71         return true;
72     }
73
74     virtual const ResourceRequest& iOSOriginalRequest() const { return request(); }
75 #endif
76
77     WEBCORE_EXPORT FrameLoader* frameLoader() const;
78     DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
79     const ResourceRequest& originalRequest() const { return m_originalRequest; }
80
81     WEBCORE_EXPORT void start();
82     WEBCORE_EXPORT void cancel(const ResourceError&);
83     WEBCORE_EXPORT ResourceError cancelledError();
84     ResourceError blockedError();
85     ResourceError blockedByContentBlockerError();
86     ResourceError cannotShowURLError();
87     
88     virtual void setDefersLoading(bool);
89     bool defersLoading() const { return m_defersLoading; }
90
91     unsigned long identifier() const { return m_identifier; }
92
93     virtual void releaseResources();
94     const ResourceResponse& response() const { return m_response; }
95
96     SharedBuffer* resourceData() const { return m_resourceData.get(); }
97     void clearResourceData();
98     
99     virtual bool isSubresourceLoader();
100
101     virtual void willSendRequest(ResourceRequest&&, const ResourceResponse& redirectResponse, std::function<void(ResourceRequest&&)>&& callback);
102     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent);
103     virtual void didReceiveResponse(const ResourceResponse&);
104     virtual void didReceiveData(const char*, unsigned, long long encodedDataLength, DataPayloadType);
105     virtual void didReceiveBuffer(Ref<SharedBuffer>&&, long long encodedDataLength, DataPayloadType);
106     virtual void didFinishLoading(const NetworkLoadMetrics&);
107     virtual void didFail(const ResourceError&);
108 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
109     virtual void didReceiveDataArray(CFArrayRef dataArray);
110 #endif
111     virtual void didRetrieveDerivedDataFromCache(const String& type, SharedBuffer&);
112
113     virtual bool shouldUseCredentialStorage();
114     virtual void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
115 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
116     virtual bool canAuthenticateAgainstProtectionSpace(const ProtectionSpace&);
117 #endif
118     virtual void receivedCancellation(const AuthenticationChallenge&);
119
120 #if USE(QUICK_LOOK)
121     bool isQuickLookResource() const;
122 #endif
123
124     const URL& url() const { return m_request.url(); }
125     ResourceHandle* handle() const { return m_handle.get(); }
126     bool shouldSendResourceLoadCallbacks() const { return m_options.sendLoadCallbacks == SendCallbacks; }
127     void setSendCallbackPolicy(SendCallbackPolicy sendLoadCallbacks) { m_options.sendLoadCallbacks = sendLoadCallbacks; }
128     bool shouldSniffContent() const { return m_options.sniffContent == SniffContent; }
129     WEBCORE_EXPORT bool isAllowedToAskUserForCredentials() const;
130     bool shouldIncludeCertificateInfo() const { return m_options.certificateInfoPolicy == IncludeCertificateInfo; }
131
132     bool reachedTerminalState() const { return m_reachedTerminalState; }
133
134
135     const ResourceRequest& request() const { return m_request; }
136
137     void setDataBufferingPolicy(DataBufferingPolicy);
138
139     void willSwitchToSubstituteResource();
140
141     const LoadTiming& loadTiming() { return m_loadTiming; }
142
143 #if PLATFORM(COCOA) && !USE(CFURLCONNECTION)
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 protected:
154     ResourceLoader(Frame&, ResourceLoaderOptions);
155
156     void didFinishLoadingOnePart(const NetworkLoadMetrics&);
157     void cleanupForError(const ResourceError&);
158
159     bool wasCancelled() const { return m_cancellationStatus >= Cancelled; }
160
161     void didReceiveDataOrBuffer(const char*, unsigned, RefPtr<SharedBuffer>&&, long long encodedDataLength, DataPayloadType);
162
163 #if PLATFORM(COCOA) && !USE(CFURLCONNECTION)
164     NSCachedURLResponse* willCacheResponse(ResourceHandle*, NSCachedURLResponse*) override;
165 #endif
166 #if PLATFORM(COCOA) && USE(CFURLCONNECTION)
167     CFCachedURLResponseRef willCacheResponse(ResourceHandle*, CFCachedURLResponseRef) override;
168 #endif
169
170     virtual void willSendRequestInternal(ResourceRequest&, const ResourceResponse& redirectResponse);
171
172     RefPtr<ResourceHandle> m_handle;
173     RefPtr<Frame> m_frame;
174     RefPtr<DocumentLoader> m_documentLoader;
175     ResourceResponse m_response;
176     LoadTiming m_loadTiming;
177 #if USE(QUICK_LOOK)
178     std::unique_ptr<QuickLookHandle> m_quickLookHandle;
179 #endif
180
181 private:
182     virtual void willCancel(const ResourceError&) = 0;
183     virtual void didCancel(const ResourceError&) = 0;
184
185     void addDataOrBuffer(const char*, unsigned, SharedBuffer*, DataPayloadType);
186     void loadDataURL();
187     void finishNetworkLoad();
188
189     // ResourceHandleClient
190     ResourceRequest willSendRequest(ResourceHandle*, ResourceRequest&&, ResourceResponse&& redirectResponse) override;
191     void didSendData(ResourceHandle*, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) override;
192     void didReceiveResponse(ResourceHandle*, ResourceResponse&&) override;
193     void didReceiveData(ResourceHandle*, const char*, unsigned, int encodedDataLength) override;
194     void didReceiveBuffer(ResourceHandle*, Ref<SharedBuffer>&&, int encodedDataLength) override;
195     void didFinishLoading(ResourceHandle*) override;
196     void didFail(ResourceHandle*, const ResourceError&) override;
197     void wasBlocked(ResourceHandle*) override;
198     void cannotShowURL(ResourceHandle*) override;
199 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
200     void didReceiveDataArray(ResourceHandle*, CFArrayRef dataArray) override;
201 #endif
202     bool shouldUseCredentialStorage(ResourceHandle*) override { return shouldUseCredentialStorage(); }
203     void didReceiveAuthenticationChallenge(ResourceHandle*, const AuthenticationChallenge& challenge) override { didReceiveAuthenticationChallenge(challenge); } 
204 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
205     bool canAuthenticateAgainstProtectionSpace(ResourceHandle*, const ProtectionSpace& protectionSpace) override { return canAuthenticateAgainstProtectionSpace(protectionSpace); }
206 #endif
207     void receivedCancellation(ResourceHandle*, const AuthenticationChallenge& challenge) override { receivedCancellation(challenge); }
208 #if PLATFORM(IOS)
209     RetainPtr<CFDictionaryRef> connectionProperties(ResourceHandle*) override;
210 #endif
211 #if PLATFORM(WIN) && USE(CFURLCONNECTION)
212     // FIXME: Windows should use willCacheResponse - <https://bugs.webkit.org/show_bug.cgi?id=57257>.
213     bool shouldCacheResponse(ResourceHandle*, CFCachedURLResponseRef) override;
214 #endif
215
216     ResourceRequest m_request;
217     ResourceRequest m_originalRequest; // Before redirects.
218     RefPtr<SharedBuffer> m_resourceData;
219     
220     unsigned long m_identifier { 0 };
221
222     bool m_reachedTerminalState { false };
223     bool m_notifiedLoadComplete { false };
224
225     enum CancellationStatus {
226         NotCancelled,
227         CalledWillCancel,
228         Cancelled,
229         FinishedCancel
230     };
231     CancellationStatus m_cancellationStatus { NotCancelled };
232
233     bool m_defersLoading;
234     ResourceRequest m_deferredRequest;
235     ResourceLoaderOptions m_options;
236
237 #if ENABLE(CONTENT_EXTENSIONS)
238 protected:
239     ResourceType m_resourceType { ResourceType::Invalid };
240 #endif
241 };
242
243 } // namespace WebCore