LCOV - code coverage report
Current view: top level - netwerk/base - Dashboard.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 512 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 87 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* This Source Code Form is subject to the terms of the Mozilla Public
       2             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       3             :  * file, You can obtain one at http:mozilla.org/MPL/2.0/. */
       4             : 
       5             : #include "mozilla/dom/NetDashboardBinding.h"
       6             : #include "mozilla/dom/ToJSValue.h"
       7             : #include "mozilla/ErrorNames.h"
       8             : #include "mozilla/net/Dashboard.h"
       9             : #include "mozilla/net/HttpInfo.h"
      10             : #include "nsHttp.h"
      11             : #include "nsICancelable.h"
      12             : #include "nsIDNSService.h"
      13             : #include "nsIDNSRecord.h"
      14             : #include "nsIInputStream.h"
      15             : #include "nsISocketTransport.h"
      16             : #include "nsIThread.h"
      17             : #include "nsProxyRelease.h"
      18             : #include "nsSocketTransportService2.h"
      19             : #include "nsThreadUtils.h"
      20             : #include "nsURLHelper.h"
      21             : #include "mozilla/Logging.h"
      22             : #include "nsIOService.h"
      23             : #include "../cache2/CacheFileUtils.h"
      24             : 
      25             : using mozilla::AutoSafeJSContext;
      26             : using mozilla::dom::Sequence;
      27             : using mozilla::dom::ToJSValue;
      28             : 
      29             : namespace mozilla {
      30             : namespace net {
      31             : 
      32             : class SocketData
      33             :     : public nsISupports
      34             : {
      35             : public:
      36             :     NS_DECL_THREADSAFE_ISUPPORTS
      37             : 
      38           0 :     SocketData()
      39           0 :     {
      40           0 :         mTotalSent = 0;
      41           0 :         mTotalRecv = 0;
      42           0 :         mEventTarget = nullptr;
      43           0 :     }
      44             : 
      45             :     uint64_t mTotalSent;
      46             :     uint64_t mTotalRecv;
      47             :     nsTArray<SocketInfo> mData;
      48             :     nsMainThreadPtrHandle<NetDashboardCallback> mCallback;
      49             :     nsIEventTarget *mEventTarget;
      50             : 
      51             : private:
      52           0 :     virtual ~SocketData()
      53           0 :     {
      54           0 :     }
      55             : };
      56             : 
      57             : static void GetErrorString(nsresult rv, nsAString& errorString);
      58             : 
      59           0 : NS_IMPL_ISUPPORTS0(SocketData)
      60             : 
      61             : 
      62             : class HttpData
      63             :     : public nsISupports
      64             : {
      65           0 :     virtual ~HttpData()
      66           0 :     {
      67           0 :     }
      68             : 
      69             : public:
      70             :     NS_DECL_THREADSAFE_ISUPPORTS
      71             : 
      72           0 :     HttpData()
      73           0 :     {
      74           0 :         mEventTarget = nullptr;
      75           0 :     }
      76             : 
      77             :     nsTArray<HttpRetParams> mData;
      78             :     nsMainThreadPtrHandle<NetDashboardCallback> mCallback;
      79             :     nsIEventTarget *mEventTarget;
      80             : };
      81             : 
      82           0 : NS_IMPL_ISUPPORTS0(HttpData)
      83             : 
      84             : 
      85             : class WebSocketRequest
      86             :     : public nsISupports
      87             : {
      88           0 :     virtual ~WebSocketRequest()
      89           0 :     {
      90           0 :     }
      91             : 
      92             : public:
      93             :     NS_DECL_THREADSAFE_ISUPPORTS
      94             : 
      95           0 :     WebSocketRequest()
      96           0 :     {
      97           0 :         mEventTarget = nullptr;
      98           0 :     }
      99             : 
     100             :     nsMainThreadPtrHandle<NetDashboardCallback> mCallback;
     101             :     nsIEventTarget *mEventTarget;
     102             : };
     103             : 
     104           0 : NS_IMPL_ISUPPORTS0(WebSocketRequest)
     105             : 
     106             : 
     107             : class DnsData
     108             :     : public nsISupports
     109             : {
     110           0 :     virtual ~DnsData()
     111           0 :     {
     112           0 :     }
     113             : 
     114             : public:
     115             :     NS_DECL_THREADSAFE_ISUPPORTS
     116             : 
     117           0 :     DnsData()
     118           0 :     {
     119           0 :         mEventTarget = nullptr;
     120           0 :     }
     121             : 
     122             :     nsTArray<DNSCacheEntries> mData;
     123             :     nsMainThreadPtrHandle<NetDashboardCallback> mCallback;
     124             :     nsIEventTarget *mEventTarget;
     125             : };
     126             : 
     127           0 : NS_IMPL_ISUPPORTS0(DnsData)
     128             : 
     129             : 
     130             : class ConnectionData
     131             :     : public nsITransportEventSink
     132             :     , public nsITimerCallback
     133             : {
     134           0 :     virtual ~ConnectionData()
     135           0 :     {
     136           0 :         if (mTimer) {
     137           0 :             mTimer->Cancel();
     138             :         }
     139           0 :     }
     140             : 
     141             : public:
     142             :     NS_DECL_THREADSAFE_ISUPPORTS
     143             :     NS_DECL_NSITRANSPORTEVENTSINK
     144             :     NS_DECL_NSITIMERCALLBACK
     145             : 
     146             :     void StartTimer(uint32_t aTimeout);
     147             :     void StopTimer();
     148             : 
     149           0 :     explicit ConnectionData(Dashboard *target)
     150           0 :     {
     151           0 :         mEventTarget = nullptr;
     152           0 :         mDashboard = target;
     153           0 :     }
     154             : 
     155             :     nsCOMPtr<nsISocketTransport> mSocket;
     156             :     nsCOMPtr<nsIInputStream> mStreamIn;
     157             :     nsCOMPtr<nsITimer> mTimer;
     158             :     nsMainThreadPtrHandle<NetDashboardCallback> mCallback;
     159             :     nsIEventTarget *mEventTarget;
     160             :     Dashboard *mDashboard;
     161             : 
     162             :     nsCString mHost;
     163             :     uint32_t mPort;
     164             :     const char *mProtocol;
     165             :     uint32_t mTimeout;
     166             : 
     167             :     nsString mStatus;
     168             : };
     169             : 
     170           0 : NS_IMPL_ISUPPORTS(ConnectionData, nsITransportEventSink, nsITimerCallback)
     171             : 
     172             : 
     173             : class RcwnData
     174             :     : public nsISupports
     175             : {
     176           0 :     virtual ~RcwnData()
     177           0 :     {
     178           0 :     }
     179             : 
     180             : public:
     181             :     NS_DECL_THREADSAFE_ISUPPORTS
     182             : 
     183           0 :     RcwnData()
     184           0 :     {
     185           0 :         mEventTarget = nullptr;
     186           0 :     }
     187             : 
     188             :     nsMainThreadPtrHandle<NetDashboardCallback> mCallback;
     189             :     nsIEventTarget *mEventTarget;
     190             : };
     191             : 
     192           0 : NS_IMPL_ISUPPORTS0(RcwnData)
     193             : 
     194             : NS_IMETHODIMP
     195           0 : ConnectionData::OnTransportStatus(nsITransport *aTransport, nsresult aStatus,
     196             :                                   int64_t aProgress, int64_t aProgressMax)
     197             : {
     198           0 :     if (aStatus == NS_NET_STATUS_CONNECTED_TO) {
     199           0 :         StopTimer();
     200             :     }
     201             : 
     202           0 :     GetErrorString(aStatus, mStatus);
     203           0 :     mEventTarget->Dispatch(NewRunnableMethod<RefPtr<ConnectionData>>
     204           0 :                            ("net::Dashboard::GetConnectionStatus",
     205             :                             mDashboard, &Dashboard::GetConnectionStatus, this),
     206           0 :                            NS_DISPATCH_NORMAL);
     207             : 
     208           0 :     return NS_OK;
     209             : }
     210             : 
     211             : NS_IMETHODIMP
     212           0 : ConnectionData::Notify(nsITimer *aTimer)
     213             : {
     214           0 :     MOZ_ASSERT(aTimer == mTimer);
     215             : 
     216           0 :     if (mSocket) {
     217           0 :         mSocket->Close(NS_ERROR_ABORT);
     218           0 :         mSocket = nullptr;
     219           0 :         mStreamIn = nullptr;
     220             :     }
     221             : 
     222           0 :     mTimer = nullptr;
     223             : 
     224           0 :     mStatus.AssignLiteral(u"NS_ERROR_NET_TIMEOUT");
     225           0 :     mEventTarget->Dispatch(NewRunnableMethod<RefPtr<ConnectionData>>
     226           0 :                            ("net::Dashboard::GetConnectionStatus",
     227             :                             mDashboard, &Dashboard::GetConnectionStatus, this),
     228           0 :                            NS_DISPATCH_NORMAL);
     229             : 
     230           0 :     return NS_OK;
     231             : }
     232             : 
     233             : void
     234           0 : ConnectionData::StartTimer(uint32_t aTimeout)
     235             : {
     236           0 :     if (!mTimer) {
     237           0 :         mTimer = do_CreateInstance("@mozilla.org/timer;1");
     238             :     }
     239             : 
     240           0 :     mTimer->InitWithCallback(this, aTimeout * 1000,
     241           0 :         nsITimer::TYPE_ONE_SHOT);
     242           0 : }
     243             : 
     244             : void
     245           0 : ConnectionData::StopTimer()
     246             : {
     247           0 :     if (mTimer) {
     248           0 :         mTimer->Cancel();
     249           0 :         mTimer = nullptr;
     250             :     }
     251           0 : }
     252             : 
     253             : 
     254             : class LookupHelper;
     255             : 
     256             : class LookupArgument
     257             :     : public nsISupports
     258             : {
     259           0 :     virtual ~LookupArgument()
     260           0 :     {
     261           0 :     }
     262             : 
     263             : public:
     264             :     NS_DECL_THREADSAFE_ISUPPORTS
     265             : 
     266           0 :     LookupArgument(nsIDNSRecord *aRecord, LookupHelper *aHelper)
     267           0 :     {
     268           0 :         mRecord = aRecord;
     269           0 :         mHelper = aHelper;
     270           0 :     }
     271             : 
     272             :     nsCOMPtr<nsIDNSRecord> mRecord;
     273             :     RefPtr<LookupHelper> mHelper;
     274             : };
     275             : 
     276           0 : NS_IMPL_ISUPPORTS0(LookupArgument)
     277             : 
     278             : 
     279             : class LookupHelper
     280             :     : public nsIDNSListener
     281             : {
     282           0 :     virtual ~LookupHelper()
     283           0 :     {
     284           0 :         if (mCancel) {
     285           0 :             mCancel->Cancel(NS_ERROR_ABORT);
     286             :         }
     287           0 :     }
     288             : 
     289             : public:
     290             :     NS_DECL_THREADSAFE_ISUPPORTS
     291             :     NS_DECL_NSIDNSLISTENER
     292             : 
     293           0 :     LookupHelper() {
     294           0 :     }
     295             : 
     296             :     nsresult ConstructAnswer(LookupArgument *aArgument);
     297             : public:
     298             :     nsCOMPtr<nsICancelable> mCancel;
     299             :     nsMainThreadPtrHandle<NetDashboardCallback> mCallback;
     300             :     nsIEventTarget *mEventTarget;
     301             :     nsresult mStatus;
     302             : };
     303             : 
     304           0 : NS_IMPL_ISUPPORTS(LookupHelper, nsIDNSListener)
     305             : 
     306             : NS_IMETHODIMP
     307           0 : LookupHelper::OnLookupComplete(nsICancelable *aRequest,
     308             :                                nsIDNSRecord *aRecord, nsresult aStatus)
     309             : {
     310           0 :     MOZ_ASSERT(aRequest == mCancel);
     311           0 :     mCancel = nullptr;
     312           0 :     mStatus = aStatus;
     313             : 
     314           0 :     RefPtr<LookupArgument> arg = new LookupArgument(aRecord, this);
     315           0 :     mEventTarget->Dispatch(NewRunnableMethod<RefPtr<LookupArgument>>
     316           0 :                            ("net::LookupHelper::ConstructAnswer",
     317             :                             this, &LookupHelper::ConstructAnswer, arg),
     318           0 :                            NS_DISPATCH_NORMAL);
     319             : 
     320           0 :     return NS_OK;
     321             : }
     322             : 
     323             : nsresult
     324           0 : LookupHelper::ConstructAnswer(LookupArgument *aArgument)
     325             : {
     326           0 :     nsIDNSRecord *aRecord = aArgument->mRecord;
     327           0 :     AutoSafeJSContext cx;
     328             : 
     329           0 :     mozilla::dom::DNSLookupDict dict;
     330           0 :     dict.mAddress.Construct();
     331             : 
     332           0 :     Sequence<nsString> &addresses = dict.mAddress.Value();
     333             : 
     334           0 :     if (NS_SUCCEEDED(mStatus)) {
     335           0 :         dict.mAnswer = true;
     336             :         bool hasMore;
     337           0 :         aRecord->HasMore(&hasMore);
     338           0 :         while (hasMore) {
     339           0 :             nsString* nextAddress = addresses.AppendElement(fallible);
     340           0 :             if (!nextAddress) {
     341           0 :                 return NS_ERROR_OUT_OF_MEMORY;
     342             :             }
     343             : 
     344           0 :             nsCString nextAddressASCII;
     345           0 :             aRecord->GetNextAddrAsString(nextAddressASCII);
     346           0 :             CopyASCIItoUTF16(nextAddressASCII, *nextAddress);
     347           0 :             aRecord->HasMore(&hasMore);
     348             :         }
     349             :     } else {
     350           0 :         dict.mAnswer = false;
     351           0 :         GetErrorString(mStatus, dict.mError);
     352             :     }
     353             : 
     354           0 :     JS::RootedValue val(cx);
     355           0 :     if (!ToJSValue(cx, dict, &val)) {
     356           0 :         return NS_ERROR_FAILURE;
     357             :     }
     358             : 
     359           0 :     this->mCallback->OnDashboardDataAvailable(val);
     360             : 
     361           0 :     return NS_OK;
     362             : }
     363             : 
     364           0 : NS_IMPL_ISUPPORTS(Dashboard, nsIDashboard, nsIDashboardEventNotifier)
     365             : 
     366           0 : Dashboard::Dashboard()
     367             : {
     368           0 :     mEnableLogging = false;
     369           0 : }
     370             : 
     371           0 : Dashboard::~Dashboard()
     372             : {
     373           0 : }
     374             : 
     375             : NS_IMETHODIMP
     376           0 : Dashboard::RequestSockets(NetDashboardCallback *aCallback)
     377             : {
     378           0 :     RefPtr<SocketData> socketData = new SocketData();
     379           0 :     socketData->mCallback =
     380             :         new nsMainThreadPtrHolder<NetDashboardCallback>(
     381           0 :           "NetDashboardCallback", aCallback, true);
     382           0 :     socketData->mEventTarget = GetCurrentThreadEventTarget();
     383           0 :     gSocketTransportService->Dispatch(NewRunnableMethod<RefPtr<SocketData>>
     384           0 :                                       ("net::Dashboard::GetSocketsDispatch",
     385             :                                        this, &Dashboard::GetSocketsDispatch, socketData),
     386           0 :                                       NS_DISPATCH_NORMAL);
     387           0 :     return NS_OK;
     388             : }
     389             : 
     390             : nsresult
     391           0 : Dashboard::GetSocketsDispatch(SocketData *aSocketData)
     392             : {
     393           0 :     RefPtr<SocketData> socketData = aSocketData;
     394           0 :     if (gSocketTransportService) {
     395           0 :         gSocketTransportService->GetSocketConnections(&socketData->mData);
     396           0 :         socketData->mTotalSent = gSocketTransportService->GetSentBytes();
     397           0 :         socketData->mTotalRecv = gSocketTransportService->GetReceivedBytes();
     398             :     }
     399           0 :     socketData->mEventTarget->Dispatch(NewRunnableMethod<RefPtr<SocketData>>
     400           0 :                                        ("net::Dashboard::GetSockets",
     401             :                                         this, &Dashboard::GetSockets, socketData),
     402           0 :                                        NS_DISPATCH_NORMAL);
     403           0 :     return NS_OK;
     404             : }
     405             : 
     406             : nsresult
     407           0 : Dashboard::GetSockets(SocketData *aSocketData)
     408             : {
     409           0 :     RefPtr<SocketData> socketData = aSocketData;
     410           0 :     AutoSafeJSContext cx;
     411             : 
     412           0 :     mozilla::dom::SocketsDict dict;
     413           0 :     dict.mSockets.Construct();
     414           0 :     dict.mSent = 0;
     415           0 :     dict.mReceived = 0;
     416             : 
     417           0 :     Sequence<mozilla::dom::SocketElement> &sockets = dict.mSockets.Value();
     418             : 
     419           0 :     uint32_t length = socketData->mData.Length();
     420           0 :     if (!sockets.SetCapacity(length, fallible)) {
     421           0 :             JS_ReportOutOfMemory(cx);
     422           0 :             return NS_ERROR_OUT_OF_MEMORY;
     423             :     }
     424             : 
     425           0 :     for (uint32_t i = 0; i < socketData->mData.Length(); i++) {
     426           0 :         dom::SocketElement &mSocket = *sockets.AppendElement(fallible);
     427           0 :         CopyASCIItoUTF16(socketData->mData[i].host, mSocket.mHost);
     428           0 :         mSocket.mPort = socketData->mData[i].port;
     429           0 :         mSocket.mActive = socketData->mData[i].active;
     430           0 :         mSocket.mTcp = socketData->mData[i].tcp;
     431           0 :         mSocket.mSent = (double) socketData->mData[i].sent;
     432           0 :         mSocket.mReceived = (double) socketData->mData[i].received;
     433           0 :         dict.mSent += socketData->mData[i].sent;
     434           0 :         dict.mReceived += socketData->mData[i].received;
     435             :     }
     436             : 
     437           0 :     dict.mSent += socketData->mTotalSent;
     438           0 :     dict.mReceived += socketData->mTotalRecv;
     439           0 :     JS::RootedValue val(cx);
     440           0 :     if (!ToJSValue(cx, dict, &val))
     441           0 :         return NS_ERROR_FAILURE;
     442           0 :     socketData->mCallback->OnDashboardDataAvailable(val);
     443             : 
     444           0 :     return NS_OK;
     445             : }
     446             : 
     447             : NS_IMETHODIMP
     448           0 : Dashboard::RequestHttpConnections(NetDashboardCallback *aCallback)
     449             : {
     450           0 :     RefPtr<HttpData> httpData = new HttpData();
     451           0 :     httpData->mCallback =
     452             :         new nsMainThreadPtrHolder<NetDashboardCallback>(
     453           0 :           "NetDashboardCallback", aCallback, true);
     454           0 :     httpData->mEventTarget = GetCurrentThreadEventTarget();
     455             : 
     456           0 :     gSocketTransportService->Dispatch(
     457           0 :       NewRunnableMethod<RefPtr<HttpData>>("net::Dashboard::GetHttpDispatch",
     458             :                                           this,
     459             :                                           &Dashboard::GetHttpDispatch,
     460             :                                           httpData),
     461           0 :       NS_DISPATCH_NORMAL);
     462           0 :     return NS_OK;
     463             : }
     464             : 
     465             : nsresult
     466           0 : Dashboard::GetHttpDispatch(HttpData *aHttpData)
     467             : {
     468           0 :     RefPtr<HttpData> httpData = aHttpData;
     469           0 :     HttpInfo::GetHttpConnectionData(&httpData->mData);
     470           0 :     httpData->mEventTarget->Dispatch(NewRunnableMethod<RefPtr<HttpData>>
     471           0 :                                      ("net::Dashboard::GetHttpConnections",
     472             :                                       this, &Dashboard::GetHttpConnections, httpData),
     473           0 :                                      NS_DISPATCH_NORMAL);
     474           0 :     return NS_OK;
     475             : }
     476             : 
     477             : 
     478             : nsresult
     479           0 : Dashboard::GetHttpConnections(HttpData *aHttpData)
     480             : {
     481           0 :     RefPtr<HttpData> httpData = aHttpData;
     482           0 :     AutoSafeJSContext cx;
     483             : 
     484           0 :     mozilla::dom::HttpConnDict dict;
     485           0 :     dict.mConnections.Construct();
     486             : 
     487             :     using mozilla::dom::HalfOpenInfoDict;
     488             :     using mozilla::dom::HttpConnectionElement;
     489             :     using mozilla::dom::HttpConnInfo;
     490           0 :     Sequence<HttpConnectionElement> &connections = dict.mConnections.Value();
     491             : 
     492           0 :     uint32_t length = httpData->mData.Length();
     493           0 :     if (!connections.SetCapacity(length, fallible)) {
     494           0 :             JS_ReportOutOfMemory(cx);
     495           0 :             return NS_ERROR_OUT_OF_MEMORY;
     496             :     }
     497             : 
     498           0 :     for (uint32_t i = 0; i < httpData->mData.Length(); i++) {
     499           0 :         HttpConnectionElement &connection = *connections.AppendElement(fallible);
     500             : 
     501           0 :         CopyASCIItoUTF16(httpData->mData[i].host, connection.mHost);
     502           0 :         connection.mPort = httpData->mData[i].port;
     503           0 :         connection.mSpdy = httpData->mData[i].spdy;
     504           0 :         connection.mSsl = httpData->mData[i].ssl;
     505             : 
     506           0 :         connection.mActive.Construct();
     507           0 :         connection.mIdle.Construct();
     508           0 :         connection.mHalfOpens.Construct();
     509             : 
     510           0 :         Sequence<HttpConnInfo> &active = connection.mActive.Value();
     511           0 :         Sequence<HttpConnInfo> &idle = connection.mIdle.Value();
     512           0 :         Sequence<HalfOpenInfoDict> &halfOpens = connection.mHalfOpens.Value();
     513             : 
     514           0 :         if (!active.SetCapacity(httpData->mData[i].active.Length(), fallible) ||
     515           0 :             !idle.SetCapacity(httpData->mData[i].idle.Length(), fallible) ||
     516           0 :             !halfOpens.SetCapacity(httpData->mData[i].halfOpens.Length(),
     517             :                                    fallible)) {
     518           0 :                 JS_ReportOutOfMemory(cx);
     519           0 :                 return NS_ERROR_OUT_OF_MEMORY;
     520             :         }
     521             : 
     522           0 :         for (uint32_t j = 0; j < httpData->mData[i].active.Length(); j++) {
     523           0 :             HttpConnInfo &info = *active.AppendElement(fallible);
     524           0 :             info.mRtt = httpData->mData[i].active[j].rtt;
     525           0 :             info.mTtl = httpData->mData[i].active[j].ttl;
     526             :             info.mProtocolVersion =
     527           0 :                 httpData->mData[i].active[j].protocolVersion;
     528             :         }
     529             : 
     530           0 :         for (uint32_t j = 0; j < httpData->mData[i].idle.Length(); j++) {
     531           0 :             HttpConnInfo &info = *idle.AppendElement(fallible);
     532           0 :             info.mRtt = httpData->mData[i].idle[j].rtt;
     533           0 :             info.mTtl = httpData->mData[i].idle[j].ttl;
     534           0 :             info.mProtocolVersion = httpData->mData[i].idle[j].protocolVersion;
     535             :         }
     536             : 
     537           0 :         for (uint32_t j = 0; j < httpData->mData[i].halfOpens.Length(); j++) {
     538           0 :             HalfOpenInfoDict &info = *halfOpens.AppendElement(fallible);
     539           0 :             info.mSpeculative = httpData->mData[i].halfOpens[j].speculative;
     540             :         }
     541             :     }
     542             : 
     543           0 :     JS::RootedValue val(cx);
     544           0 :     if (!ToJSValue(cx, dict, &val)) {
     545           0 :         return NS_ERROR_FAILURE;
     546             :     }
     547             : 
     548           0 :     httpData->mCallback->OnDashboardDataAvailable(val);
     549             : 
     550           0 :     return NS_OK;
     551             : }
     552             : 
     553             : NS_IMETHODIMP
     554           0 : Dashboard::GetEnableLogging(bool *value)
     555             : {
     556           0 :     *value = mEnableLogging;
     557           0 :     return NS_OK;
     558             : }
     559             : 
     560             : NS_IMETHODIMP
     561           0 : Dashboard::SetEnableLogging(const bool value)
     562             : {
     563           0 :     mEnableLogging = value;
     564           0 :     return NS_OK;
     565             : }
     566             : 
     567             : NS_IMETHODIMP
     568           0 : Dashboard::AddHost(const nsACString& aHost, uint32_t aSerial, bool aEncrypted)
     569             : {
     570           0 :     if (mEnableLogging) {
     571           0 :         mozilla::MutexAutoLock lock(mWs.lock);
     572           0 :         LogData mData(nsCString(aHost), aSerial, aEncrypted);
     573           0 :         if (mWs.data.Contains(mData)) {
     574           0 :             return NS_OK;
     575             :         }
     576           0 :         if (!mWs.data.AppendElement(mData)) {
     577           0 :             return NS_ERROR_OUT_OF_MEMORY;
     578             :         }
     579           0 :         return NS_OK;
     580             :     }
     581           0 :     return NS_ERROR_FAILURE;
     582             : }
     583             : 
     584             : NS_IMETHODIMP
     585           0 : Dashboard::RemoveHost(const nsACString& aHost, uint32_t aSerial)
     586             : {
     587           0 :     if (mEnableLogging) {
     588           0 :         mozilla::MutexAutoLock lock(mWs.lock);
     589           0 :         int32_t index = mWs.IndexOf(nsCString(aHost), aSerial);
     590           0 :         if (index == -1)
     591           0 :             return NS_ERROR_FAILURE;
     592           0 :         mWs.data.RemoveElementAt(index);
     593           0 :         return NS_OK;
     594             :     }
     595           0 :     return NS_ERROR_FAILURE;
     596             : }
     597             : 
     598             : NS_IMETHODIMP
     599           0 : Dashboard::NewMsgSent(const nsACString& aHost, uint32_t aSerial, uint32_t aLength)
     600             : {
     601           0 :     if (mEnableLogging) {
     602           0 :         mozilla::MutexAutoLock lock(mWs.lock);
     603           0 :         int32_t index = mWs.IndexOf(nsCString(aHost), aSerial);
     604           0 :         if (index == -1)
     605           0 :             return NS_ERROR_FAILURE;
     606           0 :         mWs.data[index].mMsgSent++;
     607           0 :         mWs.data[index].mSizeSent += aLength;
     608           0 :         return NS_OK;
     609             :     }
     610           0 :     return NS_ERROR_FAILURE;
     611             : }
     612             : 
     613             : NS_IMETHODIMP
     614           0 : Dashboard::NewMsgReceived(const nsACString& aHost, uint32_t aSerial, uint32_t aLength)
     615             : {
     616           0 :     if (mEnableLogging) {
     617           0 :         mozilla::MutexAutoLock lock(mWs.lock);
     618           0 :         int32_t index = mWs.IndexOf(nsCString(aHost), aSerial);
     619           0 :         if (index == -1)
     620           0 :             return NS_ERROR_FAILURE;
     621           0 :         mWs.data[index].mMsgReceived++;
     622           0 :         mWs.data[index].mSizeReceived += aLength;
     623           0 :         return NS_OK;
     624             :     }
     625           0 :     return NS_ERROR_FAILURE;
     626             : }
     627             : 
     628             : NS_IMETHODIMP
     629           0 : Dashboard::RequestWebsocketConnections(NetDashboardCallback *aCallback)
     630             : {
     631           0 :     RefPtr<WebSocketRequest> wsRequest = new WebSocketRequest();
     632           0 :     wsRequest->mCallback =
     633             :         new nsMainThreadPtrHolder<NetDashboardCallback>(
     634           0 :           "NetDashboardCallback", aCallback, true);
     635           0 :     wsRequest->mEventTarget = GetCurrentThreadEventTarget();
     636             : 
     637           0 :     wsRequest->mEventTarget->Dispatch(NewRunnableMethod<RefPtr<WebSocketRequest>>
     638           0 :                                       ("net::Dashboard::GetWebSocketConnections",
     639             :                                        this, &Dashboard::GetWebSocketConnections, wsRequest),
     640           0 :                                       NS_DISPATCH_NORMAL);
     641           0 :     return NS_OK;
     642             : }
     643             : 
     644             : nsresult
     645           0 : Dashboard::GetWebSocketConnections(WebSocketRequest *aWsRequest)
     646             : {
     647           0 :     RefPtr<WebSocketRequest> wsRequest = aWsRequest;
     648           0 :     AutoSafeJSContext cx;
     649             : 
     650           0 :     mozilla::dom::WebSocketDict dict;
     651           0 :     dict.mWebsockets.Construct();
     652             :     Sequence<mozilla::dom::WebSocketElement> &websockets =
     653           0 :         dict.mWebsockets.Value();
     654             : 
     655           0 :     mozilla::MutexAutoLock lock(mWs.lock);
     656           0 :     uint32_t length = mWs.data.Length();
     657           0 :     if (!websockets.SetCapacity(length, fallible)) {
     658           0 :         JS_ReportOutOfMemory(cx);
     659           0 :         return NS_ERROR_OUT_OF_MEMORY;
     660             :     }
     661             : 
     662           0 :     for (uint32_t i = 0; i < mWs.data.Length(); i++) {
     663           0 :         dom::WebSocketElement &websocket = *websockets.AppendElement(fallible);
     664           0 :         CopyASCIItoUTF16(mWs.data[i].mHost, websocket.mHostport);
     665           0 :         websocket.mMsgsent = mWs.data[i].mMsgSent;
     666           0 :         websocket.mMsgreceived = mWs.data[i].mMsgReceived;
     667           0 :         websocket.mSentsize = mWs.data[i].mSizeSent;
     668           0 :         websocket.mReceivedsize = mWs.data[i].mSizeReceived;
     669           0 :         websocket.mEncrypted = mWs.data[i].mEncrypted;
     670             :     }
     671             : 
     672           0 :     JS::RootedValue val(cx);
     673           0 :     if (!ToJSValue(cx, dict, &val)) {
     674           0 :         return NS_ERROR_FAILURE;
     675             :     }
     676           0 :     wsRequest->mCallback->OnDashboardDataAvailable(val);
     677             : 
     678           0 :     return NS_OK;
     679             : }
     680             : 
     681             : NS_IMETHODIMP
     682           0 : Dashboard::RequestDNSInfo(NetDashboardCallback *aCallback)
     683             : {
     684           0 :     RefPtr<DnsData> dnsData = new DnsData();
     685           0 :     dnsData->mCallback =
     686             :         new nsMainThreadPtrHolder<NetDashboardCallback>(
     687           0 :           "NetDashboardCallback", aCallback, true);
     688             : 
     689             :     nsresult rv;
     690           0 :     dnsData->mData.Clear();
     691           0 :     dnsData->mEventTarget = GetCurrentThreadEventTarget();
     692             : 
     693           0 :     if (!mDnsService) {
     694           0 :         mDnsService = do_GetService("@mozilla.org/network/dns-service;1", &rv);
     695           0 :         if (NS_FAILED(rv)) {
     696           0 :             return rv;
     697             :         }
     698             :     }
     699             : 
     700           0 :     gSocketTransportService->Dispatch(
     701           0 :       NewRunnableMethod<RefPtr<DnsData>>("net::Dashboard::GetDnsInfoDispatch",
     702             :                                          this,
     703             :                                          &Dashboard::GetDnsInfoDispatch,
     704             :                                          dnsData),
     705           0 :       NS_DISPATCH_NORMAL);
     706           0 :     return NS_OK;
     707             : }
     708             : 
     709             : nsresult
     710           0 : Dashboard::GetDnsInfoDispatch(DnsData *aDnsData)
     711             : {
     712           0 :     RefPtr<DnsData> dnsData = aDnsData;
     713           0 :     if (mDnsService) {
     714           0 :         mDnsService->GetDNSCacheEntries(&dnsData->mData);
     715             :     }
     716           0 :     dnsData->mEventTarget->Dispatch(NewRunnableMethod<RefPtr<DnsData>>
     717           0 :                                     ("net::Dashboard::GetDNSCacheEntries",
     718             :                                      this, &Dashboard::GetDNSCacheEntries, dnsData),
     719           0 :                                     NS_DISPATCH_NORMAL);
     720           0 :     return NS_OK;
     721             : }
     722             : 
     723             : nsresult
     724           0 : Dashboard::GetDNSCacheEntries(DnsData *dnsData)
     725             : {
     726           0 :     AutoSafeJSContext cx;
     727             : 
     728           0 :     mozilla::dom::DNSCacheDict dict;
     729           0 :     dict.mEntries.Construct();
     730           0 :     Sequence<mozilla::dom::DnsCacheEntry> &entries = dict.mEntries.Value();
     731             : 
     732           0 :     uint32_t length = dnsData->mData.Length();
     733           0 :     if (!entries.SetCapacity(length, fallible)) {
     734           0 :         JS_ReportOutOfMemory(cx);
     735           0 :         return NS_ERROR_OUT_OF_MEMORY;
     736             :     }
     737             : 
     738           0 :     for (uint32_t i = 0; i < dnsData->mData.Length(); i++) {
     739           0 :         dom::DnsCacheEntry &entry = *entries.AppendElement(fallible);
     740           0 :         entry.mHostaddr.Construct();
     741             : 
     742           0 :         Sequence<nsString> &addrs = entry.mHostaddr.Value();
     743           0 :         if (!addrs.SetCapacity(dnsData->mData[i].hostaddr.Length(), fallible)) {
     744           0 :             JS_ReportOutOfMemory(cx);
     745           0 :             return NS_ERROR_OUT_OF_MEMORY;
     746             :         }
     747             : 
     748           0 :         CopyASCIItoUTF16(dnsData->mData[i].hostname, entry.mHostname);
     749           0 :         entry.mExpiration = dnsData->mData[i].expiration;
     750             : 
     751           0 :         for (uint32_t j = 0; j < dnsData->mData[i].hostaddr.Length(); j++) {
     752           0 :             nsString* addr = addrs.AppendElement(fallible);
     753           0 :             if (!addr) {
     754           0 :                 JS_ReportOutOfMemory(cx);
     755           0 :                 return NS_ERROR_OUT_OF_MEMORY;
     756             :             }
     757           0 :             CopyASCIItoUTF16(dnsData->mData[i].hostaddr[j], *addr);
     758             :         }
     759             : 
     760           0 :         if (dnsData->mData[i].family == PR_AF_INET6) {
     761           0 :             CopyASCIItoUTF16("ipv6", entry.mFamily);
     762             :         } else {
     763           0 :             CopyASCIItoUTF16("ipv4", entry.mFamily);
     764             :         }
     765             :     }
     766             : 
     767           0 :     JS::RootedValue val(cx);
     768           0 :     if (!ToJSValue(cx, dict, &val)) {
     769           0 :         return NS_ERROR_FAILURE;
     770             :     }
     771           0 :     dnsData->mCallback->OnDashboardDataAvailable(val);
     772             : 
     773           0 :     return NS_OK;
     774             : }
     775             : 
     776             : NS_IMETHODIMP
     777           0 : Dashboard::RequestDNSLookup(const nsACString &aHost,
     778             :                             NetDashboardCallback *aCallback)
     779             : {
     780             :     nsresult rv;
     781             : 
     782           0 :     if (!mDnsService) {
     783           0 :         mDnsService = do_GetService("@mozilla.org/network/dns-service;1", &rv);
     784           0 :         if (NS_FAILED(rv)) {
     785           0 :             return rv;
     786             :         }
     787             :     }
     788             : 
     789           0 :     RefPtr<LookupHelper> helper = new LookupHelper();
     790           0 :     helper->mCallback =
     791             :         new nsMainThreadPtrHolder<NetDashboardCallback>(
     792           0 :           "NetDashboardCallback", aCallback, true);
     793           0 :     helper->mEventTarget = GetCurrentThreadEventTarget();
     794           0 :     OriginAttributes attrs;
     795           0 :     rv = mDnsService->AsyncResolveNative(aHost, 0, helper.get(),
     796           0 :                                          NS_GetCurrentThread(), attrs,
     797           0 :                                          getter_AddRefs(helper->mCancel));
     798           0 :     return rv;
     799             : }
     800             : 
     801             : NS_IMETHODIMP
     802           0 : Dashboard::RequestRcwnStats(NetDashboardCallback *aCallback)
     803             : {
     804           0 :     RefPtr<RcwnData> rcwnData = new RcwnData();
     805           0 :     rcwnData->mEventTarget = GetCurrentThreadEventTarget();
     806           0 :     rcwnData->mCallback =
     807             :         new nsMainThreadPtrHolder<NetDashboardCallback>(
     808           0 :           "NetDashboardCallback", aCallback, true);
     809             : 
     810           0 :     return rcwnData->mEventTarget->Dispatch(
     811           0 :       NewRunnableMethod<RefPtr<RcwnData>>("net::Dashboard::GetRcwnData",
     812             :                                           this, &Dashboard::GetRcwnData, rcwnData),
     813           0 :         NS_DISPATCH_NORMAL);
     814             : }
     815             : 
     816             : nsresult
     817           0 : Dashboard::GetRcwnData(RcwnData *aData)
     818             : {
     819           0 :     AutoSafeJSContext cx;
     820           0 :     mozilla::dom::RcwnStatus dict;
     821             : 
     822           0 :     dict.mTotalNetworkRequests = gIOService->GetTotalRequestNumber();
     823           0 :     dict.mRcwnCacheWonCount = gIOService->GetCacheWonRequestNumber();
     824           0 :     dict.mRcwnNetWonCount = gIOService->GetNetWonRequestNumber();
     825             : 
     826             :     uint32_t cacheSlow, cacheNotSlow;
     827           0 :     CacheFileUtils::CachePerfStats::GetSlowStats(&cacheSlow, &cacheNotSlow);
     828           0 :     dict.mCacheSlowCount = cacheSlow;
     829           0 :     dict.mCacheNotSlowCount = cacheNotSlow;
     830             : 
     831           0 :     dict.mPerfStats.Construct();
     832           0 :     Sequence<mozilla::dom::RcwnPerfStats> &perfStats = dict.mPerfStats.Value();
     833           0 :     uint32_t length = CacheFileUtils::CachePerfStats::LAST;
     834           0 :     if (!perfStats.SetCapacity(length, fallible)) {
     835           0 :         JS_ReportOutOfMemory(cx);
     836           0 :         return NS_ERROR_OUT_OF_MEMORY;
     837             :     }
     838             : 
     839           0 :     for (uint32_t i = 0; i < length; i++) {
     840             :         CacheFileUtils::CachePerfStats::EDataType perfType =
     841           0 :             static_cast<CacheFileUtils::CachePerfStats::EDataType>(i);
     842           0 :         dom::RcwnPerfStats &elem = *perfStats.AppendElement(fallible);
     843           0 :         elem.mAvgShort = CacheFileUtils::CachePerfStats::GetAverage(perfType, false);
     844           0 :         elem.mAvgLong = CacheFileUtils::CachePerfStats::GetAverage(perfType, true);
     845           0 :         elem.mStddevLong = CacheFileUtils::CachePerfStats::GetStdDev(perfType, true);
     846             :     }
     847             : 
     848           0 :     JS::RootedValue val(cx);
     849           0 :     if (!ToJSValue(cx, dict, &val)) {
     850           0 :         return NS_ERROR_FAILURE;
     851             :     }
     852             : 
     853           0 :     aData->mCallback->OnDashboardDataAvailable(val);
     854             : 
     855           0 :     return NS_OK;
     856             : }
     857             : 
     858             : void
     859           0 : HttpConnInfo::SetHTTP1ProtocolVersion(uint8_t pv)
     860             : {
     861           0 :     switch (pv) {
     862             :     case NS_HTTP_VERSION_0_9:
     863           0 :         protocolVersion.AssignLiteral(u"http/0.9");
     864           0 :         break;
     865             :     case NS_HTTP_VERSION_1_0:
     866           0 :         protocolVersion.AssignLiteral(u"http/1.0");
     867           0 :         break;
     868             :     case NS_HTTP_VERSION_1_1:
     869           0 :         protocolVersion.AssignLiteral(u"http/1.1");
     870           0 :         break;
     871             :     case NS_HTTP_VERSION_2_0:
     872           0 :         protocolVersion.AssignLiteral(u"http/2.0");
     873           0 :         break;
     874             :     default:
     875           0 :         protocolVersion.AssignLiteral(u"unknown protocol version");
     876             :     }
     877           0 : }
     878             : 
     879             : void
     880           0 : HttpConnInfo::SetHTTP2ProtocolVersion(uint8_t pv)
     881             : {
     882           0 :     MOZ_ASSERT (pv == HTTP_VERSION_2);
     883           0 :     protocolVersion.Assign(u"h2");
     884           0 : }
     885             : 
     886             : NS_IMETHODIMP
     887           0 : Dashboard::GetLogPath(nsACString &aLogPath)
     888             : {
     889           0 :     aLogPath.SetCapacity(2048);
     890           0 :     uint32_t len = LogModule::GetLogFile(aLogPath.BeginWriting(), 2048);
     891           0 :     aLogPath.SetLength(len);
     892           0 :     return NS_OK;
     893             : }
     894             : 
     895             : NS_IMETHODIMP
     896           0 : Dashboard::RequestConnection(const nsACString& aHost, uint32_t aPort,
     897             :                              const char *aProtocol, uint32_t aTimeout,
     898             :                              NetDashboardCallback *aCallback)
     899             : {
     900             :     nsresult rv;
     901           0 :     RefPtr<ConnectionData> connectionData = new ConnectionData(this);
     902           0 :     connectionData->mHost = aHost;
     903           0 :     connectionData->mPort = aPort;
     904           0 :     connectionData->mProtocol = aProtocol;
     905           0 :     connectionData->mTimeout = aTimeout;
     906             : 
     907           0 :     connectionData->mCallback =
     908             :         new nsMainThreadPtrHolder<NetDashboardCallback>(
     909           0 :           "NetDashboardCallback", aCallback, true);
     910           0 :     connectionData->mEventTarget = GetCurrentThreadEventTarget();
     911             : 
     912           0 :     rv = TestNewConnection(connectionData);
     913           0 :     if (NS_FAILED(rv)) {
     914           0 :         mozilla::net::GetErrorString(rv, connectionData->mStatus);
     915           0 :         connectionData->mEventTarget->Dispatch(NewRunnableMethod<RefPtr<ConnectionData>>
     916           0 :                                                ("net::Dashboard::GetConnectionStatus",
     917             :                                                 this, &Dashboard::GetConnectionStatus, connectionData),
     918           0 :                                                NS_DISPATCH_NORMAL);
     919           0 :         return rv;
     920             :     }
     921             : 
     922           0 :     return NS_OK;
     923             : }
     924             : 
     925             : nsresult
     926           0 : Dashboard::GetConnectionStatus(ConnectionData *aConnectionData)
     927             : {
     928           0 :     RefPtr<ConnectionData> connectionData = aConnectionData;
     929           0 :     AutoSafeJSContext cx;
     930             : 
     931           0 :     mozilla::dom::ConnStatusDict dict;
     932           0 :     dict.mStatus = connectionData->mStatus;
     933             : 
     934           0 :     JS::RootedValue val(cx);
     935           0 :     if (!ToJSValue(cx, dict, &val))
     936           0 :         return NS_ERROR_FAILURE;
     937             : 
     938           0 :     connectionData->mCallback->OnDashboardDataAvailable(val);
     939             : 
     940           0 :     return NS_OK;
     941             : }
     942             : 
     943             : nsresult
     944           0 : Dashboard::TestNewConnection(ConnectionData *aConnectionData)
     945             : {
     946           0 :     RefPtr<ConnectionData> connectionData = aConnectionData;
     947             : 
     948             :     nsresult rv;
     949           0 :     if (!connectionData->mHost.Length() ||
     950           0 :         !net_IsValidHostName(connectionData->mHost)) {
     951           0 :         return NS_ERROR_UNKNOWN_HOST;
     952             :     }
     953             : 
     954           0 :     if (connectionData->mProtocol &&
     955           0 :         NS_LITERAL_STRING("ssl").EqualsASCII(connectionData->mProtocol)) {
     956           0 :         rv = gSocketTransportService->CreateTransport(
     957           0 :             &connectionData->mProtocol, 1, connectionData->mHost,
     958           0 :             connectionData->mPort, nullptr,
     959           0 :             getter_AddRefs(connectionData->mSocket));
     960             :     } else {
     961           0 :         rv = gSocketTransportService->CreateTransport(
     962           0 :             nullptr, 0, connectionData->mHost,
     963           0 :             connectionData->mPort, nullptr,
     964           0 :             getter_AddRefs(connectionData->mSocket));
     965             :     }
     966           0 :     if (NS_FAILED(rv)) {
     967           0 :         return rv;
     968             :     }
     969             : 
     970           0 :     rv = connectionData->mSocket->SetEventSink(connectionData,
     971           0 :         GetCurrentThreadEventTarget());
     972           0 :     if (NS_FAILED(rv)) {
     973           0 :         return rv;
     974             :     }
     975             : 
     976           0 :     rv = connectionData->mSocket->OpenInputStream(
     977             :         nsITransport::OPEN_BLOCKING, 0, 0,
     978           0 :         getter_AddRefs(connectionData->mStreamIn));
     979           0 :     if (NS_FAILED(rv)) {
     980           0 :         return rv;
     981             :     }
     982             : 
     983           0 :     connectionData->StartTimer(connectionData->mTimeout);
     984             : 
     985           0 :     return rv;
     986             : }
     987             : 
     988             : typedef struct
     989             : {
     990             :     nsresult key;
     991             :     const char *error;
     992             : } ErrorEntry;
     993             : 
     994             : #undef ERROR
     995             : #define ERROR(key, val) {key, #key}
     996             : 
     997             : ErrorEntry socketTransportStatuses[] = {
     998             :         ERROR(NS_NET_STATUS_RESOLVING_HOST,         FAILURE(3)),
     999             :         ERROR(NS_NET_STATUS_RESOLVED_HOST,          FAILURE(11)),
    1000             :         ERROR(NS_NET_STATUS_CONNECTING_TO,          FAILURE(7)),
    1001             :         ERROR(NS_NET_STATUS_CONNECTED_TO,           FAILURE(4)),
    1002             :         ERROR(NS_NET_STATUS_TLS_HANDSHAKE_STARTING, FAILURE(12)),
    1003             :         ERROR(NS_NET_STATUS_TLS_HANDSHAKE_ENDED,    FAILURE(13)),
    1004             :         ERROR(NS_NET_STATUS_SENDING_TO,             FAILURE(5)),
    1005             :         ERROR(NS_NET_STATUS_WAITING_FOR,            FAILURE(10)),
    1006             :         ERROR(NS_NET_STATUS_RECEIVING_FROM,         FAILURE(6)),
    1007             : };
    1008             : #undef ERROR
    1009             : 
    1010             : 
    1011             : static void
    1012           0 : GetErrorString(nsresult rv, nsAString& errorString)
    1013             : {
    1014           0 :     for (size_t i = 0; i < ArrayLength(socketTransportStatuses); ++i) {
    1015           0 :         if (socketTransportStatuses[i].key == rv) {
    1016           0 :             errorString.AssignASCII(socketTransportStatuses[i].error);
    1017           0 :             return;
    1018             :         }
    1019             :     }
    1020           0 :     nsAutoCString errorCString;
    1021           0 :     mozilla::GetErrorName(rv, errorCString);
    1022           0 :     CopyUTF8toUTF16(errorCString, errorString);
    1023             : }
    1024             : 
    1025             : } // namespace net
    1026             : } // namespace mozilla

Generated by: LCOV version 1.13