123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include <algorithm>
- #include "TCPSocketChild.h"
- #include "mozilla/Unused.h"
- #include "mozilla/UniquePtr.h"
- #include "mozilla/net/NeckoChild.h"
- #include "mozilla/dom/PBrowserChild.h"
- #include "mozilla/dom/TabChild.h"
- #include "nsITCPSocketCallback.h"
- #include "TCPSocket.h"
- #include "nsContentUtils.h"
- #include "jsapi.h"
- #include "jsfriendapi.h"
- using mozilla::net::gNeckoChild;
- namespace IPC {
- bool
- DeserializeArrayBuffer(JSContext* cx,
- const InfallibleTArray<uint8_t>& aBuffer,
- JS::MutableHandle<JS::Value> aVal)
- {
- mozilla::UniquePtr<uint8_t[], JS::FreePolicy> data(js_pod_malloc<uint8_t>(aBuffer.Length()));
- if (!data)
- return false;
- memcpy(data.get(), aBuffer.Elements(), aBuffer.Length());
- JSObject* obj = JS_NewArrayBufferWithContents(cx, aBuffer.Length(), data.get());
- if (!obj)
- return false;
- // If JS_NewArrayBufferWithContents returns non-null, the ownership of
- // the data is transfered to obj, so we release the ownership here.
- mozilla::Unused << data.release();
- aVal.setObject(*obj);
- return true;
- }
- } // namespace IPC
- namespace mozilla {
- namespace dom {
- NS_IMPL_CYCLE_COLLECTION_CLASS(TCPSocketChildBase)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TCPSocketChildBase)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSocket)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
- NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TCPSocketChildBase)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mSocket)
- NS_IMPL_CYCLE_COLLECTION_UNLINK_END
- NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(TCPSocketChildBase)
- NS_IMPL_CYCLE_COLLECTION_TRACE_END
- NS_IMPL_CYCLE_COLLECTING_ADDREF(TCPSocketChildBase)
- NS_IMPL_CYCLE_COLLECTING_RELEASE(TCPSocketChildBase)
- NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TCPSocketChildBase)
- NS_INTERFACE_MAP_ENTRY(nsISupports)
- NS_INTERFACE_MAP_END
- TCPSocketChildBase::TCPSocketChildBase()
- : mIPCOpen(false)
- {
- mozilla::HoldJSObjects(this);
- }
- TCPSocketChildBase::~TCPSocketChildBase()
- {
- mozilla::DropJSObjects(this);
- }
- NS_IMETHODIMP_(MozExternalRefCountType) TCPSocketChild::Release(void)
- {
- nsrefcnt refcnt = TCPSocketChildBase::Release();
- if (refcnt == 1 && mIPCOpen) {
- PTCPSocketChild::SendRequestDelete();
- return 1;
- }
- return refcnt;
- }
- TCPSocketChild::TCPSocketChild(const nsAString& aHost, const uint16_t& aPort)
- : mHost(aHost)
- , mPort(aPort)
- {
- }
- void
- TCPSocketChild::SendOpen(nsITCPSocketCallback* aSocket, bool aUseSSL, bool aUseArrayBuffers)
- {
- mSocket = aSocket;
- AddIPDLReference();
- gNeckoChild->SendPTCPSocketConstructor(this, mHost, mPort);
- MOZ_ASSERT(mFilterName.IsEmpty()); // Currently nobody should use this
- PTCPSocketChild::SendOpen(mHost, mPort, aUseSSL, aUseArrayBuffers);
- }
- void
- TCPSocketChild::SendWindowlessOpenBind(nsITCPSocketCallback* aSocket,
- const nsACString& aRemoteHost, uint16_t aRemotePort,
- const nsACString& aLocalHost, uint16_t aLocalPort,
- bool aUseSSL)
- {
- mSocket = aSocket;
- AddIPDLReference();
- gNeckoChild->SendPTCPSocketConstructor(this,
- NS_ConvertUTF8toUTF16(aRemoteHost),
- aRemotePort);
- PTCPSocketChild::SendOpenBind(nsCString(aRemoteHost), aRemotePort,
- nsCString(aLocalHost), aLocalPort,
- aUseSSL, true, mFilterName);
- }
- void
- TCPSocketChildBase::ReleaseIPDLReference()
- {
- MOZ_ASSERT(mIPCOpen);
- mIPCOpen = false;
- mSocket = nullptr;
- this->Release();
- }
- void
- TCPSocketChildBase::AddIPDLReference()
- {
- MOZ_ASSERT(!mIPCOpen);
- mIPCOpen = true;
- this->AddRef();
- }
- TCPSocketChild::~TCPSocketChild()
- {
- }
- bool
- TCPSocketChild::RecvUpdateBufferedAmount(const uint32_t& aBuffered,
- const uint32_t& aTrackingNumber)
- {
- mSocket->UpdateBufferedAmount(aBuffered, aTrackingNumber);
- return true;
- }
- bool
- TCPSocketChild::RecvCallback(const nsString& aType,
- const CallbackData& aData,
- const uint32_t& aReadyState)
- {
- mSocket->UpdateReadyState(aReadyState);
- if (aData.type() == CallbackData::Tvoid_t) {
- mSocket->FireEvent(aType);
- } else if (aData.type() == CallbackData::TTCPError) {
- const TCPError& err(aData.get_TCPError());
- mSocket->FireErrorEvent(err.name(), err.message());
- } else if (aData.type() == CallbackData::TSendableData) {
- const SendableData& data = aData.get_SendableData();
- if (data.type() == SendableData::TArrayOfuint8_t) {
- mSocket->FireDataArrayEvent(aType, data.get_ArrayOfuint8_t());
- } else if (data.type() == SendableData::TnsCString) {
- mSocket->FireDataStringEvent(aType, data.get_nsCString());
- } else {
- MOZ_CRASH("Invalid callback data type!");
- }
- } else {
- MOZ_CRASH("Invalid callback type!");
- }
- return true;
- }
- void
- TCPSocketChild::SendSend(const nsACString& aData, uint32_t aTrackingNumber)
- {
- SendData(nsCString(aData), aTrackingNumber);
- }
- nsresult
- TCPSocketChild::SendSend(const ArrayBuffer& aData,
- uint32_t aByteOffset,
- uint32_t aByteLength,
- uint32_t aTrackingNumber)
- {
- uint32_t buflen = aData.Length();
- uint32_t offset = std::min(buflen, aByteOffset);
- uint32_t nbytes = std::min(buflen - aByteOffset, aByteLength);
- FallibleTArray<uint8_t> fallibleArr;
- if (!fallibleArr.InsertElementsAt(0, aData.Data() + offset, nbytes, fallible)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- InfallibleTArray<uint8_t> arr;
- arr.SwapElements(fallibleArr);
- SendData(arr, aTrackingNumber);
- return NS_OK;
- }
- NS_IMETHODIMP
- TCPSocketChild::SendSendArray(nsTArray<uint8_t>& aArray, uint32_t aTrackingNumber)
- {
- SendData(aArray, aTrackingNumber);
- return NS_OK;
- }
- void
- TCPSocketChild::SetSocket(TCPSocket* aSocket)
- {
- mSocket = aSocket;
- }
- void
- TCPSocketChild::GetHost(nsAString& aHost)
- {
- aHost = mHost;
- }
- void
- TCPSocketChild::GetPort(uint16_t* aPort)
- {
- *aPort = mPort;
- }
- nsresult
- TCPSocketChild::SetFilterName(const nsACString& aFilterName)
- {
- if (!mFilterName.IsEmpty()) {
- // filter name can only be set once.
- return NS_ERROR_FAILURE;
- }
- mFilterName = aFilterName;
- return NS_OK;
- }
- bool
- TCPSocketChild::RecvRequestDelete()
- {
- mozilla::Unused << Send__delete__(this);
- return true;
- }
- } // namespace dom
- } // namespace mozilla
|