Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / network / TCPServerSocket.cpp
blobb39cad0e1464c927305adeb1f8808e3457d366bd
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 "mozilla/dom/TCPServerSocketBinding.h"
8 #include "mozilla/dom/TCPServerSocketEvent.h"
9 #include "mozilla/dom/TCPSocketBinding.h"
10 #include "TCPServerSocketParent.h"
11 #include "TCPServerSocketChild.h"
12 #include "mozilla/dom/Event.h"
13 #include "mozilla/ErrorResult.h"
14 #include "TCPServerSocket.h"
15 #include "TCPSocket.h"
16 #include "nsComponentManagerUtils.h"
18 using namespace mozilla::dom;
20 NS_IMPL_CYCLE_COLLECTION_CLASS(TCPServerSocket)
22 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(TCPServerSocket,
23 DOMEventTargetHelper)
24 NS_IMPL_CYCLE_COLLECTION_TRACE_END
26 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TCPServerSocket,
27 DOMEventTargetHelper)
28 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServerSocket)
29 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServerBridgeChild)
30 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServerBridgeParent)
31 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
33 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TCPServerSocket,
34 DOMEventTargetHelper)
35 NS_IMPL_CYCLE_COLLECTION_UNLINK(mServerSocket)
36 NS_IMPL_CYCLE_COLLECTION_UNLINK(mServerBridgeChild)
37 NS_IMPL_CYCLE_COLLECTION_UNLINK(mServerBridgeParent)
38 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
40 NS_IMPL_ADDREF_INHERITED(TCPServerSocket, DOMEventTargetHelper)
41 NS_IMPL_RELEASE_INHERITED(TCPServerSocket, DOMEventTargetHelper)
43 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPServerSocket)
44 NS_INTERFACE_MAP_ENTRY(nsIServerSocketListener)
45 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
47 TCPServerSocket::TCPServerSocket(nsIGlobalObject* aGlobal, uint16_t aPort,
48 bool aUseArrayBuffers, uint16_t aBacklog)
49 : DOMEventTargetHelper(aGlobal),
50 mPort(aPort),
51 mBacklog(aBacklog),
52 mUseArrayBuffers(aUseArrayBuffers) {}
54 TCPServerSocket::~TCPServerSocket() = default;
56 nsresult TCPServerSocket::Init() {
57 if (mServerSocket || mServerBridgeChild) {
58 NS_WARNING("Child TCPServerSocket is already listening.");
59 return NS_ERROR_FAILURE;
62 if (XRE_GetProcessType() == GeckoProcessType_Content) {
63 mServerBridgeChild =
64 new TCPServerSocketChild(this, mPort, mBacklog, mUseArrayBuffers);
65 return NS_OK;
68 nsresult rv;
69 mServerSocket =
70 do_CreateInstance("@mozilla.org/network/server-socket;1", &rv);
71 NS_ENSURE_SUCCESS(rv, rv);
72 rv = mServerSocket->Init(mPort, false, mBacklog);
73 NS_ENSURE_SUCCESS(rv, rv);
74 rv = mServerSocket->GetPort(&mPort);
75 NS_ENSURE_SUCCESS(rv, rv);
76 rv = mServerSocket->AsyncListen(this);
77 NS_ENSURE_SUCCESS(rv, rv);
78 return NS_OK;
81 already_AddRefed<TCPServerSocket> TCPServerSocket::Constructor(
82 const GlobalObject& aGlobal, uint16_t aPort,
83 const ServerSocketOptions& aOptions, uint16_t aBacklog,
84 mozilla::ErrorResult& aRv) {
85 nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
86 if (!global) {
87 aRv = NS_ERROR_FAILURE;
88 return nullptr;
90 bool useArrayBuffers =
91 aOptions.mBinaryType == TCPSocketBinaryType::Arraybuffer;
92 RefPtr<TCPServerSocket> socket =
93 new TCPServerSocket(global, aPort, useArrayBuffers, aBacklog);
94 nsresult rv = socket->Init();
95 if (NS_WARN_IF(NS_FAILED(rv))) {
96 aRv = NS_ERROR_FAILURE;
97 return nullptr;
99 return socket.forget();
102 uint16_t TCPServerSocket::LocalPort() const { return mPort; }
104 void TCPServerSocket::Close() {
105 if (mServerBridgeChild) {
106 mServerBridgeChild->Close();
108 if (mServerSocket) {
109 mServerSocket->Close();
113 void TCPServerSocket::FireEvent(const nsAString& aType, TCPSocket* aSocket) {
114 TCPServerSocketEventInit init;
115 init.mBubbles = false;
116 init.mCancelable = false;
117 init.mSocket = aSocket;
119 RefPtr<TCPServerSocketEvent> event =
120 TCPServerSocketEvent::Constructor(this, aType, init);
121 event->SetTrusted(true);
122 DispatchEvent(*event);
124 if (mServerBridgeParent) {
125 mServerBridgeParent->OnConnect(event);
129 NS_IMETHODIMP
130 TCPServerSocket::OnSocketAccepted(nsIServerSocket* aServer,
131 nsISocketTransport* aTransport) {
132 nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal();
133 RefPtr<TCPSocket> socket =
134 TCPSocket::CreateAcceptedSocket(global, aTransport, mUseArrayBuffers);
135 FireEvent(u"connect"_ns, socket);
136 return NS_OK;
139 NS_IMETHODIMP
140 TCPServerSocket::OnStopListening(nsIServerSocket* aServer, nsresult aStatus) {
141 if (aStatus != NS_BINDING_ABORTED) {
142 RefPtr<Event> event = new Event(GetOwner());
143 event->InitEvent(u"error"_ns, false, false);
144 event->SetTrusted(true);
145 DispatchEvent(*event);
147 NS_WARNING("Server socket was closed by unexpected reason.");
148 return NS_ERROR_FAILURE;
150 mServerSocket = nullptr;
151 return NS_OK;
154 nsresult TCPServerSocket::AcceptChildSocket(TCPSocketChild* aSocketChild) {
155 nsCOMPtr<nsIGlobalObject> global = GetOwnerGlobal();
156 NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
157 RefPtr<TCPSocket> socket =
158 TCPSocket::CreateAcceptedSocket(global, aSocketChild, mUseArrayBuffers);
159 NS_ENSURE_TRUE(socket, NS_ERROR_FAILURE);
160 FireEvent(u"connect"_ns, socket);
161 return NS_OK;
164 void TCPServerSocket::SetServerBridgeParent(
165 TCPServerSocketParent* aBridgeParent) {
166 mServerBridgeParent = aBridgeParent;
169 JSObject* TCPServerSocket::WrapObject(JSContext* aCx,
170 JS::Handle<JSObject*> aGivenProto) {
171 return TCPServerSocket_Binding::Wrap(aCx, this, aGivenProto);