Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / network / TCPSocketParent.cpp
blobdc7bc3c5309265ba5bc998d545f861bbefde5488
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "TCPSocketParent.h"
8 #include "jsapi.h"
9 #include "jsfriendapi.h"
10 #include "nsJSUtils.h"
11 #include "mozilla/Unused.h"
12 #include "mozilla/net/NeckoCommon.h"
13 #include "mozilla/net/PNeckoParent.h"
14 #include "mozilla/dom/ScriptSettings.h"
15 #include "mozilla/dom/BrowserParent.h"
16 #include "mozilla/HoldDropJSObjects.h"
17 #include "nsISocketTransport.h"
18 #include "nsNetUtil.h"
19 #include "TCPSocket.h"
21 namespace IPC {
23 // Defined in TCPSocketChild.cpp
24 extern bool DeserializeArrayBuffer(JSContext* aCx,
25 const nsTArray<uint8_t>& aBuffer,
26 JS::MutableHandle<JS::Value> aVal);
28 } // namespace IPC
30 namespace mozilla {
32 namespace net {
34 // set MOZ_LOG=TCPSocket:5
36 extern LazyLogModule gTCPSocketLog;
37 #define TCPSOCKET_LOG(args) MOZ_LOG(gTCPSocketLog, LogLevel::Debug, args)
38 #define TCPSOCKET_LOG_ENABLED() MOZ_LOG_TEST(gTCPSocketLog, LogLevel::Debug)
39 } // namespace net
41 using namespace net;
43 namespace dom {
45 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPSocketParentBase)
46 NS_INTERFACE_MAP_ENTRY(nsISupports)
47 NS_INTERFACE_MAP_END
49 NS_IMPL_CYCLE_COLLECTION(TCPSocketParentBase, mSocket)
50 NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPSocketParentBase)
51 NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPSocketParentBase)
53 TCPSocketParentBase::TCPSocketParentBase() : mIPCOpen(false) {}
55 TCPSocketParentBase::~TCPSocketParentBase() = default;
57 void TCPSocketParentBase::ReleaseIPDLReference() {
58 MOZ_ASSERT(mIPCOpen);
59 mIPCOpen = false;
60 this->Release();
63 void TCPSocketParentBase::AddIPDLReference() {
64 MOZ_ASSERT(!mIPCOpen);
65 mIPCOpen = true;
66 this->AddRef();
69 NS_IMETHODIMP_(MozExternalRefCountType) TCPSocketParent::Release(void) {
70 nsrefcnt refcnt = TCPSocketParentBase::Release();
71 if (refcnt == 1 && mIPCOpen) {
72 mozilla::Unused << PTCPSocketParent::SendRequestDelete();
73 return 1;
75 return refcnt;
78 mozilla::ipc::IPCResult TCPSocketParent::RecvOpen(
79 const nsString& aHost, const uint16_t& aPort, const bool& aUseSSL,
80 const bool& aUseArrayBuffers) {
81 mSocket = new TCPSocket(nullptr, aHost, aPort, aUseSSL, aUseArrayBuffers);
82 mSocket->SetSocketBridgeParent(this);
83 NS_ENSURE_SUCCESS(mSocket->Init(nullptr), IPC_OK());
84 return IPC_OK();
87 mozilla::ipc::IPCResult TCPSocketParent::RecvStartTLS() {
88 NS_ENSURE_TRUE(mSocket, IPC_OK());
89 ErrorResult rv;
90 mSocket->UpgradeToSecure(rv);
91 if (NS_WARN_IF(rv.Failed())) {
92 rv.SuppressException();
95 return IPC_OK();
98 mozilla::ipc::IPCResult TCPSocketParent::RecvSuspend() {
99 NS_ENSURE_TRUE(mSocket, IPC_OK());
100 mSocket->Suspend();
101 return IPC_OK();
104 mozilla::ipc::IPCResult TCPSocketParent::RecvResume() {
105 NS_ENSURE_TRUE(mSocket, IPC_OK());
106 ErrorResult rv;
107 mSocket->Resume(rv);
108 if (NS_WARN_IF(rv.Failed())) {
109 rv.SuppressException();
112 return IPC_OK();
115 mozilla::ipc::IPCResult TCPSocketParent::RecvData(const SendableData& aData) {
116 NS_ENSURE_TRUE(mSocket, IPC_OK());
117 ErrorResult rv;
119 switch (aData.type()) {
120 case SendableData::TArrayOfuint8_t: {
121 AutoSafeJSContext autoCx;
122 JS::Rooted<JS::Value> val(autoCx);
123 const nsTArray<uint8_t>& buffer = aData.get_ArrayOfuint8_t();
124 bool ok = IPC::DeserializeArrayBuffer(autoCx, buffer, &val);
125 NS_ENSURE_TRUE(ok, IPC_OK());
126 RootedSpiderMonkeyInterface<ArrayBuffer> data(autoCx);
127 if (!data.Init(&val.toObject())) {
128 TCPSOCKET_LOG(("%s: Failed to allocate memory", __FUNCTION__));
129 return IPC_FAIL_NO_REASON(this);
131 Optional<uint32_t> byteLength(buffer.Length());
132 mSocket->Send(data, 0, byteLength, rv);
133 break;
136 case SendableData::TnsCString: {
137 const nsCString& strData = aData.get_nsCString();
138 mSocket->Send(strData, rv);
139 break;
142 default:
143 MOZ_CRASH("unexpected SendableData type");
145 NS_ENSURE_SUCCESS(rv.StealNSResult(), IPC_OK());
146 return IPC_OK();
149 mozilla::ipc::IPCResult TCPSocketParent::RecvClose() {
150 NS_ENSURE_TRUE(mSocket, IPC_OK());
151 mSocket->Close();
152 return IPC_OK();
155 void TCPSocketParent::FireErrorEvent(const nsAString& aName,
156 const nsAString& aType, nsresult aError,
157 TCPReadyState aReadyState) {
158 SendEvent(u"error"_ns, TCPError(nsString(aName), nsString(aType), aError),
159 aReadyState);
162 void TCPSocketParent::FireEvent(const nsAString& aType,
163 TCPReadyState aReadyState) {
164 return SendEvent(aType, mozilla::void_t(), aReadyState);
167 void TCPSocketParent::FireArrayBufferDataEvent(nsTArray<uint8_t>& aBuffer,
168 TCPReadyState aReadyState) {
169 nsTArray<uint8_t> arr = std::move(aBuffer);
171 SendableData data(arr);
172 SendEvent(u"data"_ns, data, aReadyState);
175 void TCPSocketParent::FireStringDataEvent(const nsACString& aData,
176 TCPReadyState aReadyState) {
177 SendableData data((nsCString(aData)));
179 SendEvent(u"data"_ns, data, aReadyState);
182 void TCPSocketParent::SendEvent(const nsAString& aType, CallbackData aData,
183 TCPReadyState aReadyState) {
184 if (mIPCOpen) {
185 mozilla::Unused << PTCPSocketParent::SendCallback(
186 nsString(aType), aData, static_cast<uint32_t>(aReadyState));
190 void TCPSocketParent::SetSocket(TCPSocket* socket) { mSocket = socket; }
192 nsresult TCPSocketParent::GetHost(nsAString& aHost) {
193 if (!mSocket) {
194 NS_ERROR("No internal socket instance mSocket!");
195 return NS_ERROR_FAILURE;
197 mSocket->GetHost(aHost);
198 return NS_OK;
201 nsresult TCPSocketParent::GetPort(uint16_t* aPort) {
202 if (!mSocket) {
203 NS_ERROR("No internal socket instance mSocket!");
204 return NS_ERROR_FAILURE;
206 *aPort = mSocket->Port();
207 return NS_OK;
210 void TCPSocketParent::ActorDestroy(ActorDestroyReason why) {
211 if (mSocket) {
212 mSocket->Close();
214 mSocket = nullptr;
217 mozilla::ipc::IPCResult TCPSocketParent::RecvRequestDelete() {
218 mozilla::Unused << Send__delete__(this);
219 return IPC_OK();
222 } // namespace dom
223 } // namespace mozilla