mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 890597 - Transport layer ping diagnostic tool. r=valentin.gosu
This commit is contained in:
parent
027842b84f
commit
5167e2015f
@ -16,6 +16,7 @@ interface DummyInterface {
|
||||
void funcHttpConnDict(optional HttpConnDict arg);
|
||||
void funcWebSocketDict(optional WebSocketDict arg);
|
||||
void funcDNSCacheDict(optional DNSCacheDict arg);
|
||||
void funcConnStatusDict(optional ConnStatusDict arg);
|
||||
void frameRequestCallback(FrameRequestCallback arg);
|
||||
void idbObjectStoreParams(optional IDBObjectStoreParameters arg);
|
||||
void CameraPictureOptions(optional CameraPictureOptions arg);
|
||||
|
@ -49,3 +49,8 @@ dictionary DNSCacheDict {
|
||||
sequence<DOMString> family;
|
||||
sequence<double> expiration;
|
||||
};
|
||||
|
||||
dictionary ConnStatusDict {
|
||||
DOMString status;
|
||||
};
|
||||
|
||||
|
@ -35,6 +35,15 @@ interface nsIDashboard : nsISupports
|
||||
/* Arrays: hostname, family, hostaddr, expiration */
|
||||
void requestDNSInfo(in NetDashboardCallback cb);
|
||||
|
||||
/* aProtocol: a transport layer protocol:
|
||||
* ex: "ssl", "tcp", default is "tcp".
|
||||
* aHost: the host's name
|
||||
* aPort: the port which the connection will open on
|
||||
* aTimeout: the timespan before the connection will be timed out */
|
||||
void requestConnection(in ACString aHost, in unsigned long aPort,
|
||||
in string aProtocol, in unsigned long aTimeout,
|
||||
in NetDashboardCallback cb);
|
||||
|
||||
/* When true, the service will log websocket events */
|
||||
attribute boolean enableLogging;
|
||||
};
|
||||
|
@ -13,7 +13,8 @@ using mozilla::AutoSafeJSContext;
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
NS_IMPL_ISUPPORTS2(Dashboard, nsIDashboard, nsIDashboardEventNotifier)
|
||||
NS_IMPL_ISUPPORTS4(Dashboard, nsIDashboard, nsIDashboardEventNotifier,
|
||||
nsITransportEventSink, nsITimerCallback)
|
||||
using mozilla::dom::Sequence;
|
||||
|
||||
Dashboard::Dashboard()
|
||||
@ -495,4 +496,169 @@ HttpConnInfo::SetHTTP2ProtocolVersion(uint8_t pv)
|
||||
protocolVersion.Assign(NS_LITERAL_STRING("spdy/3"));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::RequestConnection(const nsACString& aHost, uint32_t aPort,
|
||||
const char *aProtocol, uint32_t aTimeout,
|
||||
NetDashboardCallback* cb)
|
||||
{
|
||||
nsresult rv;
|
||||
mConn.cb = cb;
|
||||
mConn.thread = NS_GetCurrentThread();
|
||||
|
||||
rv = TestNewConnection(aHost, aPort, aProtocol, aTimeout);
|
||||
if (NS_FAILED(rv)) {
|
||||
ConnStatus status;
|
||||
CopyASCIItoUTF16(GetErrorString(rv), status.creationSts);
|
||||
nsCOMPtr<nsIRunnable> event = new DashConnStatusRunnable(this, status);
|
||||
mConn.thread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Dashboard::GetConnectionStatus(ConnStatus aStatus)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
|
||||
mozilla::dom::ConnStatusDict dict;
|
||||
dict.mStatus.Construct();
|
||||
nsString &status = dict.mStatus.Value();
|
||||
status = aStatus.creationSts;
|
||||
|
||||
JS::RootedValue val(cx);
|
||||
if (!dict.ToObject(cx, JS::NullPtr(), &val)) {
|
||||
mConn.cb = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mConn.cb->OnDashboardDataAvailable(val);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Dashboard::TestNewConnection(const nsACString& aHost, uint32_t aPort,
|
||||
const char *aProtocol, uint32_t aTimeout)
|
||||
{
|
||||
nsresult rv;
|
||||
if (!aHost.Length() || !net_IsValidHostName(aHost))
|
||||
return NS_ERROR_UNKNOWN_HOST;
|
||||
|
||||
if (aProtocol && NS_LITERAL_STRING("ssl").EqualsASCII(aProtocol))
|
||||
rv = gSocketTransportService->CreateTransport(&aProtocol, 1, aHost,
|
||||
aPort, nullptr,
|
||||
getter_AddRefs(mConn.socket));
|
||||
else
|
||||
rv = gSocketTransportService->CreateTransport(nullptr, 0, aHost,
|
||||
aPort, nullptr,
|
||||
getter_AddRefs(mConn.socket));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = mConn.socket->SetEventSink(this, NS_GetCurrentThread());
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = mConn.socket->OpenInputStream(nsITransport::OPEN_BLOCKING, 0, 0,
|
||||
getter_AddRefs(mConn.streamIn));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
StartTimer(aTimeout);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::OnTransportStatus(nsITransport *aTransport, nsresult aStatus,
|
||||
uint64_t aProgress, uint64_t aProgressMax)
|
||||
{
|
||||
if (aStatus == NS_NET_STATUS_CONNECTED_TO)
|
||||
StopTimer();
|
||||
|
||||
ConnStatus status;
|
||||
CopyASCIItoUTF16(GetErrorString(aStatus), status.creationSts);
|
||||
nsCOMPtr<nsIRunnable> event = new DashConnStatusRunnable(this, status);
|
||||
mConn.thread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Dashboard::Notify(nsITimer *timer)
|
||||
{
|
||||
if (mConn.socket) {
|
||||
mConn.socket->Close(NS_ERROR_ABORT);
|
||||
mConn.socket = nullptr;
|
||||
mConn.streamIn = nullptr;
|
||||
}
|
||||
|
||||
mConn.timer = nullptr;
|
||||
|
||||
ConnStatus status;
|
||||
status.creationSts.Assign(NS_LITERAL_STRING("NS_ERROR_NET_TIMEOUT"));
|
||||
nsCOMPtr<nsIRunnable> event = new DashConnStatusRunnable(this, status);
|
||||
mConn.thread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Dashboard::StartTimer(uint32_t aTimeout)
|
||||
{
|
||||
if (!mConn.timer)
|
||||
mConn.timer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mConn.timer->InitWithCallback(this, aTimeout * 1000, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
void
|
||||
Dashboard::StopTimer()
|
||||
{
|
||||
if (mConn.timer) {
|
||||
mConn.timer->Cancel();
|
||||
mConn.timer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nsresult key;
|
||||
const char *error;
|
||||
} ErrorEntry;
|
||||
|
||||
#undef ERROR
|
||||
#define ERROR(key, val) {key, #key}
|
||||
|
||||
ErrorEntry errors[] = {
|
||||
#include "ErrorList.h"
|
||||
};
|
||||
|
||||
ErrorEntry socketTransportStatuses[] = {
|
||||
ERROR(NS_NET_STATUS_RESOLVING_HOST, FAILURE(3)),
|
||||
ERROR(NS_NET_STATUS_RESOLVED_HOST, FAILURE(11)),
|
||||
ERROR(NS_NET_STATUS_CONNECTING_TO, FAILURE(7)),
|
||||
ERROR(NS_NET_STATUS_CONNECTED_TO, FAILURE(4)),
|
||||
ERROR(NS_NET_STATUS_SENDING_TO, FAILURE(5)),
|
||||
ERROR(NS_NET_STATUS_WAITING_FOR, FAILURE(10)),
|
||||
ERROR(NS_NET_STATUS_RECEIVING_FROM, FAILURE(6)),
|
||||
};
|
||||
#undef ERROR
|
||||
|
||||
const char *
|
||||
Dashboard::GetErrorString(nsresult rv)
|
||||
{
|
||||
int length = sizeof(socketTransportStatuses) / sizeof(ErrorEntry);
|
||||
for (int i = 0;i < length;i++)
|
||||
if (socketTransportStatuses[i].key == rv)
|
||||
return socketTransportStatuses[i].error;
|
||||
|
||||
length = sizeof(errors) / sizeof(ErrorEntry);
|
||||
for (int i = 0;i < length;i++)
|
||||
if (errors[i].key == rv)
|
||||
return errors[i].error;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} } // namespace mozilla::net
|
||||
|
@ -15,32 +15,45 @@
|
||||
#include "nsSocketTransport2.h"
|
||||
#include "mozilla/net/DashboardTypes.h"
|
||||
#include "nsHttp.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class Dashboard:
|
||||
public nsIDashboard,
|
||||
public nsIDashboardEventNotifier
|
||||
public nsIDashboardEventNotifier,
|
||||
public nsITransportEventSink,
|
||||
public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIDASHBOARD
|
||||
NS_DECL_NSIDASHBOARDEVENTNOTIFIER
|
||||
NS_DECL_NSITRANSPORTEVENTSINK
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
Dashboard();
|
||||
friend class DashConnStatusRunnable;
|
||||
static const char *GetErrorString(nsresult rv);
|
||||
private:
|
||||
virtual ~Dashboard();
|
||||
|
||||
void GetSocketsDispatch();
|
||||
void GetHttpDispatch();
|
||||
void GetDnsInfoDispatch();
|
||||
void StartTimer(uint32_t aTimeout);
|
||||
void StopTimer();
|
||||
nsresult TestNewConnection(const nsACString& aHost, uint32_t aPort,
|
||||
const char *aProtocol, uint32_t aTimeout);
|
||||
|
||||
/* Helper methods that pass the JSON to the callback function. */
|
||||
nsresult GetSockets();
|
||||
nsresult GetHttpConnections();
|
||||
nsresult GetWebSocketConnections();
|
||||
nsresult GetDNSCacheEntries();
|
||||
nsresult GetConnectionStatus(struct ConnStatus aStatus);
|
||||
|
||||
private:
|
||||
struct SocketData
|
||||
@ -106,13 +119,41 @@ private:
|
||||
nsIThread* thread;
|
||||
};
|
||||
|
||||
struct ConnectionData
|
||||
{
|
||||
nsCOMPtr<nsISocketTransport> socket;
|
||||
nsCOMPtr<nsIInputStream> streamIn;
|
||||
nsCOMPtr<nsITimer> timer;
|
||||
nsCOMPtr<NetDashboardCallback> cb;
|
||||
nsIThread* thread;
|
||||
};
|
||||
|
||||
bool mEnableLogging;
|
||||
|
||||
struct SocketData mSock;
|
||||
struct HttpData mHttp;
|
||||
struct WebSocketData mWs;
|
||||
struct DnsData mDns;
|
||||
struct ConnectionData mConn;
|
||||
};
|
||||
|
||||
class DashConnStatusRunnable: public nsRunnable
|
||||
{
|
||||
public:
|
||||
DashConnStatusRunnable(Dashboard * aDashboard, ConnStatus aStatus)
|
||||
: mDashboard(aDashboard)
|
||||
{
|
||||
mStatus.creationSts = aStatus.creationSts;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
return mDashboard->GetConnectionStatus(mStatus);
|
||||
}
|
||||
|
||||
private:
|
||||
ConnStatus mStatus;
|
||||
Dashboard * mDashboard;
|
||||
};
|
||||
|
||||
} } // namespace mozilla::net
|
||||
|
@ -57,6 +57,11 @@ struct HttpRetParams
|
||||
bool ssl;
|
||||
};
|
||||
|
||||
struct ConnStatus
|
||||
{
|
||||
nsString creationSts;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif // mozilla_net_DashboardTypes_h_
|
||||
|
Loading…
Reference in New Issue
Block a user