[WTF] Import std::optional reference implementation as WTF::Optional
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / NetworkDataTask.cpp
1 /*
2  * Copyright (C) 2016 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. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "NetworkDataTask.h"
28
29 #if USE(NETWORK_SESSION)
30
31 #include "NetworkDataTaskBlob.h"
32 #include "NetworkLoadParameters.h"
33 #include "NetworkSession.h"
34 #include <WebCore/ResourceError.h>
35 #include <WebCore/ResourceResponse.h>
36 #include <wtf/MainThread.h>
37
38 #if PLATFORM(COCOA)
39 #include "NetworkDataTaskCocoa.h"
40 #endif
41 #if USE(SOUP)
42 #include "NetworkDataTaskSoup.h"
43 #endif
44
45 using namespace WebCore;
46
47 namespace WebKit {
48
49 Ref<NetworkDataTask> NetworkDataTask::create(NetworkSession& session, NetworkDataTaskClient& client, const NetworkLoadParameters& parameters)
50 {
51     if (parameters.request.url().protocolIsBlob())
52         return NetworkDataTaskBlob::create(session, client, parameters.request, parameters.contentSniffingPolicy, parameters.blobFileReferences);
53
54 #if PLATFORM(COCOA)
55     return NetworkDataTaskCocoa::create(session, client, parameters.request, parameters.allowStoredCredentials, parameters.contentSniffingPolicy, parameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
56 #endif
57 #if USE(SOUP)
58     return NetworkDataTaskSoup::create(session, client, parameters.request, parameters.allowStoredCredentials, parameters.contentSniffingPolicy, parameters.shouldClearReferrerOnHTTPSToHTTPRedirect);
59 #endif
60 }
61
62 NetworkDataTask::NetworkDataTask(NetworkSession& session, NetworkDataTaskClient& client, const ResourceRequest& requestWithCredentials, StoredCredentials storedCredentials, bool shouldClearReferrerOnHTTPSToHTTPRedirect)
63     : m_failureTimer(*this, &NetworkDataTask::failureTimerFired)
64     , m_session(session)
65     , m_client(&client)
66     , m_storedCredentials(storedCredentials)
67     , m_lastHTTPMethod(requestWithCredentials.httpMethod())
68     , m_firstRequest(requestWithCredentials)
69     , m_shouldClearReferrerOnHTTPSToHTTPRedirect(shouldClearReferrerOnHTTPSToHTTPRedirect)
70 {
71     ASSERT(isMainThread());
72
73     if (!requestWithCredentials.url().isValid()) {
74         scheduleFailure(InvalidURLFailure);
75         return;
76     }
77
78     if (!portAllowed(requestWithCredentials.url())) {
79         scheduleFailure(BlockedFailure);
80         return;
81     }
82 }
83
84 NetworkDataTask::~NetworkDataTask()
85 {
86     ASSERT(isMainThread());
87     ASSERT(!m_client);
88 }
89
90 void NetworkDataTask::scheduleFailure(FailureType type)
91 {
92     ASSERT(type != NoFailure);
93     m_scheduledFailureType = type;
94     m_failureTimer.startOneShot(0);
95 }
96
97 void NetworkDataTask::didReceiveResponse(ResourceResponse&& response, ResponseCompletionHandler&& completionHandler)
98 {
99     ASSERT(m_client);
100     if (response.isHttpVersion0_9()) {
101         auto url = response.url();
102         std::optional<uint16_t> port = url.port();
103         if (port && !isDefaultPortForProtocol(port.value(), url.protocol())) {
104             cancel();
105             m_client->didCompleteWithError({ String(), 0, url, "Cancelled load from '" + url.stringCenterEllipsizedToLength() + "' because it is using HTTP/0.9." });
106             return;
107         }
108     }
109     m_client->didReceiveResponseNetworkSession(WTFMove(response), WTFMove(completionHandler));
110 }
111
112 void NetworkDataTask::failureTimerFired()
113 {
114     RefPtr<NetworkDataTask> protectedThis(this);
115
116     switch (m_scheduledFailureType) {
117     case BlockedFailure:
118         m_scheduledFailureType = NoFailure;
119         if (m_client)
120             m_client->wasBlocked();
121         return;
122     case InvalidURLFailure:
123         m_scheduledFailureType = NoFailure;
124         if (m_client)
125             m_client->cannotShowURL();
126         return;
127     case NoFailure:
128         ASSERT_NOT_REACHED();
129         break;
130     }
131     ASSERT_NOT_REACHED();
132 }
133
134 } // namespace WebKit
135
136 #endif // USE(NETWORK_SESSION)