1 | /* |
2 | * Copyright (C) 2004-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 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #pragma once |
27 | |
28 | #include "AuthenticationClient.h" |
29 | #include "StoredCredentialsPolicy.h" |
30 | #include <wtf/MonotonicTime.h> |
31 | #include <wtf/RefCounted.h> |
32 | #include <wtf/RefPtr.h> |
33 | #include <wtf/text/AtomicString.h> |
34 | |
35 | #if PLATFORM(COCOA) || USE(CFURLCONNECTION) |
36 | #include <wtf/RetainPtr.h> |
37 | #endif |
38 | |
39 | #if USE(CURL) |
40 | #include "CurlResourceHandleDelegate.h" |
41 | #endif |
42 | |
43 | #if USE(CF) |
44 | typedef const struct __CFData * CFDataRef; |
45 | #endif |
46 | |
47 | #if PLATFORM(COCOA) |
48 | OBJC_CLASS NSCachedURLResponse; |
49 | OBJC_CLASS NSData; |
50 | OBJC_CLASS NSDictionary; |
51 | OBJC_CLASS NSError; |
52 | OBJC_CLASS NSURLConnection; |
53 | OBJC_CLASS NSURLRequest; |
54 | #ifndef __OBJC__ |
55 | typedef struct objc_object *id; |
56 | #endif |
57 | #endif |
58 | |
59 | #if USE(CFURLCONNECTION) |
60 | typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef; |
61 | typedef struct _CFURLConnection* CFURLConnectionRef; |
62 | typedef int CFHTTPCookieStorageAcceptPolicy; |
63 | typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef; |
64 | #endif |
65 | |
66 | #if PLATFORM(COCOA) || USE(CFURLCONNECTION) |
67 | typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; |
68 | #endif |
69 | |
70 | namespace WTF { |
71 | class SchedulePair; |
72 | template<typename T> class MessageQueue; |
73 | } |
74 | |
75 | namespace WebCore { |
76 | |
77 | class AuthenticationChallenge; |
78 | class Credential; |
79 | class Frame; |
80 | class NetworkingContext; |
81 | class ProtectionSpace; |
82 | class ResourceError; |
83 | class ResourceHandleClient; |
84 | class ResourceHandleInternal; |
85 | class NetworkLoadMetrics; |
86 | class ResourceRequest; |
87 | class ResourceResponse; |
88 | class SharedBuffer; |
89 | class Timer; |
90 | |
91 | #if USE(CURL) |
92 | class CurlRequest; |
93 | class CurlResourceHandleDelegate; |
94 | #endif |
95 | |
96 | class ResourceHandle : public RefCounted<ResourceHandle>, public AuthenticationClient { |
97 | public: |
98 | WEBCORE_EXPORT static RefPtr<ResourceHandle> create(NetworkingContext*, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff); |
99 | WEBCORE_EXPORT static void loadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data); |
100 | WEBCORE_EXPORT virtual ~ResourceHandle(); |
101 | |
102 | #if PLATFORM(COCOA) || USE(CFURLCONNECTION) |
103 | void willSendRequest(ResourceRequest&&, ResourceResponse&&, CompletionHandler<void(ResourceRequest&&)>&&); |
104 | #endif |
105 | |
106 | void didReceiveResponse(ResourceResponse&&, CompletionHandler<void()>&&); |
107 | |
108 | bool shouldUseCredentialStorage(); |
109 | void didReceiveAuthenticationChallenge(const AuthenticationChallenge&); |
110 | void receivedCredential(const AuthenticationChallenge&, const Credential&) override; |
111 | void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&) override; |
112 | void receivedCancellation(const AuthenticationChallenge&) override; |
113 | void receivedRequestToPerformDefaultHandling(const AuthenticationChallenge&) override; |
114 | void receivedChallengeRejection(const AuthenticationChallenge&) override; |
115 | |
116 | #if PLATFORM(COCOA) || USE(CFURLCONNECTION) |
117 | bool tryHandlePasswordBasedAuthentication(const AuthenticationChallenge&); |
118 | #endif |
119 | |
120 | #if PLATFORM(COCOA) && USE(PROTECTION_SPACE_AUTH_CALLBACK) |
121 | void canAuthenticateAgainstProtectionSpace(const ProtectionSpace&, CompletionHandler<void(bool)>&&); |
122 | #endif |
123 | |
124 | #if PLATFORM(COCOA) |
125 | WEBCORE_EXPORT NSURLConnection *connection() const; |
126 | id makeDelegate(bool, WTF::MessageQueue<WTF::Function<void()>>*); |
127 | id delegate(); |
128 | void releaseDelegate(); |
129 | #endif |
130 | |
131 | #if PLATFORM(COCOA) |
132 | #if USE(CFURLCONNECTION) |
133 | static void getConnectionTimingData(CFURLConnectionRef, NetworkLoadMetrics&); |
134 | #else |
135 | static void getConnectionTimingData(NSURLConnection *, NetworkLoadMetrics&); |
136 | #endif |
137 | #endif |
138 | |
139 | #if PLATFORM(COCOA) |
140 | void schedule(WTF::SchedulePair&); |
141 | void unschedule(WTF::SchedulePair&); |
142 | #endif |
143 | |
144 | #if USE(CFURLCONNECTION) |
145 | CFURLStorageSessionRef storageSession() const; |
146 | CFURLConnectionRef connection() const; |
147 | WEBCORE_EXPORT RetainPtr<CFURLConnectionRef> releaseConnectionForDownload(); |
148 | const ResourceRequest& currentRequest() const; |
149 | static void setHostAllowsAnyHTTPSCertificate(const String&); |
150 | static void setClientCertificate(const String& host, CFDataRef); |
151 | #endif |
152 | |
153 | #if OS(WINDOWS) && USE(CURL) |
154 | static void setHostAllowsAnyHTTPSCertificate(const String&); |
155 | static void setClientCertificateInfo(const String&, const String&, const String&); |
156 | #endif |
157 | |
158 | #if OS(WINDOWS) && USE(CURL) && USE(CF) |
159 | static void setClientCertificate(const String& host, CFDataRef); |
160 | #endif |
161 | |
162 | bool shouldContentSniff() const; |
163 | static bool shouldContentSniffURL(const URL&); |
164 | |
165 | bool shouldContentEncodingSniff() const; |
166 | |
167 | WEBCORE_EXPORT static void forceContentSniffing(); |
168 | |
169 | #if USE(CURL) |
170 | ResourceHandleInternal* getInternal() { return d.get(); } |
171 | #endif |
172 | |
173 | #if USE(CURL) |
174 | bool cancelledOrClientless(); |
175 | CurlResourceHandleDelegate* delegate(); |
176 | |
177 | void continueAfterDidReceiveResponse(); |
178 | void willSendRequest(); |
179 | void continueAfterWillSendRequest(ResourceRequest&&); |
180 | #endif |
181 | |
182 | bool hasAuthenticationChallenge() const; |
183 | void clearAuthentication(); |
184 | WEBCORE_EXPORT virtual void cancel(); |
185 | |
186 | // The client may be 0, in which case no callbacks will be made. |
187 | WEBCORE_EXPORT ResourceHandleClient* client() const; |
188 | WEBCORE_EXPORT void clearClient(); |
189 | |
190 | WEBCORE_EXPORT void setDefersLoading(bool); |
191 | |
192 | WEBCORE_EXPORT ResourceRequest& firstRequest(); |
193 | const String& lastHTTPMethod() const; |
194 | |
195 | void failureTimerFired(); |
196 | |
197 | NetworkingContext* context() const; |
198 | |
199 | using RefCounted<ResourceHandle>::ref; |
200 | using RefCounted<ResourceHandle>::deref; |
201 | |
202 | #if PLATFORM(COCOA) || USE(CFURLCONNECTION) |
203 | WEBCORE_EXPORT static CFStringRef synchronousLoadRunLoopMode(); |
204 | #endif |
205 | |
206 | typedef Ref<ResourceHandle> (*BuiltinConstructor)(const ResourceRequest& request, ResourceHandleClient* client); |
207 | static void registerBuiltinConstructor(const AtomicString& protocol, BuiltinConstructor); |
208 | |
209 | typedef void (*BuiltinSynchronousLoader)(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data); |
210 | static void registerBuiltinSynchronousLoader(const AtomicString& protocol, BuiltinSynchronousLoader); |
211 | |
212 | protected: |
213 | ResourceHandle(NetworkingContext*, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff); |
214 | |
215 | private: |
216 | enum FailureType { |
217 | NoFailure, |
218 | BlockedFailure, |
219 | InvalidURLFailure |
220 | }; |
221 | |
222 | void platformSetDefersLoading(bool); |
223 | |
224 | void platformContinueSynchronousDidReceiveResponse(); |
225 | |
226 | void scheduleFailure(FailureType); |
227 | |
228 | bool start(); |
229 | static void platformLoadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data); |
230 | |
231 | void refAuthenticationClient() override { ref(); } |
232 | void derefAuthenticationClient() override { deref(); } |
233 | |
234 | #if PLATFORM(COCOA) || USE(CFURLCONNECTION) |
235 | enum class SchedulingBehavior { Asynchronous, Synchronous }; |
236 | #endif |
237 | |
238 | #if USE(CFURLCONNECTION) |
239 | void createCFURLConnection(bool shouldUseCredentialStorage, bool shouldContentSniff, bool shouldContentEncodingSniff, WTF::MessageQueue<WTF::Function<void()>>*, CFDictionaryRef clientProperties); |
240 | #endif |
241 | |
242 | #if PLATFORM(MAC) |
243 | void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, bool shouldContentEncodingSniff, SchedulingBehavior); |
244 | #endif |
245 | |
246 | #if PLATFORM(IOS_FAMILY) |
247 | void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, bool shouldContentEncodingSniff, SchedulingBehavior, NSDictionary *connectionProperties); |
248 | #endif |
249 | |
250 | #if PLATFORM(COCOA) |
251 | NSURLRequest *applySniffingPoliciesIfNeeded(NSURLRequest *, bool shouldContentSniff, bool shouldContentEncodingSniff); |
252 | #endif |
253 | |
254 | #if USE(CURL) |
255 | enum class RequestStatus { |
256 | NewRequest, |
257 | ReusedRequest |
258 | }; |
259 | |
260 | void addCacheValidationHeaders(ResourceRequest&); |
261 | Ref<CurlRequest> createCurlRequest(ResourceRequest&&, RequestStatus = RequestStatus::NewRequest); |
262 | |
263 | bool shouldRedirectAsGET(const ResourceRequest&, bool crossOrigin); |
264 | |
265 | Optional<Credential> getCredential(const ResourceRequest&, bool); |
266 | void restartRequestWithCredential(const ProtectionSpace&, const Credential&); |
267 | |
268 | void handleDataURL(); |
269 | #endif |
270 | |
271 | friend class ResourceHandleInternal; |
272 | std::unique_ptr<ResourceHandleInternal> d; |
273 | }; |
274 | |
275 | } |
276 | |