mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 783205 - Networking Dashboard. r=mcmanus, r=jorendorff, sr=biesi
This commit is contained in:
parent
2ca324a589
commit
bd752af443
@ -75,6 +75,8 @@ public:
|
||||
virtual void OnSocketReady(PRFileDesc *fd, int16_t outflags);
|
||||
virtual void OnSocketDetached(PRFileDesc *fd);
|
||||
virtual void IsLocal(bool *aIsLocal);
|
||||
virtual uint64_t ByteCountSent() { return 0; }
|
||||
virtual uint64_t ByteCountReceived() { return 0; }
|
||||
|
||||
// nsISupports methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -129,6 +129,9 @@ class SocketHandler : public nsASocketHandler {
|
||||
*aIsLocal = false;
|
||||
}
|
||||
|
||||
virtual uint64_t ByteCountSent() { return 0; }
|
||||
virtual uint64_t ByteCountReceived() { return 0; }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
private:
|
||||
|
@ -82,6 +82,9 @@ class TransportLayerPrsock : public TransportLayer {
|
||||
*aIsLocal = false;
|
||||
}
|
||||
|
||||
virtual uint64_t ByteCountSent() { return 0; }
|
||||
virtual uint64_t ByteCountReceived() { return 0; }
|
||||
|
||||
// nsISupports methods
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
|
@ -30,6 +30,8 @@ SDK_XPIDLSRCS = \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIDashboard.idl \
|
||||
nsIDashboardEventNotifier.idl \
|
||||
nsIApplicationCache.idl \
|
||||
nsIApplicationCacheChannel.idl \
|
||||
nsIApplicationCacheContainer.idl \
|
||||
|
@ -67,6 +67,13 @@ public:
|
||||
// connections.
|
||||
//
|
||||
virtual void IsLocal(bool *aIsLocal) = 0;
|
||||
|
||||
|
||||
//
|
||||
// returns the number of bytes sent/transmitted over the socket
|
||||
//
|
||||
virtual uint64_t ByteCountSent() = 0;
|
||||
virtual uint64_t ByteCountReceived() = 0;
|
||||
};
|
||||
|
||||
#endif // !nsASocketHandler_h__
|
||||
|
40
netwerk/base/public/nsIDashboard.idl
Normal file
40
netwerk/base/public/nsIDashboard.idl
Normal file
@ -0,0 +1,40 @@
|
||||
/* 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 "nsISupports.idl"
|
||||
#include "nsIDashboardEventNotifier.idl"
|
||||
|
||||
/* A JavaScript callback function that takes a JSON as its parameter.
|
||||
* The returned JSON contains arrays with data
|
||||
*/
|
||||
[scriptable, function, uuid(19d7f24f-a95a-4fd9-87e2-d96e9e4b1f6d)]
|
||||
interface NetDashboardCallback : nsISupports
|
||||
{
|
||||
void onDashboardDataAvailable(in jsval data);
|
||||
};
|
||||
|
||||
/* The dashboard service.
|
||||
* The async API returns JSONs, which hold arrays with the required info.
|
||||
* Only one request of each type may be pending at any time.
|
||||
*/
|
||||
[scriptable, uuid(c79eb3c6-091a-45a6-8544-5a8d1ab79537)]
|
||||
interface nsIDashboard : nsISupports
|
||||
{
|
||||
/* Arrays: host, port, tcp, active, socksent, sockreceived
|
||||
* Values: sent, received */
|
||||
void requestSockets(in NetDashboardCallback cb);
|
||||
|
||||
/* Arrays: host, port, spdy, ssl
|
||||
* Array of arrays: active, idle */
|
||||
void requestHttpConnections(in NetDashboardCallback cb);
|
||||
|
||||
/* Arrays: hostport, encrypted, msgsent, msgreceived, sentsize, receivedsize */
|
||||
void requestWebsocketConnections(in NetDashboardCallback cb);
|
||||
|
||||
/* Arrays: hostname, family, hostaddr, expiration */
|
||||
void requestDNSInfo(in NetDashboardCallback cb);
|
||||
|
||||
/* When true, the service will log websocket events */
|
||||
attribute boolean enableLogging;
|
||||
};
|
23
netwerk/base/public/nsIDashboardEventNotifier.idl
Normal file
23
netwerk/base/public/nsIDashboardEventNotifier.idl
Normal file
@ -0,0 +1,23 @@
|
||||
/* 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 "nsISupports.idl"
|
||||
|
||||
[builtinclass, uuid(24fdfcbe-54cb-4997-8392-3c476126ea3b)]
|
||||
interface nsIDashboardEventNotifier : nsISupports
|
||||
{
|
||||
/* These methods are called to register a websocket event with the dashboard
|
||||
*
|
||||
* A host is identified by the (aHost, aSerial) pair.
|
||||
* aHost: the host's name: example.com
|
||||
* aSerial: a number that uniquely identifies the websocket
|
||||
*
|
||||
* aEncrypted: if the connection is encrypted
|
||||
* aLength: the length of the message in bytes
|
||||
*/
|
||||
void addHost(in ACString aHost, in unsigned long aSerial, in boolean aEncrypted);
|
||||
void removeHost(in ACString aHost, in unsigned long aSerial);
|
||||
void newMsgSent(in ACString aHost, in unsigned long aSerial, in unsigned long aLength);
|
||||
void newMsgReceived(in ACString aHost, in unsigned long aSerial, in unsigned long aLength);
|
||||
};
|
415
netwerk/base/src/Dashboard.cpp
Normal file
415
netwerk/base/src/Dashboard.cpp
Normal file
@ -0,0 +1,415 @@
|
||||
/* 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 "nsContentUtils.h"
|
||||
#include "mozilla/net/Dashboard.h"
|
||||
#include "mozilla/net/HttpInfo.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(Dashboard, nsIDashboard, nsIDashboardEventNotifier)
|
||||
|
||||
#define CREATE_ARRAY_OBJECT(object) \
|
||||
JSObject* object = JS_NewArrayObject(cx, 0, nullptr); \
|
||||
if (!object) \
|
||||
return NS_ERROR_OUT_OF_MEMORY ; \
|
||||
|
||||
#define SET_ELEMENT(object, func, param, index) \
|
||||
if (!JS_DefineElement(cx, object, index, func(param), \
|
||||
nullptr, nullptr, JSPROP_ENUMERATE)) \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
|
||||
#define SET_PROPERTY(finalObject, object, property) \
|
||||
val = OBJECT_TO_JSVAL(object); \
|
||||
if (!JS_DefineProperty(cx, finalObject, #property, \
|
||||
val, nullptr, nullptr, JSPROP_ENUMERATE)) \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
|
||||
Dashboard::Dashboard()
|
||||
{
|
||||
mEnableLogging = false;
|
||||
}
|
||||
|
||||
Dashboard::~Dashboard()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::RequestSockets(NetDashboardCallback* cb)
|
||||
{
|
||||
if (mSock.cb)
|
||||
return NS_ERROR_FAILURE;
|
||||
mSock.cb = cb;
|
||||
mSock.data.Clear();
|
||||
mSock.thread = NS_GetCurrentThread();
|
||||
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &Dashboard::GetSocketsDispatch);
|
||||
gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Dashboard::GetSocketsDispatch()
|
||||
{
|
||||
if (gSocketTransportService)
|
||||
gSocketTransportService->GetSocketConnections(&mSock.data);
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &Dashboard::GetSockets);
|
||||
mSock.thread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Dashboard::GetSockets()
|
||||
{
|
||||
jsval val;
|
||||
JSContext* cx = nsContentUtils::GetSafeJSContext();
|
||||
JSAutoRequest request(cx);
|
||||
|
||||
JSObject* finalObject = JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
if (!finalObject)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
CREATE_ARRAY_OBJECT(hostJs);
|
||||
CREATE_ARRAY_OBJECT(portJs);
|
||||
CREATE_ARRAY_OBJECT(activeJs);
|
||||
CREATE_ARRAY_OBJECT(sentJs);
|
||||
CREATE_ARRAY_OBJECT(receivedJs);
|
||||
CREATE_ARRAY_OBJECT(tcpJs);
|
||||
CREATE_ARRAY_OBJECT(sockSentJs);
|
||||
CREATE_ARRAY_OBJECT(sockRecJs);
|
||||
mSock.totalSent = 0;
|
||||
mSock.totalRecv = 0;
|
||||
|
||||
for (uint32_t i = 0; i < mSock.data.Length(); i++) {
|
||||
JSString* hostString = JS_NewStringCopyZ(cx, mSock.data[i].host.get());
|
||||
SET_ELEMENT(hostJs, STRING_TO_JSVAL, hostString, i);
|
||||
SET_ELEMENT(portJs, INT_TO_JSVAL, mSock.data[i].port, i);
|
||||
SET_ELEMENT(activeJs, BOOLEAN_TO_JSVAL, mSock.data[i].active, i);
|
||||
SET_ELEMENT(tcpJs, INT_TO_JSVAL, mSock.data[i].tcp, i);
|
||||
SET_ELEMENT(sockSentJs, DOUBLE_TO_JSVAL, (double) mSock.data[i].sent, i);
|
||||
SET_ELEMENT(sockRecJs, DOUBLE_TO_JSVAL, (double) mSock.data[i].received, i);
|
||||
mSock.totalSent += mSock.data[i].sent;
|
||||
mSock.totalRecv += mSock.data[i].received;
|
||||
}
|
||||
|
||||
SET_ELEMENT(sentJs, DOUBLE_TO_JSVAL, (double) mSock.totalSent, 0);
|
||||
SET_ELEMENT(receivedJs, DOUBLE_TO_JSVAL, (double) mSock.totalRecv, 0);
|
||||
|
||||
SET_PROPERTY(finalObject, hostJs, host);
|
||||
SET_PROPERTY(finalObject, portJs, port);
|
||||
SET_PROPERTY(finalObject, activeJs, active);
|
||||
SET_PROPERTY(finalObject, tcpJs, tcp);
|
||||
SET_PROPERTY(finalObject, sockSentJs, socksent);
|
||||
SET_PROPERTY(finalObject, sockRecJs, sockreceived);
|
||||
SET_PROPERTY(finalObject, sentJs, sent);
|
||||
SET_PROPERTY(finalObject, receivedJs, received);
|
||||
|
||||
val = OBJECT_TO_JSVAL(finalObject);
|
||||
mSock.cb->OnDashboardDataAvailable(val);
|
||||
mSock.cb = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::RequestHttpConnections(NetDashboardCallback* cb)
|
||||
{
|
||||
if (mHttp.cb)
|
||||
return NS_ERROR_FAILURE;
|
||||
mHttp.cb = cb;
|
||||
mHttp.data.Clear();
|
||||
mHttp.thread = NS_GetCurrentThread();
|
||||
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &Dashboard::GetHttpDispatch);
|
||||
gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Dashboard::GetHttpDispatch()
|
||||
{
|
||||
HttpInfo::GetHttpConnectionData(&mHttp.data);
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &Dashboard::GetHttpConnections);
|
||||
mHttp.thread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
Dashboard::GetHttpConnections()
|
||||
{
|
||||
jsval val;
|
||||
JSContext* cx = nsContentUtils::GetSafeJSContext();
|
||||
JSAutoRequest request(cx);
|
||||
|
||||
JSObject* finalObject = JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
if (!finalObject)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
CREATE_ARRAY_OBJECT(hostJs);
|
||||
CREATE_ARRAY_OBJECT(portJs);
|
||||
CREATE_ARRAY_OBJECT(activeJs);
|
||||
CREATE_ARRAY_OBJECT(idleJs);
|
||||
CREATE_ARRAY_OBJECT(spdyJs);
|
||||
CREATE_ARRAY_OBJECT(sslJs);
|
||||
|
||||
for (uint32_t i = 0; i < mHttp.data.Length(); i++) {
|
||||
JSString* hostString = JS_NewStringCopyZ(cx, mHttp.data[i].host.get());
|
||||
SET_ELEMENT(hostJs, STRING_TO_JSVAL, hostString, i);
|
||||
SET_ELEMENT(portJs, INT_TO_JSVAL, mHttp.data[i].port, i);
|
||||
|
||||
JSObject* rtt_Active = JS_NewArrayObject(cx, 0, nullptr);
|
||||
JSObject* timeToLive_Active = JS_NewArrayObject(cx, 0, nullptr);
|
||||
for (uint32_t j = 0; j < mHttp.data[i].active.Length(); j++) {
|
||||
SET_ELEMENT(rtt_Active, INT_TO_JSVAL, mHttp.data[i].active[j].rtt, j);
|
||||
SET_ELEMENT(timeToLive_Active, INT_TO_JSVAL, mHttp.data[i].active[j].ttl, j);
|
||||
}
|
||||
JSObject* active = JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
SET_PROPERTY(active, rtt_Active, rtt);
|
||||
SET_PROPERTY(active, timeToLive_Active, ttl);
|
||||
SET_ELEMENT(activeJs, OBJECT_TO_JSVAL, active, i);
|
||||
|
||||
JSObject* rtt_Idle = JS_NewArrayObject(cx, 0, nullptr);
|
||||
JSObject* timeToLive_Idle = JS_NewArrayObject(cx, 0, nullptr);
|
||||
for (uint32_t j = 0; j < mHttp.data[i].idle.Length(); j++) {
|
||||
SET_ELEMENT(rtt_Idle, INT_TO_JSVAL, mHttp.data[i].idle[j].rtt, j);
|
||||
SET_ELEMENT(timeToLive_Idle, INT_TO_JSVAL, mHttp.data[i].idle[j].ttl, j);
|
||||
}
|
||||
JSObject* idle = JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
SET_PROPERTY(idle, rtt_Idle, rtt);
|
||||
SET_PROPERTY(idle, timeToLive_Idle, ttl);
|
||||
SET_ELEMENT(idleJs, OBJECT_TO_JSVAL, idle, i);
|
||||
|
||||
SET_ELEMENT(spdyJs, BOOLEAN_TO_JSVAL, mHttp.data[i].spdy, i);
|
||||
SET_ELEMENT(sslJs, BOOLEAN_TO_JSVAL, mHttp.data[i].ssl, i);
|
||||
}
|
||||
|
||||
SET_PROPERTY(finalObject, hostJs, host);
|
||||
SET_PROPERTY(finalObject, portJs, port);
|
||||
SET_PROPERTY(finalObject, activeJs, active);
|
||||
SET_PROPERTY(finalObject, idleJs, idle);
|
||||
SET_PROPERTY(finalObject, spdyJs, spdy);
|
||||
SET_PROPERTY(finalObject, sslJs, ssl);
|
||||
|
||||
val = OBJECT_TO_JSVAL(finalObject);
|
||||
mHttp.cb->OnDashboardDataAvailable(val);
|
||||
mHttp.cb = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::GetEnableLogging(bool* value)
|
||||
{
|
||||
*value = mEnableLogging;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::SetEnableLogging(const bool value)
|
||||
{
|
||||
mEnableLogging = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::AddHost(const nsACString& aHost, uint32_t aSerial, bool aEncrypted)
|
||||
{
|
||||
if (mEnableLogging) {
|
||||
mozilla::MutexAutoLock lock(mWs.lock);
|
||||
LogData data(nsCString(aHost), aSerial, aEncrypted);
|
||||
if (mWs.data.Contains(data))
|
||||
return NS_OK;
|
||||
if (!mWs.data.AppendElement(data))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::RemoveHost(const nsACString& aHost, uint32_t aSerial)
|
||||
{
|
||||
if (mEnableLogging) {
|
||||
mozilla::MutexAutoLock lock(mWs.lock);
|
||||
int32_t index = mWs.IndexOf(nsCString(aHost), aSerial);
|
||||
if (index == -1)
|
||||
return NS_ERROR_FAILURE;
|
||||
mWs.data.RemoveElementAt(index);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::NewMsgSent(const nsACString& aHost, uint32_t aSerial, uint32_t aLength)
|
||||
{
|
||||
if (mEnableLogging) {
|
||||
mozilla::MutexAutoLock lock(mWs.lock);
|
||||
int32_t index = mWs.IndexOf(nsCString(aHost), aSerial);
|
||||
if (index == -1)
|
||||
return NS_ERROR_FAILURE;
|
||||
mWs.data[index].mMsgSent++;
|
||||
mWs.data[index].mSizeSent += aLength;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::NewMsgReceived(const nsACString& aHost, uint32_t aSerial, uint32_t aLength)
|
||||
{
|
||||
if (mEnableLogging) {
|
||||
mozilla::MutexAutoLock lock(mWs.lock);
|
||||
int32_t index = mWs.IndexOf(nsCString(aHost), aSerial);
|
||||
if (index == -1)
|
||||
return NS_ERROR_FAILURE;
|
||||
mWs.data[index].mMsgReceived++;
|
||||
mWs.data[index].mSizeReceived += aLength;
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::RequestWebsocketConnections(NetDashboardCallback* cb)
|
||||
{
|
||||
if (mWs.cb)
|
||||
return NS_ERROR_FAILURE;
|
||||
mWs.cb = cb;
|
||||
mWs.thread = NS_GetCurrentThread();
|
||||
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &Dashboard::GetWebSocketConnections);
|
||||
mWs.thread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Dashboard::GetWebSocketConnections()
|
||||
{
|
||||
jsval val;
|
||||
JSString* jsstring;
|
||||
JSContext* cx = nsContentUtils::GetSafeJSContext();
|
||||
JSAutoRequest request(cx);
|
||||
|
||||
JSObject* finalObject = JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
if (!finalObject)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
CREATE_ARRAY_OBJECT(hostJs);
|
||||
CREATE_ARRAY_OBJECT(msgSentJs);
|
||||
CREATE_ARRAY_OBJECT(msgRecvJs);
|
||||
CREATE_ARRAY_OBJECT(sizeSentJs);
|
||||
CREATE_ARRAY_OBJECT(sizeRecvJs);
|
||||
CREATE_ARRAY_OBJECT(encryptJs);
|
||||
|
||||
mozilla::MutexAutoLock lock(mWs.lock);
|
||||
for (uint32_t i = 0; i < mWs.data.Length(); i++) {
|
||||
jsstring = JS_NewStringCopyN(cx, mWs.data[i].mHost.get(), mWs.data[i].mHost.Length());
|
||||
SET_ELEMENT(hostJs, STRING_TO_JSVAL, jsstring, i);
|
||||
SET_ELEMENT(msgSentJs, INT_TO_JSVAL, mWs.data[i].mMsgSent, i);
|
||||
SET_ELEMENT(msgRecvJs, INT_TO_JSVAL, mWs.data[i].mMsgReceived, i);
|
||||
SET_ELEMENT(sizeSentJs, DOUBLE_TO_JSVAL, (double) mWs.data[i].mSizeSent, i);
|
||||
SET_ELEMENT(sizeRecvJs, DOUBLE_TO_JSVAL, (double) mWs.data[i].mSizeReceived, i);
|
||||
SET_ELEMENT(encryptJs, BOOLEAN_TO_JSVAL, mWs.data[i].mEncrypted, i);
|
||||
}
|
||||
|
||||
SET_PROPERTY(finalObject, hostJs, hostport);
|
||||
SET_PROPERTY(finalObject, msgSentJs, msgsent);
|
||||
SET_PROPERTY(finalObject, msgRecvJs, msgreceived);
|
||||
SET_PROPERTY(finalObject, sizeSentJs, sentsize);
|
||||
SET_PROPERTY(finalObject, sizeRecvJs, receivedsize);
|
||||
SET_PROPERTY(finalObject, encryptJs, encrypted);
|
||||
|
||||
val = OBJECT_TO_JSVAL(finalObject);
|
||||
mWs.cb->OnDashboardDataAvailable(val);
|
||||
mWs.cb = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::RequestDNSInfo(NetDashboardCallback* cb)
|
||||
{
|
||||
if (mDns.cb)
|
||||
return NS_ERROR_FAILURE;
|
||||
mDns.cb = cb;
|
||||
nsresult rv;
|
||||
mDns.data.Clear();
|
||||
mDns.thread = NS_GetCurrentThread();
|
||||
|
||||
if (!mDns.serv) {
|
||||
mDns.serv = do_GetService("@mozilla.org/network/dns-service;1", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &Dashboard::GetDnsInfoDispatch);
|
||||
gSocketTransportService->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Dashboard::GetDnsInfoDispatch()
|
||||
{
|
||||
if (mDns.serv)
|
||||
mDns.serv->GetDNSCacheEntries(&mDns.data);
|
||||
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(this, &Dashboard::GetDNSCacheEntries);
|
||||
mDns.thread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
Dashboard::GetDNSCacheEntries()
|
||||
{
|
||||
jsval val;
|
||||
JSContext* cx = nsContentUtils::GetSafeJSContext();
|
||||
JSAutoRequest request(cx);
|
||||
|
||||
JSObject* finalObject = JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
if (!finalObject)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
CREATE_ARRAY_OBJECT(nameJs);
|
||||
CREATE_ARRAY_OBJECT(addrJs);
|
||||
CREATE_ARRAY_OBJECT(familyJs);
|
||||
CREATE_ARRAY_OBJECT(expiresJs);
|
||||
|
||||
for (uint32_t i = 0; i < mDns.data.Length(); i++) {
|
||||
JSString* hostnameString = JS_NewStringCopyZ(cx, mDns.data[i].hostname.get());
|
||||
SET_ELEMENT(nameJs, STRING_TO_JSVAL, hostnameString, i);
|
||||
|
||||
JSObject* addrObject = JS_NewObject(cx, nullptr, nullptr, nullptr);
|
||||
if (!addrObject)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for (uint32_t j = 0; j < mDns.data[i].hostaddr.Length(); j++) {
|
||||
JSString* addrString = JS_NewStringCopyZ(cx, mDns.data[i].hostaddr[j].get());
|
||||
SET_ELEMENT(addrObject, STRING_TO_JSVAL, addrString, j);
|
||||
}
|
||||
|
||||
SET_ELEMENT(addrJs, OBJECT_TO_JSVAL, addrObject, i);
|
||||
|
||||
JSString* familyString;
|
||||
if (mDns.data[i].family == PR_AF_INET6)
|
||||
familyString = JS_NewStringCopyZ(cx, "ipv6");
|
||||
else
|
||||
familyString = JS_NewStringCopyZ(cx, "ipv4");
|
||||
|
||||
SET_ELEMENT(familyJs, STRING_TO_JSVAL, familyString, i);
|
||||
SET_ELEMENT(expiresJs, DOUBLE_TO_JSVAL, (double) mDns.data[i].expiration, i);
|
||||
}
|
||||
|
||||
SET_PROPERTY(finalObject, nameJs, hostname);
|
||||
SET_PROPERTY(finalObject, addrJs, hostaddr);
|
||||
SET_PROPERTY(finalObject, familyJs, family);
|
||||
SET_PROPERTY(finalObject, expiresJs, expiration);
|
||||
|
||||
val = OBJECT_TO_JSVAL(finalObject);
|
||||
mDns.cb->OnDashboardDataAvailable(val);
|
||||
mDns.cb = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} } // namespace mozilla::net
|
119
netwerk/base/src/Dashboard.h
Normal file
119
netwerk/base/src/Dashboard.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsDashboard_h__
|
||||
#define nsDashboard_h__
|
||||
|
||||
#include "nsIDashboard.h"
|
||||
#include "nsIDashboardEventNotifier.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIThread.h"
|
||||
#include "nsSocketTransport2.h"
|
||||
#include "mozilla/net/DashboardTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class Dashboard:
|
||||
public nsIDashboard,
|
||||
public nsIDashboardEventNotifier
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDASHBOARD
|
||||
NS_DECL_NSIDASHBOARDEVENTNOTIFIER
|
||||
|
||||
Dashboard();
|
||||
private:
|
||||
virtual ~Dashboard();
|
||||
|
||||
void GetSocketsDispatch();
|
||||
void GetHttpDispatch();
|
||||
void GetDnsInfoDispatch();
|
||||
|
||||
/* Helper methods that pass the JSON to the callback function. */
|
||||
nsresult GetSockets();
|
||||
nsresult GetHttpConnections();
|
||||
nsresult GetWebSocketConnections();
|
||||
nsresult GetDNSCacheEntries();
|
||||
|
||||
private:
|
||||
struct SocketData
|
||||
{
|
||||
uint64_t totalSent;
|
||||
uint64_t totalRecv;
|
||||
nsTArray<SocketInfo> data;
|
||||
nsCOMPtr<NetDashboardCallback> cb;
|
||||
nsIThread* thread;
|
||||
};
|
||||
|
||||
struct HttpData {
|
||||
nsTArray<HttpRetParams> data;
|
||||
nsCOMPtr<NetDashboardCallback> cb;
|
||||
nsIThread* thread;
|
||||
};
|
||||
|
||||
struct LogData
|
||||
{
|
||||
LogData(nsCString host, uint32_t serial, bool encryption):
|
||||
mHost(host),
|
||||
mSerial(serial),
|
||||
mMsgSent(0),
|
||||
mMsgReceived(0),
|
||||
mSizeSent(0),
|
||||
mSizeReceived(0),
|
||||
mEncrypted(encryption)
|
||||
{ }
|
||||
nsCString mHost;
|
||||
uint32_t mSerial;
|
||||
uint32_t mMsgSent;
|
||||
uint32_t mMsgReceived;
|
||||
uint64_t mSizeSent;
|
||||
uint64_t mSizeReceived;
|
||||
bool mEncrypted;
|
||||
bool operator==(const LogData& a) const
|
||||
{
|
||||
return mHost.Equals(a.mHost) && (mSerial == a.mSerial);
|
||||
}
|
||||
};
|
||||
|
||||
struct WebSocketData
|
||||
{
|
||||
WebSocketData():lock("Dashboard.webSocketData")
|
||||
{
|
||||
}
|
||||
uint32_t IndexOf(nsCString hostname, uint32_t mSerial)
|
||||
{
|
||||
LogData temp(hostname, mSerial, false);
|
||||
return data.IndexOf(temp);
|
||||
}
|
||||
nsTArray<LogData> data;
|
||||
mozilla::Mutex lock;
|
||||
nsCOMPtr<NetDashboardCallback> cb;
|
||||
nsIThread* thread;
|
||||
};
|
||||
|
||||
struct DnsData
|
||||
{
|
||||
nsCOMPtr<nsIDNSService> serv;
|
||||
nsTArray<DNSCacheEntries> data;
|
||||
nsCOMPtr<NetDashboardCallback> cb;
|
||||
nsIThread* thread;
|
||||
};
|
||||
|
||||
bool mEnableLogging;
|
||||
|
||||
struct SocketData mSock;
|
||||
struct HttpData mHttp;
|
||||
struct WebSocketData mWs;
|
||||
struct DnsData mDns;
|
||||
|
||||
};
|
||||
|
||||
} } // namespace mozilla::net
|
||||
#endif // nsDashboard_h__
|
48
netwerk/base/src/DashboardTypes.h
Normal file
48
netwerk/base/src/DashboardTypes.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef nsDashboardTypes__
|
||||
#define nsDashboardTypes__
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
struct SocketInfo
|
||||
{
|
||||
nsCString host;
|
||||
uint64_t sent;
|
||||
uint64_t received;
|
||||
uint16_t port;
|
||||
bool active;
|
||||
bool tcp;
|
||||
};
|
||||
|
||||
struct DNSCacheEntries
|
||||
{
|
||||
nsCString hostname;
|
||||
nsTArray<nsCString> hostaddr;
|
||||
int8_t family;
|
||||
int64_t expiration;
|
||||
};
|
||||
|
||||
struct HttpConnInfo
|
||||
{
|
||||
uint32_t ttl;
|
||||
uint32_t rtt;
|
||||
};
|
||||
|
||||
struct HttpRetParams
|
||||
{
|
||||
nsCString host;
|
||||
nsTArray<HttpConnInfo> active;
|
||||
nsTArray<HttpConnInfo> idle;
|
||||
uint32_t counter;
|
||||
uint16_t port;
|
||||
bool spdy;
|
||||
bool ssl;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif // nsDashboardTypes__
|
@ -21,6 +21,13 @@ EXPORTS = \
|
||||
nsURLHelper.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/net
|
||||
|
||||
EXPORTS_mozilla/net = \
|
||||
Dashboard.h \
|
||||
DashboardTypes.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsTransportUtils.cpp \
|
||||
nsAsyncStreamCopier.cpp \
|
||||
@ -67,6 +74,7 @@ CPPSRCS = \
|
||||
nsPreloadedStream.cpp \
|
||||
nsStreamListenerWrapper.cpp \
|
||||
ProxyAutoConfig.cpp \
|
||||
Dashboard.cpp \
|
||||
NetworkActivityMonitor.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
@ -24,6 +24,8 @@ public:
|
||||
virtual void OnSocketDetached(PRFileDesc *fd);
|
||||
virtual void IsLocal(bool *aIsLocal);
|
||||
|
||||
virtual uint64_t ByteCountSent() { return 0; }
|
||||
virtual uint64_t ByteCountReceived() { return 0; }
|
||||
nsServerSocket();
|
||||
|
||||
// This must be public to support older compilers (xlC_r on AIX)
|
||||
|
@ -131,6 +131,8 @@ public:
|
||||
// called when a socket event is handled
|
||||
void OnSocketEvent(uint32_t type, nsresult status, nsISupports *param);
|
||||
|
||||
uint64_t ByteCountReceived() { return mInput.ByteCount(); }
|
||||
uint64_t ByteCountSent() { return mOutput.ByteCount(); }
|
||||
protected:
|
||||
|
||||
virtual ~nsSocketTransport();
|
||||
|
@ -34,6 +34,7 @@ void StopSSLServerCertVerificationThreads();
|
||||
} } // namespace mozilla::psm
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
PRLogModuleInfo *gSocketTransportLog = nullptr;
|
||||
@ -1014,3 +1015,41 @@ nsSocketTransportService::DiscoverMaxCount()
|
||||
|
||||
return PR_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
nsSocketTransportService::AnalyzeConnection(nsTArray<SocketInfo> *data,
|
||||
struct SocketContext *context, bool aActive)
|
||||
{
|
||||
PRFileDesc *aFD = context->mFD;
|
||||
bool tcp = (PR_GetDescType(aFD) == PR_DESC_SOCKET_TCP);
|
||||
|
||||
PRNetAddr peer_addr;
|
||||
PR_GetPeerName(aFD, &peer_addr);
|
||||
|
||||
char host[64] = {0};
|
||||
PR_NetAddrToString(&peer_addr, host, sizeof(host));
|
||||
|
||||
uint16_t port;
|
||||
if (peer_addr.raw.family == PR_AF_INET)
|
||||
port = peer_addr.inet.port;
|
||||
else
|
||||
port = peer_addr.ipv6.port;
|
||||
port = PR_ntohs(port);
|
||||
uint64_t sent = context->mHandler->ByteCountSent();
|
||||
uint64_t received = context->mHandler->ByteCountReceived();
|
||||
SocketInfo info = { nsCString(host), sent, received, port, aActive, tcp };
|
||||
|
||||
data->AppendElement(info);
|
||||
}
|
||||
|
||||
void
|
||||
nsSocketTransportService::GetSocketConnections(nsTArray<SocketInfo> *data)
|
||||
{
|
||||
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
|
||||
for (uint32_t i = 0; i < mActiveCount; i++)
|
||||
AnalyzeConnection(data, &mActiveList[i], true);
|
||||
for (uint32_t i = 0; i < mIdleCount; i++)
|
||||
AnalyzeConnection(data, &mIdleList[i], false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsASocketHandler.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/net/DashboardTypes.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -73,6 +74,9 @@ public:
|
||||
return mActiveCount + mIdleCount < gMaxCount;
|
||||
}
|
||||
|
||||
// Called by the networking dashboard
|
||||
// Fills the passed array with socket information
|
||||
void GetSocketConnections(nsTArray<mozilla::net::SocketInfo> *);
|
||||
protected:
|
||||
|
||||
virtual ~nsSocketTransportService();
|
||||
@ -183,6 +187,9 @@ private:
|
||||
void ProbeMaxCount();
|
||||
#endif
|
||||
bool mProbedMaxCount;
|
||||
|
||||
void AnalyzeConnection(nsTArray<mozilla::net::SocketInfo> *data,
|
||||
SocketContext *context, bool aActive);
|
||||
};
|
||||
|
||||
extern nsSocketTransportService *gSocketTransportService;
|
||||
|
@ -867,6 +867,19 @@
|
||||
NS_NETWORK_SOCKET_CONTRACTID_PREFIX "starttls"
|
||||
|
||||
|
||||
#define NS_DASHBOARD_CLASSNAME \
|
||||
"Dashboard"
|
||||
#define NS_DASHBOARD_CONTRACTID \
|
||||
"@mozilla.org/network/dashboard;1"
|
||||
#define NS_DASHBOARD_CID \
|
||||
{ /*c79eb3c6-091a-45a6-8544-5a8d1ab79537 */ \
|
||||
0xc79eb3c6, \
|
||||
0x091a, \
|
||||
0x45a6, \
|
||||
{ 0x85, 0x44, 0x5a, 0x8d, 0x1a, 0xb7, 0x95, 0x37 } \
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* netwerk/cookie classes
|
||||
*/
|
||||
|
@ -232,6 +232,13 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpBasicAuth)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHttpDigestAuth)
|
||||
#endif // !NECKO_PROTOCOL_http
|
||||
|
||||
#include "mozilla/net/Dashboard.h"
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(Dashboard)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NECKO_PROTOCOL_res
|
||||
// resource
|
||||
#include "nsResProtocolHandler.h"
|
||||
@ -694,6 +701,7 @@ NS_DEFINE_NAMED_CID(NS_BUFFEREDOUTPUTSTREAM_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MIMEINPUTSTREAM_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PROTOCOLPROXYSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_STREAMCONVERTERSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_DASHBOARD_CID);
|
||||
#ifdef BUILD_APPLEFILE_DECODER
|
||||
NS_DEFINE_NAMED_CID(NS_APPLEFILEDECODER_CID);
|
||||
#endif
|
||||
@ -826,6 +834,7 @@ static const mozilla::Module::CIDEntry kNeckoCIDs[] = {
|
||||
{ &kNS_MIMEINPUTSTREAM_CID, false, NULL, nsMIMEInputStreamConstructor },
|
||||
{ &kNS_PROTOCOLPROXYSERVICE_CID, true, NULL, nsProtocolProxyServiceConstructor },
|
||||
{ &kNS_STREAMCONVERTERSERVICE_CID, false, NULL, CreateNewStreamConvServiceFactory },
|
||||
{ &kNS_DASHBOARD_CID, false, NULL, mozilla::net::DashboardConstructor },
|
||||
#ifdef BUILD_APPLEFILE_DECODER
|
||||
{ &kNS_APPLEFILEDECODER_CID, false, NULL, nsAppleFileDecoderConstructor },
|
||||
#endif
|
||||
@ -962,6 +971,7 @@ static const mozilla::Module::ContractIDEntry kNeckoContracts[] = {
|
||||
{ NS_MIMEINPUTSTREAM_CONTRACTID, &kNS_MIMEINPUTSTREAM_CID },
|
||||
{ NS_PROTOCOLPROXYSERVICE_CONTRACTID, &kNS_PROTOCOLPROXYSERVICE_CID },
|
||||
{ NS_STREAMCONVERTERSERVICE_CONTRACTID, &kNS_STREAMCONVERTERSERVICE_CID },
|
||||
{ NS_DASHBOARD_CONTRACTID, &kNS_DASHBOARD_CID },
|
||||
#ifdef BUILD_APPLEFILE_DECODER
|
||||
{ NS_IAPPLEFILEDECODER_CONTRACTID, &kNS_APPLEFILEDECODER_CID },
|
||||
#endif
|
||||
|
@ -853,3 +853,11 @@ nsDNSService::GetAFForLookup(const nsACString &host, uint32_t flags)
|
||||
|
||||
return af;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDNSService::GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *args)
|
||||
{
|
||||
NS_ENSURE_TRUE(mResolver, NS_ERROR_NOT_INITIALIZED);
|
||||
mResolver->GetDNSCacheEntries(args);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::net;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@ -1026,3 +1027,55 @@ nsHostResolver::Create(uint32_t maxCacheEntries,
|
||||
*result = res;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
CacheEntryEnumerator(PLDHashTable *table, PLDHashEntryHdr *entry,
|
||||
uint32_t number, void *arg)
|
||||
{
|
||||
nsHostDBEnt *ent = static_cast<nsHostDBEnt *> (entry);
|
||||
nsTArray<DNSCacheEntries> *args =
|
||||
static_cast<nsTArray<DNSCacheEntries> *> (arg);
|
||||
nsHostRecord *rec = ent->rec;
|
||||
// Without addr_info, there is no meaning of adding this entry
|
||||
if (rec->addr_info) {
|
||||
DNSCacheEntries info;
|
||||
const char *hostname;
|
||||
PRNetAddr addr;
|
||||
|
||||
if (rec->host)
|
||||
hostname = rec->host;
|
||||
else // No need to add this entry if no host name is there
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
uint32_t now = NowInMinutes();
|
||||
info.expiration = ((int64_t) rec->expiration - now) * 60;
|
||||
|
||||
// We only need valid DNS cache entries
|
||||
if (info.expiration <= 0)
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
info.family = rec->af;
|
||||
info.hostname = hostname;
|
||||
|
||||
{
|
||||
MutexAutoLock lock(rec->addr_info_lock);
|
||||
void *ptr = PR_EnumerateAddrInfo(nullptr, rec->addr_info, 0, &addr);
|
||||
while (ptr) {
|
||||
char buf[64];
|
||||
if (PR_NetAddrToString(&addr, buf, sizeof(buf)) == PR_SUCCESS)
|
||||
info.hostaddr.AppendElement(buf);
|
||||
ptr = PR_EnumerateAddrInfo(ptr, rec->addr_info, 0, &addr);
|
||||
}
|
||||
}
|
||||
|
||||
args->AppendElement(info);
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsHostResolver::GetDNSCacheEntries(nsTArray<DNSCacheEntries> *args)
|
||||
{
|
||||
PL_DHashTableEnumerate(&mDB, CacheEntryEnumerator, args);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "nsIDNSListener.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/net/DashboardTypes.h"
|
||||
|
||||
class nsHostResolver;
|
||||
class nsHostRecord;
|
||||
@ -275,6 +276,12 @@ private:
|
||||
bool mShutdown;
|
||||
PRIntervalTime mLongIdleTimeout;
|
||||
PRIntervalTime mShortIdleTimeout;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Called by the networking dashboard via the DnsService2
|
||||
*/
|
||||
void GetDNSCacheEntries(nsTArray<mozilla::net::DNSCacheEntries> *);
|
||||
};
|
||||
|
||||
#endif // nsHostResolver_h__
|
||||
|
@ -9,10 +9,20 @@ interface nsIEventTarget;
|
||||
interface nsIDNSRecord;
|
||||
interface nsIDNSListener;
|
||||
|
||||
%{C++
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla { namespace net {
|
||||
struct DNSCacheEntries;
|
||||
} }
|
||||
%}
|
||||
|
||||
[ptr] native EntriesArray(nsTArray<mozilla::net::DNSCacheEntries>);
|
||||
|
||||
/**
|
||||
* nsIDNSService
|
||||
*/
|
||||
[scriptable, uuid(F6E05CC3-8A13-463D-877F-D59B20B59724)]
|
||||
[scriptable, uuid(f1971942-19db-44bf-81e8-d15df220a39f)]
|
||||
interface nsIDNSService : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -73,6 +83,13 @@ interface nsIDNSService : nsISupports
|
||||
nsIDNSRecord resolve(in AUTF8String aHostName,
|
||||
in unsigned long aFlags);
|
||||
|
||||
/**
|
||||
* The method takes a pointer to an nsTArray
|
||||
* and fills it with cache entry data
|
||||
* Called by the networking dashboard
|
||||
*/
|
||||
[noscript] void getDNSCacheEntries(in EntriesArray args);
|
||||
|
||||
/**
|
||||
* @return the hostname of the operating system.
|
||||
*/
|
||||
|
15
netwerk/protocol/http/HttpInfo.cpp
Normal file
15
netwerk/protocol/http/HttpInfo.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
/* 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 "nsHttpHandler.h"
|
||||
#include "HttpInfo.h"
|
||||
|
||||
|
||||
void
|
||||
mozilla::net::HttpInfo::
|
||||
GetHttpConnectionData(nsTArray<HttpRetParams>* args)
|
||||
{
|
||||
if (gHttpHandler)
|
||||
gHttpHandler->ConnMgr()->GetConnectionData(args);
|
||||
}
|
22
netwerk/protocol/http/HttpInfo.h
Normal file
22
netwerk/protocol/http/HttpInfo.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* 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 "mozilla/net/DashboardTypes.h"
|
||||
|
||||
#ifndef nsHttpInfo__
|
||||
#define nsHttpInfo__
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class HttpInfo
|
||||
{
|
||||
public:
|
||||
/* Calls getConnectionData method in nsHttpConnectionMgr. */
|
||||
static void GetHttpConnectionData(nsTArray<HttpRetParams> *);
|
||||
};
|
||||
|
||||
} } // namespace mozilla::net
|
||||
|
||||
#endif // nsHttpInfo__
|
@ -45,6 +45,7 @@ EXPORTS_mozilla/net += \
|
||||
HttpChannelParent.h \
|
||||
HttpChannelChild.h \
|
||||
PHttpChannelParams.h \
|
||||
HttpInfo.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
@ -78,6 +79,7 @@ CPPSRCS = \
|
||||
HttpChannelParent.cpp \
|
||||
HttpChannelChild.cpp \
|
||||
HttpChannelParentListener.cpp \
|
||||
HttpInfo.cpp \
|
||||
NullHttpTransaction.cpp \
|
||||
ASpdySession.cpp \
|
||||
SpdySession2.cpp \
|
||||
|
@ -131,6 +131,7 @@ public:
|
||||
|
||||
bool UsingSpdy() { return !!mUsingSpdyVersion; }
|
||||
bool EverUsedSpdy() { return mEverUsedSpdy; }
|
||||
PRIntervalTime Rtt() { return mRtt; }
|
||||
|
||||
// true when connection SSL NPN phase is complete and we know
|
||||
// authoritatively whether UsingSpdy() or not.
|
||||
|
@ -3187,6 +3187,40 @@ nsConnectionEntry::MaxPipelineDepth(nsAHttpTransaction::Classifier aClass)
|
||||
return mGreenDepth;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
nsHttpConnectionMgr::ReadConnectionEntry(const nsACString &key,
|
||||
nsAutoPtr<nsConnectionEntry> &ent,
|
||||
void *aArg)
|
||||
{
|
||||
nsTArray<HttpRetParams> *args = static_cast<nsTArray<HttpRetParams> *> (aArg);
|
||||
HttpRetParams data;
|
||||
data.host = ent->mConnInfo->Host();
|
||||
data.port = ent->mConnInfo->Port();
|
||||
for (uint32_t i = 0; i < ent->mActiveConns.Length(); i++) {
|
||||
HttpConnInfo info;
|
||||
info.ttl = ent->mActiveConns[i]->TimeToLive();
|
||||
info.rtt = ent->mActiveConns[i]->Rtt();
|
||||
data.active.AppendElement(info);
|
||||
}
|
||||
for (uint32_t i = 0; i < ent->mIdleConns.Length(); i++) {
|
||||
HttpConnInfo info;
|
||||
info.ttl = ent->mIdleConns[i]->TimeToLive();
|
||||
info.rtt = ent->mIdleConns[i]->Rtt();
|
||||
data.active.AppendElement(info);
|
||||
}
|
||||
data.spdy = ent->mUsingSpdy;
|
||||
data.ssl = ent->mConnInfo->UsingSSL();
|
||||
args->AppendElement(data);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
bool
|
||||
nsHttpConnectionMgr::GetConnectionData(nsTArray<mozilla::net::HttpRetParams> *aArg)
|
||||
{
|
||||
mCT.Enumerate(ReadConnectionEntry, aArg);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
nsHttpConnectionMgr::nsConnectionEntry::UnconnectedHalfOpens()
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "nsISocketTransportService.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/net/DashboardTypes.h"
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsITimer.h"
|
||||
@ -223,6 +224,7 @@ public:
|
||||
|
||||
bool SupportsPipelining(nsHttpConnectionInfo *);
|
||||
|
||||
bool GetConnectionData(nsTArray<mozilla::net::HttpRetParams> *);
|
||||
private:
|
||||
virtual ~nsHttpConnectionMgr();
|
||||
|
||||
@ -611,6 +613,11 @@ private:
|
||||
nsTHashtable<nsCStringHashKey> mAlternateProtocolHash;
|
||||
static PLDHashOperator TrimAlternateProtocolHash(nsCStringHashKey *entry,
|
||||
void *closure);
|
||||
|
||||
static PLDHashOperator ReadConnectionEntry(const nsACString &key,
|
||||
nsAutoPtr<nsConnectionEntry> &ent,
|
||||
void *aArg);
|
||||
|
||||
// Read Timeout Tick handlers
|
||||
void ActivateTimeoutTick();
|
||||
void TimeoutTick();
|
||||
|
@ -912,6 +912,8 @@ private:
|
||||
// WebSocketChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
uint32_t WebSocketChannel::sSerialSeed = 0;
|
||||
|
||||
WebSocketChannel::WebSocketChannel() :
|
||||
mPort(0),
|
||||
mCloseTimeout(20000),
|
||||
@ -949,7 +951,8 @@ WebSocketChannel::WebSocketChannel() :
|
||||
mCurrentOutSent(0),
|
||||
mCompressor(nullptr),
|
||||
mDynamicOutputSize(0),
|
||||
mDynamicOutput(nullptr)
|
||||
mDynamicOutput(nullptr),
|
||||
mConnectionLogService(nullptr)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
|
||||
|
||||
@ -959,6 +962,13 @@ WebSocketChannel::WebSocketChannel() :
|
||||
sWebSocketAdmissions = new nsWSAdmissionManager();
|
||||
|
||||
mFramePtr = mBuffer = static_cast<uint8_t *>(moz_xmalloc(mBufferSize));
|
||||
|
||||
nsresult rv;
|
||||
mConnectionLogService = do_GetService("@mozilla.org/network/dashboard;1",&rv);
|
||||
if (NS_FAILED(rv))
|
||||
LOG(("Failed to initiate dashboard service."));
|
||||
|
||||
mSerial = sSerialSeed++;
|
||||
}
|
||||
|
||||
WebSocketChannel::~WebSocketChannel()
|
||||
@ -1320,6 +1330,15 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
||||
}
|
||||
|
||||
NS_DispatchToMainThread(new CallOnMessageAvailable(this, utf8Data, -1));
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mConnectionLogService->NewMsgReceived(host, mSerial, count);
|
||||
LOG(("Added new msg received for %s",host.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (opcode & kControlFrameMask) {
|
||||
// control frames
|
||||
@ -1401,6 +1420,16 @@ WebSocketChannel::ProcessInput(uint8_t *buffer, uint32_t count)
|
||||
nsCString binaryData((const char *)payload, payloadLength);
|
||||
NS_DispatchToMainThread(new CallOnMessageAvailable(this, binaryData,
|
||||
payloadLength));
|
||||
// To add the header to 'Networking Dashboard' log
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mConnectionLogService->NewMsgReceived(host, mSerial, count);
|
||||
LOG(("Added new received msg for %s",host.get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (opcode != kContinuation) {
|
||||
/* unknown opcode */
|
||||
@ -1814,6 +1843,14 @@ WebSocketChannel::CleanupConnection()
|
||||
mTransport = nullptr;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mConnectionLogService->RemoveHost(host, mSerial);
|
||||
}
|
||||
|
||||
DecrementSessionCount();
|
||||
}
|
||||
|
||||
@ -2638,6 +2675,14 @@ WebSocketChannel::AsyncOpen(nsIURI *aURI,
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (mConnectionLogService) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mConnectionLogService->AddHost(host, mSerial, BaseWebSocketChannel::mEncrypted);
|
||||
}
|
||||
}
|
||||
|
||||
rv = ApplyForAdmission();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
@ -2734,6 +2779,16 @@ WebSocketChannel::SendMsgCommon(const nsACString *aMsg, bool aIsBinary,
|
||||
return NS_ERROR_FILE_TOO_BIG;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (mConnectionLogService) {
|
||||
nsAutoCString host;
|
||||
rv = mURI->GetHostPort(host);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mConnectionLogService->NewMsgSent(host, mSerial, aLength);
|
||||
LOG(("Added new msg sent for %s",host.get()));
|
||||
}
|
||||
}
|
||||
|
||||
return mSocketThread->Dispatch(
|
||||
aStream ? new OutboundEnqueuer(this, new OutboundMessage(aStream, aLength))
|
||||
: new OutboundEnqueuer(this,
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIRandomGenerator.h"
|
||||
#include "BaseWebSocketChannel.h"
|
||||
#include "nsIDashboardEventNotifier.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
@ -242,6 +243,10 @@ private:
|
||||
nsWSCompression *mCompressor;
|
||||
uint32_t mDynamicOutputSize;
|
||||
uint8_t *mDynamicOutput;
|
||||
|
||||
nsCOMPtr<nsIDashboardEventNotifier> mConnectionLogService;
|
||||
uint32_t mSerial;
|
||||
static uint32_t sSerialSeed;
|
||||
};
|
||||
|
||||
class WebSocketSSLChannel : public WebSocketChannel
|
||||
|
Loading…
Reference in New Issue
Block a user