Move URL from WebCore to WTF
[WebKit-https.git] / Source / WebKit / WebProcess / Network / WebSocketStream.cpp
1 /*
2  * Copyright (C) 2017-2018 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 "WebSocketStream.h"
28
29 #include "DataReference.h"
30 #include "NetworkConnectionToWebProcessMessages.h"
31 #include "NetworkProcessConnection.h"
32 #include "NetworkSocketStreamMessages.h"
33 #include "WebCoreArgumentCoders.h"
34 #include "WebProcess.h"
35 #include <WebCore/CookieRequestHeaderFieldProxy.h>
36 #include <WebCore/SocketStreamError.h>
37 #include <WebCore/SocketStreamHandleClient.h>
38 #include <pal/SessionID.h>
39 #include <wtf/NeverDestroyed.h>
40
41 namespace WebKit {
42 using namespace WebCore;
43
44 static HashMap<uint64_t, WebSocketStream*>& globalWebSocketStreamMap()
45 {
46     static NeverDestroyed<HashMap<uint64_t, WebSocketStream*>> globalMap;
47     return globalMap;
48 }
49
50 WebSocketStream* WebSocketStream::streamWithIdentifier(uint64_t identifier)
51 {
52     return globalWebSocketStreamMap().get(identifier);
53 }
54
55 void WebSocketStream::networkProcessCrashed()
56 {
57     for (auto& stream : globalWebSocketStreamMap().values()) {
58         for (auto& callback : stream->m_sendDataCallbacks.values())
59             callback(false);
60         for (auto& callback : stream->m_sendHandshakeCallbacks.values())
61             callback(false, false);
62         stream->m_client.didFailSocketStream(*stream, SocketStreamError(0, { }, "Network process crashed."));
63     }
64
65     globalWebSocketStreamMap().clear();
66 }
67
68 Ref<WebSocketStream> WebSocketStream::create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& credentialPartition)
69 {
70     return adoptRef(*new WebSocketStream(url, client, sessionID, credentialPartition));
71 }
72
73 WebSocketStream::WebSocketStream(const URL& url, WebCore::SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& cachePartition)
74     : SocketStreamHandle(url, client)
75     , m_client(client)
76 {
77     WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::CreateSocketStream(url, sessionID, cachePartition, identifier()), 0);
78
79     ASSERT(!globalWebSocketStreamMap().contains(identifier()));
80     globalWebSocketStreamMap().set(identifier(), this);
81 }
82
83 WebSocketStream::~WebSocketStream()
84 {
85     ASSERT(globalWebSocketStreamMap().contains(identifier()));
86     globalWebSocketStreamMap().remove(identifier());
87 }
88
89 IPC::Connection* WebSocketStream::messageSenderConnection()
90 {
91     return &WebProcess::singleton().ensureNetworkProcessConnection().connection();
92 }
93
94 uint64_t WebSocketStream::messageSenderDestinationID()
95 {
96     return identifier();
97 }
98
99 void WebSocketStream::platformSend(const uint8_t* data, size_t length, Function<void(bool)>&& completionHandler)
100 {
101     static uint64_t nextDataIdentifier = 1;
102     uint64_t dataIdentifier = nextDataIdentifier++;
103     send(Messages::NetworkSocketStream::SendData(IPC::DataReference(data, length), dataIdentifier));
104     ASSERT(!m_sendDataCallbacks.contains(dataIdentifier));
105     m_sendDataCallbacks.add(dataIdentifier, WTFMove(completionHandler));
106 }
107
108 void WebSocketStream::platformSendHandshake(const uint8_t* data, size_t length, const std::optional<CookieRequestHeaderFieldProxy>& headerFieldProxy, Function<void(bool, bool)>&& completionHandler)
109 {
110     static uint64_t nextDataIdentifier = 1;
111     uint64_t dataIdentifier = nextDataIdentifier++;
112     send(Messages::NetworkSocketStream::SendHandshake(IPC::DataReference(data, length), headerFieldProxy, dataIdentifier));
113     ASSERT(!m_sendHandshakeCallbacks.contains(dataIdentifier));
114     m_sendHandshakeCallbacks.add(dataIdentifier, WTFMove(completionHandler));
115 }
116
117 void WebSocketStream::didSendData(uint64_t identifier, bool success)
118 {
119     ASSERT(m_sendDataCallbacks.contains(identifier));
120     m_sendDataCallbacks.take(identifier)(success);
121 }
122
123 void WebSocketStream::didSendHandshake(uint64_t identifier, bool success, bool didAccessSecureCookies)
124 {
125     ASSERT(m_sendHandshakeCallbacks.contains(identifier));
126     m_sendHandshakeCallbacks.take(identifier)(success, didAccessSecureCookies);
127 }
128
129 void WebSocketStream::platformClose()
130 {
131     send(Messages::NetworkSocketStream::Close());
132 }
133
134 size_t WebSocketStream::bufferedAmount()
135 {
136     return m_bufferedAmount;
137 }
138
139 void WebSocketStream::didOpenSocketStream()
140 {
141     m_state = Open;
142     m_client.didOpenSocketStream(*this);
143 }
144
145 void WebSocketStream::didCloseSocketStream()
146 {
147     m_state = Closed;
148     m_client.didCloseSocketStream(*this);
149 }
150
151 void WebSocketStream::didReceiveSocketStreamData(const IPC::DataReference& data)
152 {
153     m_client.didReceiveSocketStreamData(*this, reinterpret_cast<const char*>(data.data()), data.size());
154 }
155
156 void WebSocketStream::didFailToReceiveSocketStreamData()
157 {
158     m_client.didFailToReceiveSocketStreamData(*this);
159 }
160
161 void WebSocketStream::didUpdateBufferedAmount(uint64_t newAmount)
162 {
163     m_bufferedAmount = newAmount;
164     m_client.didUpdateBufferedAmount(*this, newAmount);
165 }
166
167 void WebSocketStream::didFailSocketStream(WebCore::SocketStreamError&& error)
168 {
169     m_client.didFailSocketStream(*this, WTFMove(error));
170 }
171
172 } // namespace WebKit