From ce638de3d6677c7d07545f39e77834ed54abd278 Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Sun, 20 Sep 2015 23:05:20 -0400 Subject: [PATCH] Bug 950660: Part 2 - Change TCPSocket interface to TCPSocketChild and unbitrot r=jdm --- dom/network/PTCPSocket.ipdl | 2 +- dom/network/TCPSocket.cpp | 82 +++++++++++++++++++++++++-------- dom/network/TCPSocket.h | 6 +++ dom/network/TCPSocketChild.cpp | 38 +++------------ dom/network/TCPSocketChild.h | 15 ++++++ dom/network/TCPSocketParent.cpp | 10 ++-- dom/network/TCPSocketParent.h | 2 +- 7 files changed, 100 insertions(+), 55 deletions(-) diff --git a/dom/network/PTCPSocket.ipdl b/dom/network/PTCPSocket.ipdl index cc44b0d18df..ced62c895cd 100644 --- a/dom/network/PTCPSocket.ipdl +++ b/dom/network/PTCPSocket.ipdl @@ -45,7 +45,7 @@ parent: // address specified in |localAddr| and |localPort|. OpenBind(nsCString host, uint16_t port, nsCString localAddr, uint16_t localPort, - bool useSSL, nsCString binaryType); + bool useSSL, bool aUseArrayBuffers); // When child's send() is called, this message requrests parent to send // data and update it's trackingNumber. diff --git a/dom/network/TCPSocket.cpp b/dom/network/TCPSocket.cpp index d6e9365c6c8..c07afe1f2ba 100644 --- a/dom/network/TCPSocket.cpp +++ b/dom/network/TCPSocket.cpp @@ -167,12 +167,14 @@ TCPSocket::TCPSocket(nsIGlobalObject* aGlobal, const nsAString& aHost, uint16_t , mInBrowser(false) #endif { - nsCOMPtr window = do_QueryInterface(aGlobal); - if (window && window->IsOuterWindow()) { - window = window->GetCurrentInnerWindow(); - } - if (window) { - mInnerWindowID = window->WindowID(); + if (aGlobal) { + nsCOMPtr window = do_QueryInterface(aGlobal); + if (window && window->IsOuterWindow()) { + window = window->GetCurrentInnerWindow(); + } + if (window) { + mInnerWindowID = window->WindowID(); + } } } @@ -234,6 +236,24 @@ TCPSocket::CreateStream() return NS_OK; } +nsresult +TCPSocket::InitWithUnconnectedTransport(nsISocketTransport* aTransport) +{ + mReadyState = TCPReadyState::Connecting; + mTransport = aTransport; + + MOZ_ASSERT(XRE_GetProcessType() != GeckoProcessType_Content); + + nsCOMPtr mainThread; + NS_GetMainThread(getter_AddRefs(mainThread)); + mTransport->SetEventSink(this, mainThread); + + nsresult rv = CreateStream(); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + nsresult TCPSocket::Init() { @@ -242,9 +262,8 @@ TCPSocket::Init() obs->AddObserver(this, "inner-window-destroyed", true); } - mReadyState = TCPReadyState::Connecting; - if (XRE_GetProcessType() == GeckoProcessType_Content) { + mReadyState = TCPReadyState::Connecting; mSocketBridgeChild = new TCPSocketChild(mHost, mPort); mSocketBridgeChild->SendOpen(this, mSsl, mUseArrayBuffers); return NS_OK; @@ -259,19 +278,12 @@ TCPSocket::Init() } else { socketTypes[0] = "starttls"; } + nsCOMPtr transport; nsresult rv = sts->CreateTransport(socketTypes, 1, NS_ConvertUTF16toUTF8(mHost), mPort, - nullptr, getter_AddRefs(mTransport)); + nullptr, getter_AddRefs(transport)); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr mainThread; - NS_GetMainThread(getter_AddRefs(mainThread)); - - mTransport->SetEventSink(this, mainThread); - - rv = CreateStream(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; + return InitWithUnconnectedTransport(transport); } void @@ -485,6 +497,40 @@ TCPSocket::FireEvent(const nsAString& aType) FireDataEvent(api.cx(), aType, val); } +void +TCPSocket::FireDataEvent(const nsAString& aType, + const InfallibleTArray& buffer) +{ + AutoJSAPI api; + if (NS_WARN_IF(!api.Init(GetOwner()))) { + return NS_ERROR_FAILURE; + } + JSContext* cx = api.cx(); + JS::Rooted val(cx); + + bool ok = IPC::DeserializeArrayBuffer(cx, buffer, &val); + if (ok) { + FireDataEvent(aType, val); + } +} + +void +TCPSocket::FireDataEvent(const nsAString& aType, + const nsACString& aString) +{ + AutoJSAPI api; + if (NS_WARN_IF(!api.Init(GetOwner()))) { + return NS_ERROR_FAILURE; + } + JSContext* cx = api.cx(); + JS::Rooted val(cx); + + bool ok = ToJSValue(cx, NS_ConvertASCIItoUTF16(aString), &val); + if (ok) { + FireDataEvent(aType, val); + } +} + void TCPSocket::FireDataEvent(JSContext* aCx, const nsAString& aType, JS::Handle aData) { diff --git a/dom/network/TCPSocket.h b/dom/network/TCPSocket.h index 1f262d97081..0c5f1ddd8f2 100644 --- a/dom/network/TCPSocket.h +++ b/dom/network/TCPSocket.h @@ -164,8 +164,14 @@ public: // Dispatch an event of the given type at this object. void FireEvent(const nsAString& aType); // Dispatch a "data" event at this object. + void FireDataEvent(const nsAString& aType, const InfallibleTArray& buffer); + void FireDataEvent(const nsAString& aType, const nsAString& aString); void FireDataEvent(JSContext* aCx, const nsAString& aType, JS::Handle aData); + // Initialize this socket from a low-level connection that hasn't connected yet + // (called from RecvOpenBind() in TCPSocketParent). + nsresult InitWithUnconnectedTransport(nsISocketTransport* aTransport); + private: ~TCPSocket(); diff --git a/dom/network/TCPSocketChild.cpp b/dom/network/TCPSocketChild.cpp index 38193d32714..db33a24c2a3 100644 --- a/dom/network/TCPSocketChild.cpp +++ b/dom/network/TCPSocketChild.cpp @@ -102,8 +102,8 @@ TCPSocketChild::SendOpen(TCPSocket* aSocket, bool aUseSSL, bool aUseArrayBuffers PTCPSocketChild::SendOpen(mHost, mPort, aUseSSL, aUseArrayBuffers); } -NS_IMETHODIMP -TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketInternal* aSocket, +void +TCPSocketChild::SendWindowlessOpenBind(TCPSocket* aSocket, const nsACString& aRemoteHost, uint16_t aRemotePort, const nsACString& aLocalHost, uint16_t aLocalPort, bool aUseSSL) @@ -115,8 +115,7 @@ TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketInternal* aSocket, aRemotePort); PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort, nsCString(aLocalHost), aLocalPort, - aUseSSL, NS_LITERAL_CSTRING("arraybuffer")); - return NS_OK; + aUseSSL, true); } void @@ -165,35 +164,12 @@ TCPSocketChild::RecvCallback(const nsString& aType, const SendableData& data = aData.get_SendableData(); if (data.type() == SendableData::TArrayOfuint8_t) { - // See if we can pass array directly. - nsCOMPtr nativeSocket = do_QueryInterface(mSocket); - if (nativeSocket) { - const InfallibleTArray& buffer = data.get_ArrayOfuint8_t(); - nativeSocket->CallListenerNativeArray(const_cast(buffer.Elements()), - buffer.Length()); - return true; - } - } - AutoJSAPI api; - if (NS_WARN_IF(!api.Init(mSocket->GetOwner()))) { - return true; - } - JSContext* cx = api.cx(); - JS::Rooted val(cx); - - if (data.type() == SendableData::TArrayOfuint8_t) { - bool ok = IPC::DeserializeArrayBuffer(cx, data.get_ArrayOfuint8_t(), &val); - NS_ENSURE_TRUE(ok, true); - + mSocket->FireDataEvent(cx, aType, data.get_ArrayOfuint8_t()); } else if (data.type() == SendableData::TnsCString) { - bool ok = ToJSValue(cx, NS_ConvertASCIItoUTF16(data.get_nsCString()), &val); - NS_ENSURE_TRUE(ok, true); - + mSocket->FireDataEvent(aType, data.get_nsCString()); } else { MOZ_CRASH("Invalid callback data type!"); } - mSocket->FireDataEvent(cx, aType, val); - } else { MOZ_CRASH("Invalid callback type!"); } @@ -227,9 +203,9 @@ TCPSocketChild::SendSend(const ArrayBuffer& aData, } NS_IMETHODIMP -TCPSocketChild::SendSendArray(nsTArray *aArr, uint32_t aTrackingNumber) +TCPSocketChild::SendSendArray(nsTArray& aArray, uint32_t aTrackingNumber) { - SendData(*aArr, aTrackingNumber); + SendData(aArray, aTrackingNumber); return NS_OK; } diff --git a/dom/network/TCPSocketChild.h b/dom/network/TCPSocketChild.h index 5674dd5d842..18b6265e4ab 100644 --- a/dom/network/TCPSocketChild.h +++ b/dom/network/TCPSocketChild.h @@ -12,6 +12,13 @@ #include "nsCOMPtr.h" #include "js/TypeDecls.h" +namespace IPC { +bool +DeserializeArrayBuffer(JSContext* cx, + const InfallibleTArray& aBuffer, + JS::MutableHandle aVal); +} + namespace mozilla { namespace dom { @@ -43,11 +50,19 @@ public: ~TCPSocketChild(); void SendOpen(TCPSocket* aSocket, bool aUseSSL, bool aUseArrayBuffers); + void SendWindowlessOpenBind(TCPSocket* aSocket, + const nsACString& aRemoteHost, uint16_t aRemotePort, + const nsACString& aLocalHost, uint16_t aLocalPort, + bool aUseSSL); + NS_IMETHOD SendSendArray(nsTArray& aArray, + uint32_t aTrackingNumber); void SendSend(const nsACString& aData, uint32_t aTrackingNumber); nsresult SendSend(const ArrayBuffer& aData, uint32_t aByteOffset, uint32_t aByteLength, uint32_t aTrackingNumber); + void SendSendArray(nsTArray* arr, + uint32_t trackingNumber); void SetSocket(TCPSocket* aSocket); void GetHost(nsAString& aHost); diff --git a/dom/network/TCPSocketParent.cpp b/dom/network/TCPSocketParent.cpp index e3a12fb9bbb..fc3d659139a 100644 --- a/dom/network/TCPSocketParent.cpp +++ b/dom/network/TCPSocketParent.cpp @@ -178,7 +178,7 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost, const nsCString& aLocalAddr, const uint16_t& aLocalPort, const bool& aUseSSL, - const nsCString& aBinaryType) + const bool& aUseArrayBuffers) { if (net::UsingNeckoIPCSecurity() && !AssertAppProcessPermission(Manager()->Manager(), "tcp-socket")) { @@ -223,18 +223,20 @@ TCPSocketParent::RecvOpenBind(const nsCString& aRemoteHost, // Obtain App ID uint32_t appId = nsIScriptSecurityManager::NO_APP_ID; + bool inBrowser = false; const PContentParent *content = Manager()->Manager(); const InfallibleTArray& browsers = content->ManagedPBrowserParent(); if (browsers.Length() > 0) { TabParent *tab = static_cast(browsers[0]); appId = tab->OwnAppId(); + inBrowser = tab->IsBrowserElement(); } - mSocket = new TCPSocket(nullptr, aRemoteHost, aRemotePort, aUseSSL, - aBinaryType.EqualsLiteral("arraybuffer")); + mSocket = new TCPSocket(nullptr, NS_ConvertUTF8toUTF16(aRemoteHost), aRemotePort, aUseSSL, aUseArrayBuffers); mSocket->SetAppIdAndBrowser(appId, inBrowser); mSocket->SetSocketBridgeParent(this); - NS_ENSURE_SUCCESS(mSocket->InitWithTransport(socketTransport), true); + rv = mSocket->InitWithUnconnectedTransport(socketTransport); + NS_ENSURE_SUCCESS(rv, true); return true; } diff --git a/dom/network/TCPSocketParent.h b/dom/network/TCPSocketParent.h index efaf82b635c..298498f91a5 100644 --- a/dom/network/TCPSocketParent.h +++ b/dom/network/TCPSocketParent.h @@ -57,7 +57,7 @@ public: const nsCString& aLocalAddr, const uint16_t& aLocalPort, const bool& aUseSSL, - const nsCString& aBinaryType) override; + const bool& aUseArrayBuffers) override; virtual bool RecvStartTLS() override; virtual bool RecvSuspend() override;