413dffb6fce7f22fe7106dfc49d472c76026824b
[WebKit-https.git] / Source / WebKit / WebProcess / Network / WebSocketStream.cpp
1 /*
2  * Copyright (C) 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. 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/SocketStreamError.h>
36 #include <WebCore/SocketStreamHandleClient.h>
37 #include <pal/SessionID.h>
38 #include <wtf/NeverDestroyed.h>
39
40 using namespace WebCore;
41
42 namespace WebKit {
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         stream->m_client.didFailSocketStream(*stream, SocketStreamError(0, { }, "Network process crashed."));
61     }
62
63     globalWebSocketStreamMap().clear();
64 }
65
66 Ref<WebSocketStream> WebSocketStream::create(const URL& url, SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& credentialPartition)
67 {
68     return adoptRef(*new WebSocketStream(url, client, sessionID, credentialPartition));
69 }
70
71 WebSocketStream::WebSocketStream(const WebCore::URL& url, WebCore::SocketStreamHandleClient& client, PAL::SessionID sessionID, const String& cachePartition)
72     : SocketStreamHandle(url, client)
73     , m_client(client)
74 {
75     WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::CreateSocketStream(url, sessionID, cachePartition, identifier()), 0);
76
77     ASSERT(!globalWebSocketStreamMap().contains(identifier()));
78     globalWebSocketStreamMap().set(identifier(), this);
79 }
80
81 WebSocketStream::~WebSocketStream()
82 {
83     ASSERT(globalWebSocketStreamMap().contains(identifier()));
84     globalWebSocketStreamMap().remove(identifier());
85 }
86
87 IPC::Connection* WebSocketStream::messageSenderConnection()
88 {
89     return &WebProcess::singleton().ensureNetworkProcessConnection().connection();
90 }
91
92 uint64_t WebSocketStream::messageSenderDestinationID()
93 {
94     return identifier();
95 }
96
97 void WebSocketStream::platformSend(const char* data, size_t length, Function<void(bool)>&& completionHandler)
98 {
99     static uint64_t nextDataIdentifier = 1;
100     uint64_t dataIdentifier = nextDataIdentifier++;
101     send(Messages::NetworkSocketStream::SendData(IPC::DataReference(reinterpret_cast<const uint8_t *>(data), length), dataIdentifier));
102     ASSERT(!m_sendDataCallbacks.contains(dataIdentifier));
103     m_sendDataCallbacks.set(dataIdentifier, WTFMove(completionHandler));
104 }
105
106 void WebSocketStream::didSendData(uint64_t identifier, bool success)
107 {
108     ASSERT(m_sendDataCallbacks.contains(identifier));
109     m_sendDataCallbacks.take(identifier)(success);
110 }
111     
112 void WebSocketStream::platformClose()
113 {
114     send(Messages::NetworkSocketStream::Close());
115 }
116
117 size_t WebSocketStream::bufferedAmount()
118 {
119     return m_bufferedAmount;
120 }
121
122 void WebSocketStream::didOpenSocketStream()
123 {
124     m_state = Open;
125     m_client.didOpenSocketStream(*this);
126 }
127
128 void WebSocketStream::didCloseSocketStream()
129 {
130     m_state = Closed;
131     m_client.didCloseSocketStream(*this);
132 }
133
134 void WebSocketStream::didReceiveSocketStreamData(const IPC::DataReference& data)
135 {
136     m_client.didReceiveSocketStreamData(*this, reinterpret_cast<const char*>(data.data()), data.size());
137 }
138
139 void WebSocketStream::didFailToReceiveSocketStreamData()
140 {
141     m_client.didFailToReceiveSocketStreamData(*this);
142 }
143
144 void WebSocketStream::didUpdateBufferedAmount(uint64_t newAmount)
145 {
146     m_bufferedAmount = newAmount;
147     m_client.didUpdateBufferedAmount(*this, newAmount);
148 }
149
150 void WebSocketStream::didFailSocketStream(WebCore::SocketStreamError&& error)
151 {
152     m_client.didFailSocketStream(*this, WTFMove(error));
153 }
154
155 } // namespace WebKit