Bug 952927 - Part 1: Expose raw data on UDP socket messages. r=bz, r=mcmanus, r=schien

This commit is contained in:
Pranav Kant 2014-03-07 08:55:15 -05:00
parent 92923dcbfe
commit 64e17d1e5e
3 changed files with 167 additions and 24 deletions

View File

@ -12,6 +12,7 @@ interface nsISocketTransport;
interface nsIOutputStream;
%{ C++
#include "nsTArrayForwardDeclare.h"
namespace mozilla {
namespace net {
union NetAddr;
@ -20,6 +21,7 @@ union NetAddr;
%}
native NetAddr(mozilla::net::NetAddr);
[ptr] native NetAddrPtr(mozilla::net::NetAddr);
[ref] native Uint8TArrayRef(FallibleTArray<uint8_t>);
/**
* nsIUDPSocket
@ -208,4 +210,10 @@ interface nsIUDPMessage : nsISupports
* Stream to send a response
*/
readonly attribute nsIOutputStream outputStream;
/**
* Raw Data of the message
*/
[implicit_jscontext] readonly attribute jsval rawData;
[noscript, notxpcom, nostdcall] Uint8TArrayRef getDataAsTArray();
};

View File

@ -5,6 +5,8 @@
#include "mozilla/Attributes.h"
#include "mozilla/Endian.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/HoldDropJSObjects.h"
#include "nsSocketTransport2.h"
#include "nsUDPSocket.h"
@ -139,50 +141,91 @@ NS_IMETHODIMP nsUDPOutputStream::IsNonBlocking(bool *_retval)
//-----------------------------------------------------------------------------
// nsUDPMessage impl
//-----------------------------------------------------------------------------
NS_IMPL_ISUPPORTS1(nsUDPMessage, nsIUDPMessage)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsUDPMessage)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsUDPMessage)
nsUDPMessage::nsUDPMessage(PRNetAddr* aAddr,
nsIOutputStream* aOutputStream,
const nsACString& aData)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsUDPMessage)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsUDPMessage)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIUDPMessage)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsUDPMessage)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsobj)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsUDPMessage)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsUDPMessage)
tmp->mJsobj = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
nsUDPMessage::nsUDPMessage(NetAddr* aAddr,
nsIOutputStream* aOutputStream,
FallibleTArray<uint8_t>& aData)
: mOutputStream(aOutputStream)
, mData(aData)
{
memcpy(&mAddr, aAddr, sizeof(NetAddr));
aData.SwapElements(mData);
}
nsUDPMessage::~nsUDPMessage()
{
mozilla::DropJSObjects(this);
}
/* readonly attribute nsINetAddr from; */
NS_IMETHODIMP nsUDPMessage::GetFromAddr(nsINetAddr * *aFromAddr)
NS_IMETHODIMP
nsUDPMessage::GetFromAddr(nsINetAddr * *aFromAddr)
{
NS_ENSURE_ARG_POINTER(aFromAddr);
NetAddr clientAddr;
PRNetAddrToNetAddr(&mAddr, &clientAddr);
nsCOMPtr<nsINetAddr> result = new nsNetAddr(&clientAddr);
nsCOMPtr<nsINetAddr> result = new nsNetAddr(&mAddr);
result.forget(aFromAddr);
return NS_OK;
}
/* readonly attribute ACString data; */
NS_IMETHODIMP nsUDPMessage::GetData(nsACString & aData)
NS_IMETHODIMP
nsUDPMessage::GetData(nsACString & aData)
{
aData = mData;
aData.Assign(reinterpret_cast<const char*>(mData.Elements()), mData.Length());
return NS_OK;
}
/* readonly attribute nsIOutputStream outputStream; */
NS_IMETHODIMP nsUDPMessage::GetOutputStream(nsIOutputStream * *aOutputStream)
NS_IMETHODIMP
nsUDPMessage::GetOutputStream(nsIOutputStream * *aOutputStream)
{
NS_ENSURE_ARG_POINTER(aOutputStream);
NS_IF_ADDREF(*aOutputStream = mOutputStream);
return NS_OK;
}
/* readonly attribute jsval rawData; */
NS_IMETHODIMP
nsUDPMessage::GetRawData(JSContext* cx,
JS::MutableHandleValue aRawData)
{
if(!mJsobj){
mJsobj = mozilla::dom::Uint8Array::Create(cx, nullptr, mData.Length(), mData.Elements());
mozilla::HoldJSObjects(this);
}
aRawData.setObject(*mJsobj);
return NS_OK;
}
/* [noscript, notxpcom, nostdcall] Uint8ArrayRef getDataAsTArray(); */
FallibleTArray<uint8_t>&
nsUDPMessage::GetDataAsTArray()
{
return mData;
}
//-----------------------------------------------------------------------------
// nsUDPSocket
//-----------------------------------------------------------------------------
@ -303,6 +346,78 @@ nsUDPSocket::TryAttach()
return NS_OK;
}
namespace {
//-----------------------------------------------------------------------------
// UDPMessageProxy
//-----------------------------------------------------------------------------
class UDPMessageProxy MOZ_FINAL : public nsIUDPMessage
{
public:
UDPMessageProxy(NetAddr* aAddr,
nsIOutputStream* aOutputStream,
FallibleTArray<uint8_t>& aData)
: mOutputStream(aOutputStream)
{
memcpy(&mAddr, aAddr, sizeof(NetAddr));
aData.SwapElements(mData);
}
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIUDPMESSAGE
private:
NetAddr mAddr;
nsCOMPtr<nsIOutputStream> mOutputStream;
FallibleTArray<uint8_t> mData;
};
NS_IMPL_ISUPPORTS1(UDPMessageProxy, nsIUDPMessage)
/* readonly attribute nsINetAddr from; */
NS_IMETHODIMP
UDPMessageProxy::GetFromAddr(nsINetAddr * *aFromAddr)
{
NS_ENSURE_ARG_POINTER(aFromAddr);
nsCOMPtr<nsINetAddr> result = new nsNetAddr(&mAddr);
result.forget(aFromAddr);
return NS_OK;
}
/* readonly attribute ACString data; */
NS_IMETHODIMP
UDPMessageProxy::GetData(nsACString & aData)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* [noscript, notxpcom, nostdcall] Uint8TArrayRef getDataAsTArray(); */
FallibleTArray<uint8_t>&
UDPMessageProxy::GetDataAsTArray()
{
return mData;
}
/* readonly attribute jsval rawData; */
NS_IMETHODIMP
UDPMessageProxy::GetRawData(JSContext* cx,
JS::MutableHandleValue aRawData)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute nsIOutputStream outputStream; */
NS_IMETHODIMP
UDPMessageProxy::GetOutputStream(nsIOutputStream * *aOutputStream)
{
NS_ENSURE_ARG_POINTER(aOutputStream);
NS_IF_ADDREF(*aOutputStream = mOutputStream);
return NS_OK;
}
} //anonymous namespace
//-----------------------------------------------------------------------------
// nsUDPSocket::nsASocketHandler
//-----------------------------------------------------------------------------
@ -333,9 +448,9 @@ nsUDPSocket::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
}
mByteReadCount += count;
nsCString data;
if (!data.Assign(buff, count, mozilla::fallible_t())) {
mCondition = NS_ERROR_OUT_OF_MEMORY;
FallibleTArray<uint8_t> data;
if(!data.AppendElements(buff, count)){
mCondition = NS_ERROR_UNEXPECTED;
return;
}
@ -360,7 +475,9 @@ nsUDPSocket::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
return;
}
nsCOMPtr<nsIUDPMessage> message = new nsUDPMessage(&prClientAddr, pipeOut, data);
NetAddr netAddr;
PRNetAddrToNetAddr(&prClientAddr, &netAddr);
nsCOMPtr<nsIUDPMessage> message = new UDPMessageProxy(&netAddr, pipeOut, data);
mListener->OnPacketReceived(this, message);
}
@ -534,7 +651,9 @@ nsUDPSocket::GetAddress(NetAddr *aResult)
}
namespace {
//-----------------------------------------------------------------------------
// SocketListenerProxy
//-----------------------------------------------------------------------------
class SocketListenerProxy MOZ_FINAL : public nsIUDPSocketListener
{
public:
@ -613,7 +732,20 @@ SocketListenerProxy::OnStopListening(nsIUDPSocket* aSocket,
NS_IMETHODIMP
SocketListenerProxy::OnPacketReceivedRunnable::Run()
{
mListener->OnPacketReceived(mSocket, mMessage);
NetAddr netAddr;
nsCOMPtr<nsINetAddr> nsAddr;
mMessage->GetFromAddr(getter_AddRefs(nsAddr));
nsAddr->GetNetAddr(&netAddr);
nsCOMPtr<nsIOutputStream> outputStream;
mMessage->GetOutputStream(getter_AddRefs(outputStream));
FallibleTArray<uint8_t>& data = mMessage->GetDataAsTArray();
nsCOMPtr<nsIUDPMessage> message = new nsUDPMessage(&netAddr,
outputStream,
data);
mListener->OnPacketReceived(mSocket, message);
return NS_OK;
}

View File

@ -10,6 +10,7 @@
#include "mozilla/Mutex.h"
#include "nsIOutputStream.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
//-----------------------------------------------------------------------------
@ -61,19 +62,21 @@ private:
class nsUDPMessage : public nsIUDPMessage
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsUDPMessage)
NS_DECL_NSIUDPMESSAGE
nsUDPMessage(PRNetAddr* aAddr,
nsUDPMessage(mozilla::net::NetAddr* aAddr,
nsIOutputStream* aOutputStream,
const nsACString& aData);
FallibleTArray<uint8_t>& aData);
private:
virtual ~nsUDPMessage();
PRNetAddr mAddr;
mozilla::net::NetAddr mAddr;
nsCOMPtr<nsIOutputStream> mOutputStream;
nsCString mData;
FallibleTArray<uint8_t> mData;
JS::Heap<JSObject*> mJsobj;
};