diff --git a/netwerk/protocol/http/NullHttpTransaction.cpp b/netwerk/protocol/http/NullHttpTransaction.cpp index edc1c5bee2f3..e8542ebfbb1c 100644 --- a/netwerk/protocol/http/NullHttpTransaction.cpp +++ b/netwerk/protocol/http/NullHttpTransaction.cpp @@ -11,10 +11,82 @@ #include "NullHttpTransaction.h" #include "nsHttpHandler.h" #include "nsHttpRequestHead.h" +#include "nsIHttpActivityObserver.h" +#include "NullHttpChannel.h" namespace mozilla { namespace net { +class CallObserveActivity MOZ_FINAL : public nsIRunnable +{ + ~CallObserveActivity() + { + } +public: + NS_DECL_THREADSAFE_ISUPPORTS + CallObserveActivity(nsIHttpActivityObserver *aActivityDistributor, + const nsCString &aHost, + int32_t aPort, + bool aEndToEndSSL, + uint32_t aActivityType, + uint32_t aActivitySubtype, + PRTime aTimestamp, + uint64_t aExtraSizeData, + const nsACString &aExtraStringData) + : mActivityDistributor(aActivityDistributor) + , mHost(aHost) + , mPort(aPort) + , mEndToEndSSL(aEndToEndSSL) + , mActivityType(aActivityType) + , mActivitySubtype(aActivitySubtype) + , mTimestamp(aTimestamp) + , mExtraSizeData(aExtraSizeData) + , mExtraStringData(aExtraStringData) + { + } + NS_IMETHOD Run() MOZ_OVERRIDE + { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr uri; + nsAutoCString port(NS_LITERAL_CSTRING("")); + if (mPort != -1 && ((mEndToEndSSL && mPort != 443) || + (!mEndToEndSSL && mPort != 80))) { + port.AppendInt(mPort); + } + + nsresult rv = NS_NewURI(getter_AddRefs(uri), + (mEndToEndSSL ? NS_LITERAL_CSTRING("https://") + : NS_LITERAL_CSTRING("http://") ) + mHost + port); + if (NS_FAILED(rv)) { + return NS_OK; + } + + nsRefPtr channel = new NullHttpChannel(); + channel->Init(uri, 0, nullptr, 0, nullptr); + mActivityDistributor->ObserveActivity( + nsCOMPtr(do_QueryObject(channel)), + mActivityType, + mActivitySubtype, + mTimestamp, + mExtraSizeData, + mExtraStringData); + + return NS_OK; + } +private: + nsCOMPtr mActivityDistributor; + nsCString mHost; + int32_t mPort; + bool mEndToEndSSL; + uint32_t mActivityType; + uint32_t mActivitySubtype; + PRTime mTimestamp; + uint64_t mExtraSizeData; + nsCString mExtraStringData; +}; + +NS_IMPL_ISUPPORTS(CallObserveActivity, nsIRunnable) + NS_IMPL_ISUPPORTS(NullHttpTransaction, NullHttpTransaction, nsISupportsWeakReference) NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci, @@ -28,6 +100,24 @@ NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci, , mCallbacks(callbacks) , mConnectionInfo(ci) { + nsresult rv; + mActivityDistributor = do_GetService(NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, + &rv); + if (NS_FAILED(rv)) { + return; + } + + bool activityDistributorActive; + rv = mActivityDistributor->GetIsActive(&activityDistributorActive); + if (NS_SUCCEEDED(rv) && activityDistributorActive) { + // There are some observers registered at activity distributor. + LOG(("NulHttpTransaction::NullHttpTransaction() " + "mActivityDistributor is active " + "[this=%p, %s]", this, ci->GetHost().get())); + } else { + // There is no observer, so don't use it. + mActivityDistributor = nullptr; + } } NullHttpTransaction::~NullHttpTransaction() @@ -59,6 +149,17 @@ void NullHttpTransaction::OnTransportStatus(nsITransport* transport, nsresult status, uint64_t progress) { + if (mActivityDistributor) { + NS_DispatchToMainThread(new CallObserveActivity(mActivityDistributor, + mConnectionInfo->GetHost(), + mConnectionInfo->Port(), + mConnectionInfo->EndToEndSSL(), + NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT, + static_cast(status), + PR_Now(), + progress, + EmptyCString())); + } } bool @@ -129,8 +230,21 @@ NullHttpTransaction::RequestHead() nsresult rv = nsHttpHandler::GenerateHostPort(host, mConnectionInfo->Port(), hostHeader); - if (NS_SUCCEEDED(rv)) - mRequestHead->SetHeader(nsHttp::Host, hostHeader); + if (NS_SUCCEEDED(rv)) { + mRequestHead->SetHeader(nsHttp::Host, hostHeader); + if (mActivityDistributor) { + // Report request headers. + nsCString reqHeaderBuf; + mRequestHead->Flatten(reqHeaderBuf, false); + NS_DispatchToMainThread(new CallObserveActivity(mActivityDistributor, + mConnectionInfo->GetHost(), + mConnectionInfo->Port(), + mConnectionInfo->EndToEndSSL(), + NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, + NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_HEADER, + PR_Now(), 0, reqHeaderBuf)); + } + } // CONNECT tunnels may also want Proxy-Authorization but that is a lot // harder to determine, so for now we will let those connections fail in @@ -159,6 +273,16 @@ NullHttpTransaction::Close(nsresult reason) mStatus = reason; mConnection = nullptr; mIsDone = true; + if (mActivityDistributor) { + // Report that this transaction is closing. + NS_DispatchToMainThread(new CallObserveActivity(mActivityDistributor, + mConnectionInfo->GetHost(), + mConnectionInfo->Port(), + mConnectionInfo->EndToEndSSL(), + NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, + NS_HTTP_ACTIVITY_SUBTYPE_TRANSACTION_CLOSE, + PR_Now(), 0, EmptyCString())); + } } nsHttpConnectionInfo * diff --git a/netwerk/protocol/http/NullHttpTransaction.h b/netwerk/protocol/http/NullHttpTransaction.h index d32ebf622f6b..04031761b26a 100644 --- a/netwerk/protocol/http/NullHttpTransaction.h +++ b/netwerk/protocol/http/NullHttpTransaction.h @@ -15,6 +15,8 @@ // tunnels) so that a nsHttpConnection becomes fully established in // anticipation of a real transaction needing to use it soon. +class nsIHttpActivityObserver; + namespace mozilla { namespace net { class nsAHttpConnection; @@ -65,6 +67,7 @@ protected: nsRefPtr mConnection; nsCOMPtr mCallbacks; nsRefPtr mConnectionInfo; + nsCOMPtr mActivityDistributor; }; NS_DEFINE_STATIC_IID_ACCESSOR(NullHttpTransaction, NS_NULLHTTPTRANSACTION_IID)