[WTF] Add makeUnique<T>, which ensures T is fast-allocated, makeUnique / makeUniqueWi...
[WebKit-https.git] / Source / WebKit / NetworkProcess / NetworkSocketChannel.cpp
1 /*
2  * Copyright (C) 2019 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 "NetworkSocketChannel.h"
28
29 #include "DataReference.h"
30 #include "NetworkConnectionToWebProcess.h"
31 #include "NetworkProcess.h"
32 #include "NetworkSession.h"
33 #include "WebSocketChannelMessages.h"
34 #include "WebSocketTask.h"
35
36 namespace WebKit {
37 using namespace WebCore;
38
39 std::unique_ptr<NetworkSocketChannel> NetworkSocketChannel::create(NetworkConnectionToWebProcess& connection, PAL::SessionID sessionID, const ResourceRequest& request, const String& protocol, uint64_t identifier)
40 {
41     auto result = makeUnique<NetworkSocketChannel>(connection, connection.networkProcess().networkSession(sessionID), request, protocol, identifier);
42     if (!result->m_socket) {
43         result->didClose(0, "Cannot create a web socket task"_s);
44         return nullptr;
45     }
46     return result;
47 }
48
49 NetworkSocketChannel::NetworkSocketChannel(NetworkConnectionToWebProcess& connection, NetworkSession* session, const ResourceRequest& request, const String& protocol, uint64_t identifier)
50     : m_connectionToWebProcess(connection)
51     , m_identifier(identifier)
52     , m_session(makeWeakPtr(session))
53 {
54     if (!m_session)
55         return;
56
57     m_socket = m_session->createWebSocketTask(*this, request, protocol);
58     if (m_socket) {
59         m_session->addWebSocketTask(*m_socket);
60         m_socket->resume();
61     }
62 }
63
64 NetworkSocketChannel::~NetworkSocketChannel()
65 {
66     if (m_session)
67         m_session->removeWebSocketTask(*m_socket);
68
69     if (m_socket)
70         m_socket->cancel();
71 }
72
73 void NetworkSocketChannel::sendString(const String& message, CompletionHandler<void()>&& callback)
74 {
75     m_socket->sendString(message, WTFMove(callback));
76 }
77
78 void NetworkSocketChannel::sendData(const IPC::DataReference& data, CompletionHandler<void()>&& callback)
79 {
80     m_socket->sendData(data, WTFMove(callback));
81 }
82
83 void NetworkSocketChannel::finishClosingIfPossible()
84 {
85     if (m_state == State::Open) {
86         m_state = State::Closing;
87         return;
88     }
89     ASSERT(m_state == State::Closing);
90     m_state = State::Closed;
91     m_connectionToWebProcess.removeSocketChannel(m_identifier);
92 }
93
94 void NetworkSocketChannel::close(int32_t code, const String& reason)
95 {
96     m_socket->close(code, reason);
97     finishClosingIfPossible();
98 }
99
100 void NetworkSocketChannel::didConnect(const String& subprotocol, const String& extensions)
101 {
102     send(Messages::WebSocketChannel::DidConnect { subprotocol, extensions });
103 }
104
105 void NetworkSocketChannel::didReceiveText(const String& text)
106 {
107     send(Messages::WebSocketChannel::DidReceiveText { text });
108 }
109
110 void NetworkSocketChannel::didReceiveBinaryData(const uint8_t* data, size_t length)
111 {
112     send(Messages::WebSocketChannel::DidReceiveBinaryData { { data, length } });
113 }
114
115 void NetworkSocketChannel::didClose(unsigned short code, const String& reason)
116 {
117     send(Messages::WebSocketChannel::DidClose { code, reason });
118     finishClosingIfPossible();
119 }
120
121 void NetworkSocketChannel::didReceiveMessageError(const String& errorMessage)
122 {
123     send(Messages::WebSocketChannel::DidReceiveMessageError { errorMessage });
124 }
125
126 IPC::Connection* NetworkSocketChannel::messageSenderConnection() const
127 {
128     return &m_connectionToWebProcess.connection();
129 }
130
131 } // namespace WebKit