2 * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
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>
35 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
36 #include <wtf/RetainPtr.h>
40 typedef struct _GTlsCertificate GTlsCertificate;
41 typedef struct _SoupSession SoupSession;
42 typedef struct _SoupRequest SoupRequest;
46 typedef const struct __CFData * CFDataRef;
50 OBJC_CLASS NSCachedURLResponse;
52 OBJC_CLASS NSDictionary;
54 OBJC_CLASS NSURLConnection;
55 OBJC_CLASS NSURLRequest;
57 typedef struct objc_object *id;
61 #if USE(CFURLCONNECTION)
62 typedef const struct _CFCachedURLResponse* CFCachedURLResponseRef;
63 typedef struct _CFURLConnection* CFURLConnectionRef;
64 typedef int CFHTTPCookieStorageAcceptPolicy;
65 typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef;
68 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
69 typedef const struct __CFURLStorageSession* CFURLStorageSessionRef;
74 template<typename T> class MessageQueue;
79 class AuthenticationChallenge;
83 class NetworkingContext;
84 class ProtectionSpace;
86 class ResourceHandleClient;
87 class ResourceHandleInternal;
88 class NetworkLoadMetrics;
89 class ResourceRequest;
90 class ResourceResponse;
91 class SoupNetworkSession;
95 class ResourceHandle : public RefCounted<ResourceHandle>, public AuthenticationClient {
97 WEBCORE_EXPORT static RefPtr<ResourceHandle> create(NetworkingContext*, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff);
98 WEBCORE_EXPORT static void loadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data);
101 static RefPtr<ResourceHandle> create(SoupNetworkSession&, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff);
104 WEBCORE_EXPORT virtual ~ResourceHandle();
106 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
107 void willSendRequest(ResourceRequest&&, ResourceResponse&&, CompletionHandler<void(ResourceRequest&&)>&&);
110 void didReceiveResponse(ResourceResponse&&);
112 bool shouldUseCredentialStorage();
113 void didReceiveAuthenticationChallenge(const AuthenticationChallenge&);
114 void receivedCredential(const AuthenticationChallenge&, const Credential&) override;
115 void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&) override;
116 void receivedCancellation(const AuthenticationChallenge&) override;
117 void receivedRequestToPerformDefaultHandling(const AuthenticationChallenge&) override;
118 void receivedChallengeRejection(const AuthenticationChallenge&) override;
120 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
121 bool tryHandlePasswordBasedAuthentication(const AuthenticationChallenge&);
124 #if PLATFORM(COCOA) && USE(PROTECTION_SPACE_AUTH_CALLBACK)
125 bool canAuthenticateAgainstProtectionSpace(const ProtectionSpace&);
128 #if PLATFORM(COCOA) && !USE(CFURLCONNECTION)
129 WEBCORE_EXPORT NSURLConnection *connection() const;
130 id makeDelegate(bool, WTF::MessageQueue<WTF::Function<void()>>*);
132 void releaseDelegate();
136 #if USE(CFURLCONNECTION)
137 static void getConnectionTimingData(CFURLConnectionRef, NetworkLoadMetrics&);
139 static void getConnectionTimingData(NSURLConnection *, NetworkLoadMetrics&);
144 void schedule(WTF::SchedulePair&);
145 void unschedule(WTF::SchedulePair&);
148 #if USE(CFURLCONNECTION)
149 CFURLStorageSessionRef storageSession() const;
150 CFURLConnectionRef connection() const;
151 WEBCORE_EXPORT RetainPtr<CFURLConnectionRef> releaseConnectionForDownload();
152 const ResourceRequest& currentRequest() const;
153 static void setHostAllowsAnyHTTPSCertificate(const String&);
154 static void setClientCertificate(const String& host, CFDataRef);
157 #if OS(WINDOWS) && USE(CURL)
158 static void setHostAllowsAnyHTTPSCertificate(const String&);
159 static void setClientCertificateInfo(const String&, const String&, const String&);
162 #if OS(WINDOWS) && USE(CURL) && USE(CF)
163 static void setClientCertificate(const String& host, CFDataRef);
166 bool shouldContentSniff() const;
167 static bool shouldContentSniffURL(const URL&);
169 bool shouldContentEncodingSniff() const;
171 WEBCORE_EXPORT static void forceContentSniffing();
173 #if USE(CURL) || USE(SOUP)
174 ResourceHandleInternal* getInternal() { return d.get(); }
178 RefPtr<ResourceHandle> releaseForDownload(ResourceHandleClient*);
179 void continueDidReceiveAuthenticationChallenge(const Credential& credentialFromPersistentStorage);
180 void sendPendingRequest();
181 bool cancelledOrClientless();
182 void ensureReadBuffer();
183 size_t currentStreamPosition() const;
184 void didStartRequest();
185 MonotonicTime m_requestTime;
188 bool hasAuthenticationChallenge() const;
189 void clearAuthentication();
190 WEBCORE_EXPORT virtual void cancel();
192 // The client may be 0, in which case no callbacks will be made.
193 WEBCORE_EXPORT ResourceHandleClient* client() const;
194 WEBCORE_EXPORT void clearClient();
196 // Called in response to ResourceHandleClient::didReceiveResponseAsync().
197 WEBCORE_EXPORT virtual void continueDidReceiveResponse();
199 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
200 // Called in response to ResourceHandleClient::canAuthenticateAgainstProtectionSpaceAsync().
201 WEBCORE_EXPORT void continueCanAuthenticateAgainstProtectionSpace(bool);
204 // Called in response to ResourceHandleClient::willCacheResponseAsync().
205 #if USE(CFURLCONNECTION)
206 WEBCORE_EXPORT void continueWillCacheResponse(CFCachedURLResponseRef);
208 #if PLATFORM(COCOA) && !USE(CFURLCONNECTION)
209 WEBCORE_EXPORT void continueWillCacheResponse(NSCachedURLResponse *);
212 WEBCORE_EXPORT void setDefersLoading(bool);
214 WEBCORE_EXPORT ResourceRequest& firstRequest();
215 const String& lastHTTPMethod() const;
217 void failureTimerFired();
219 NetworkingContext* context() const;
221 using RefCounted<ResourceHandle>::ref;
222 using RefCounted<ResourceHandle>::deref;
224 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
225 WEBCORE_EXPORT static CFStringRef synchronousLoadRunLoopMode();
228 #if PLATFORM(IOS) && USE(CFURLCONNECTION)
229 static CFMutableDictionaryRef createSSLPropertiesFromNSURLRequest(const ResourceRequest&);
232 typedef Ref<ResourceHandle> (*BuiltinConstructor)(const ResourceRequest& request, ResourceHandleClient* client);
233 static void registerBuiltinConstructor(const AtomicString& protocol, BuiltinConstructor);
235 typedef void (*BuiltinSynchronousLoader)(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data);
236 static void registerBuiltinSynchronousLoader(const AtomicString& protocol, BuiltinSynchronousLoader);
239 ResourceHandle(NetworkingContext*, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff);
249 ResourceHandle(SoupNetworkSession&, const ResourceRequest&, ResourceHandleClient*, bool defersLoading, bool shouldContentSniff, bool shouldContentEncodingSniff);
252 void platformSetDefersLoading(bool);
254 void platformContinueSynchronousDidReceiveResponse();
256 void scheduleFailure(FailureType);
259 static void platformLoadResourceSynchronously(NetworkingContext*, const ResourceRequest&, StoredCredentialsPolicy, ResourceError&, ResourceResponse&, Vector<char>& data);
261 void refAuthenticationClient() override { ref(); }
262 void derefAuthenticationClient() override { deref(); }
264 #if PLATFORM(COCOA) || USE(CFURLCONNECTION)
265 enum class SchedulingBehavior { Asynchronous, Synchronous };
268 #if USE(CFURLCONNECTION)
269 void createCFURLConnection(bool shouldUseCredentialStorage, bool shouldContentSniff, bool shouldContentEncodingSniff, WTF::MessageQueue<WTF::Function<void()>>*, CFDictionaryRef clientProperties);
272 #if PLATFORM(MAC) && !USE(CFURLCONNECTION)
273 void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, bool shouldContentEncodingSniff, SchedulingBehavior);
276 #if PLATFORM(IOS) && !USE(CFURLCONNECTION)
277 void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff, bool shouldContentEncodingSniff, SchedulingBehavior, NSDictionary *connectionProperties);
281 void applySniffingPoliciesAndStoragePartitionIfNeeded(NSURLRequest*&, bool shouldContentSniff, bool shouldContentEncodingSniff);
288 friend class ResourceHandleInternal;
289 std::unique_ptr<ResourceHandleInternal> d;