Bug 1707290 [wpt PR 28671] - Auto-expand details elements for find-in-page, a=testonly
[gecko.git] / dom / network / TCPSocketParent.cpp
blobfd74659562c5081f7e19fa12384b185e27ae03c5
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 ErrorResult rv;
118 switch (aData.type()) {
119 case SendableData::TArrayOfuint8_t: {
120 AutoSafeJSContext autoCx;
121 JS::Rooted<JS::Value> val(autoCx);
122 const nsTArray<uint8_t>& buffer = aData.get_ArrayOfuint8_t();
123 bool ok = IPC::DeserializeArrayBuffer(autoCx, buffer, &val);
124 NS_ENSURE_TRUE(ok, IPC_OK());
125 RootedSpiderMonkeyInterface<ArrayBuffer> data(autoCx);
126 if (!data.Init(&val.toObject())) {
127 TCPSOCKET_LOG(("%s: Failed to allocate memory", __FUNCTION__));
128 return IPC_FAIL_NO_REASON(this);
130 Optional<uint32_t> byteLength(buffer.Length());
131 mSocket->Send(data, 0, byteLength, rv);
132 break;
135 case SendableData::TnsCString: {
136 const nsCString& strData = aData.get_nsCString();
137 mSocket->Send(strData, rv);
138 break;
141 default:
142 MOZ_CRASH("unexpected SendableData type");
144 NS_ENSURE_SUCCESS(rv.StealNSResult(), IPC_OK());
145 return IPC_OK();
148 mozilla::ipc::IPCResult TCPSocketParent::RecvClose() {
149 NS_ENSURE_TRUE(mSocket, IPC_OK());
150 mSocket->Close();
151 return IPC_OK();
154 void TCPSocketParent::FireErrorEvent(const nsAString& aName,
155 const nsAString& aType, nsresult aError,
156 TCPReadyState aReadyState) {
157 SendEvent(u"error"_ns, TCPError(nsString(aName), nsString(aType), aError),
158 aReadyState);
161 void TCPSocketParent::FireEvent(const nsAString& aType,
162 TCPReadyState aReadyState) {
163 return SendEvent(aType, mozilla::void_t(), aReadyState);
166 void TCPSocketParent::FireArrayBufferDataEvent(nsTArray<uint8_t>& aBuffer,
167 TCPReadyState aReadyState) {
168 nsTArray<uint8_t> arr = std::move(aBuffer);
170 SendableData data(arr);
171 SendEvent(u"data"_ns, data, aReadyState);
174 void TCPSocketParent::FireStringDataEvent(const nsACString& aData,
175 TCPReadyState aReadyState) {
176 SendableData data((nsCString(aData)));
178 SendEvent(u"data"_ns, data, aReadyState);
181 void TCPSocketParent::SendEvent(const nsAString& aType, CallbackData aData,
182 TCPReadyState aReadyState) {
183 if (mIPCOpen) {
184 mozilla::Unused << PTCPSocketParent::SendCallback(
185 nsString(aType), aData, static_cast<uint32_t>(aReadyState));
189 void TCPSocketParent::SetSocket(TCPSocket* socket) { mSocket = socket; }
191 nsresult TCPSocketParent::GetHost(nsAString& aHost) {
192 if (!mSocket) {
193 NS_ERROR("No internal socket instance mSocket!");
194 return NS_ERROR_FAILURE;
196 mSocket->GetHost(aHost);
197 return NS_OK;
200 nsresult TCPSocketParent::GetPort(uint16_t* aPort) {
201 if (!mSocket) {
202 NS_ERROR("No internal socket instance mSocket!");
203 return NS_ERROR_FAILURE;
205 *aPort = mSocket->Port();
206 return NS_OK;
209 void TCPSocketParent::ActorDestroy(ActorDestroyReason why) {
210 if (mSocket) {
211 mSocket->Close();
213 mSocket = nullptr;
216 mozilla::ipc::IPCResult TCPSocketParent::RecvRequestDelete() {
217 mozilla::Unused << Send__delete__(this);
218 return IPC_OK();
221 } // namespace dom
222 } // namespace mozilla