#ifndef NetworkDataTask_h
#define NetworkDataTask_h
#include "SandboxExtension.h"
#include <WebCore/Credential.h>
#include <WebCore/FrameLoaderTypes.h>
#include <WebCore/ResourceHandleTypes.h>
#include <WebCore/ResourceLoaderOptions.h>
#include <WebCore/ResourceRequest.h>
#include <WebCore/Timer.h>
#include <wtf/Function.h>
#include <wtf/RetainPtr.h>
#include <wtf/text/WTFString.h>
#if PLATFORM(COCOA)
OBJC_CLASS NSURLSessionDataTask;
#endif
namespace WebCore {
class AuthenticationChallenge;
class Credential;
class ResourceError;
class ResourceRequest;
class ResourceResponse;
class SharedBuffer;
}
namespace WebKit {
class Download;
class NetworkSession;
class PendingDownload;
enum class AuthenticationChallengeDisposition {
UseCredential,
PerformDefaultHandling,
Cancel,
RejectProtectionSpace
};
typedef Function<void(const WebCore::ResourceRequest&)> RedirectCompletionHandler;
typedef Function<void(AuthenticationChallengeDisposition, const WebCore::Credential&)> ChallengeCompletionHandler;
typedef Function<void(WebCore::PolicyAction)> ResponseCompletionHandler;
class NetworkDataTaskClient {
public:
virtual void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&) = 0;
virtual void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&&) = 0;
virtual void didReceiveResponseNetworkSession(WebCore::ResourceResponse&&, ResponseCompletionHandler&&) = 0;
virtual void didReceiveData(Ref<WebCore::SharedBuffer>&&) = 0;
virtual void didCompleteWithError(const WebCore::ResourceError&) = 0;
virtual void didBecomeDownload() = 0;
virtual void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend) = 0;
virtual void wasBlocked() = 0;
virtual void cannotShowURL() = 0;
virtual ~NetworkDataTaskClient() { }
};
class NetworkDataTask : public RefCounted<NetworkDataTask> {
friend class NetworkSession;
public:
static Ref<NetworkDataTask> create(NetworkSession& session, NetworkDataTaskClient& client, const WebCore::ResourceRequest& request, WebCore::StoredCredentials storedCredentials, WebCore::ContentSniffingPolicy shouldContentSniff, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
{
return adoptRef(*new NetworkDataTask(session, client, request, storedCredentials, shouldContentSniff, shouldClearReferrerOnHTTPSToHTTPRedirect));
}
void suspend();
void cancel();
void resume();
typedef uint64_t TaskIdentifier;
~NetworkDataTask();
void didSendData(uint64_t totalBytesSent, uint64_t totalBytesExpectedToSend);
void didReceiveChallenge(const WebCore::AuthenticationChallenge&, ChallengeCompletionHandler&&);
void didCompleteWithError(const WebCore::ResourceError&);
void didReceiveResponse(WebCore::ResourceResponse&&, ResponseCompletionHandler&&);
void didReceiveData(Ref<WebCore::SharedBuffer>&&);
void didBecomeDownload();
NetworkDataTaskClient* client() const { return m_client; }
void clearClient() { m_client = nullptr; }
DownloadID pendingDownloadID() { return m_pendingDownloadID; }
PendingDownload* pendingDownload() { return m_pendingDownload; }
void setPendingDownloadID(DownloadID downloadID)
{
ASSERT(!m_pendingDownloadID.downloadID());
ASSERT(downloadID.downloadID());
m_pendingDownloadID = downloadID;
}
void setPendingDownload(PendingDownload& pendingDownload)
{
ASSERT(!m_pendingDownload);
m_pendingDownload = &pendingDownload;
}
void setPendingDownloadLocation(const String& filename, const SandboxExtension::Handle&);
const String& pendingDownloadLocation() { return m_pendingDownloadLocation; }
const WebCore::ResourceRequest& firstRequest() const { return m_firstRequest; }
WebCore::ResourceRequest currentRequest();
String suggestedFilename();
void willPerformHTTPRedirection(WebCore::ResourceResponse&&, WebCore::ResourceRequest&&, RedirectCompletionHandler&&);
void transferSandboxExtensionToDownload(Download&);
bool allowsSpecificHTTPSCertificateForHost(const WebCore::AuthenticationChallenge&);
private:
NetworkDataTask(NetworkSession&, NetworkDataTaskClient&, const WebCore::ResourceRequest&, WebCore::StoredCredentials, WebCore::ContentSniffingPolicy, bool shouldClearReferrerOnHTTPSToHTTPRedirect);
bool tryPasswordBasedAuthentication(const WebCore::AuthenticationChallenge&, const ChallengeCompletionHandler&);
enum FailureType {
NoFailure,
BlockedFailure,
InvalidURLFailure
};
FailureType m_scheduledFailureType { NoFailure };
WebCore::Timer m_failureTimer;
void failureTimerFired();
void scheduleFailure(FailureType);
RefPtr<NetworkSession> m_session;
NetworkDataTaskClient* m_client;
PendingDownload* m_pendingDownload { nullptr };
DownloadID m_pendingDownloadID;
String m_user;
String m_password;
#if USE(CREDENTIAL_STORAGE_WITH_NETWORK_SESSION)
WebCore::Credential m_initialCredential;
#endif
WebCore::StoredCredentials m_storedCredentials;
String m_lastHTTPMethod;
String m_pendingDownloadLocation;
WebCore::ResourceRequest m_firstRequest;
bool m_shouldClearReferrerOnHTTPSToHTTPRedirect;
RefPtr<SandboxExtension> m_sandboxExtension;
#if PLATFORM(COCOA)
RetainPtr<NSURLSessionDataTask> m_task;
#endif
};
#if PLATFORM(COCOA)
WebCore::Credential serverTrustCredential(const WebCore::AuthenticationChallenge&);
#endif
}
#endif