Bug 1753703 - P2: Move HttpActivityDistributor to nsHttpHandler, r=necko-reviewers,dragana

Since both DnsAndConnectSocket and nsHttpTransaction use HttpActivityDistributor, let's refactor this a bit by moving some duplicate code to nsHttpHandler.
This patch also makes it possible to test ECH activity for Http3 case.

Differential Revision: https://phabricator.services.mozilla.com/D138893
This commit is contained in:
Kershaw Chang 2022-02-18 09:30:18 +00:00
Родитель c97e0907d3
Коммит 45a4bb9143
11 изменённых файлов: 178 добавлений и 168 удалений

Просмотреть файл

@ -50,21 +50,13 @@ NS_INTERFACE_MAP_BEGIN(DnsAndConnectSocket)
NS_INTERFACE_MAP_ENTRY_CONCRETE(DnsAndConnectSocket)
NS_INTERFACE_MAP_END
static void NotifyActivity(nsIHttpActivityObserver* aActivityDistributor,
nsHttpConnectionInfo* aConnInfo, uint32_t aSubtype) {
nsCOMPtr<nsIHttpActivityObserver> activityDistributor(aActivityDistributor);
static void NotifyActivity(nsHttpConnectionInfo* aConnInfo, uint32_t aSubtype) {
HttpConnectionActivity activity(
aConnInfo->HashKey(), aConnInfo->GetOrigin(), aConnInfo->OriginPort(),
aConnInfo->EndToEndSSL(), !aConnInfo->GetEchConfig().IsEmpty(),
aConnInfo->IsHttp3());
NS_DispatchToMainThread(NS_NewRunnableFunction(
"ObserveActivityWithArgs",
[activityDistributor, activity = std::move(activity),
subType(aSubtype)]() {
Unused << activityDistributor->ObserveActivityWithArgs(
HttpActivityArgs(activity), NS_ACTIVITY_TYPE_HTTP_CONNECTION,
subType, PR_Now(), 0, ""_ns);
}));
gHttpHandler->ObserveHttpActivityWithArgs(
activity, NS_ACTIVITY_TYPE_HTTP_CONNECTION, aSubtype, PR_Now(), 0, ""_ns);
}
DnsAndConnectSocket::DnsAndConnectSocket(nsHttpConnectionInfo* ci,
@ -95,27 +87,10 @@ DnsAndConnectSocket::DnsAndConnectSocket(nsHttpConnectionInfo* ci,
}
MOZ_ASSERT(mConnInfo);
mActivityDistributor = components::HttpActivityDistributor::Service();
if (mActivityDistributor) {
bool activityDistributorActive = false;
Unused << mActivityDistributor->GetIsActive(&activityDistributorActive);
bool observeConnection = false;
nsCOMPtr<nsIHttpActivityDistributor> distributor =
do_QueryInterface(mActivityDistributor);
if (distributor) {
Unused << distributor->GetObserveConnection(&observeConnection);
}
if (!activityDistributorActive || !observeConnection) {
mActivityDistributor = nullptr;
} else {
NotifyActivity(
mActivityDistributor, mConnInfo,
mSpeculative
? NS_HTTP_ACTIVITY_SUBTYPE_SPECULATIVE_DNSANDSOCKET_CREATED
: NS_HTTP_ACTIVITY_SUBTYPE_DNSANDSOCKET_CREATED);
}
}
NotifyActivity(mConnInfo,
mSpeculative
? NS_HTTP_ACTIVITY_SUBTYPE_SPECULATIVE_DNSANDSOCKET_CREATED
: NS_HTTP_ACTIVITY_SUBTYPE_DNSANDSOCKET_CREATED);
}
void DnsAndConnectSocket::CheckIsDone() {
@ -584,10 +559,10 @@ nsresult DnsAndConnectSocket::SetupConn(bool isPrimary, nsresult status) {
nsresult rv = NS_OK;
if (isPrimary) {
rv = mPrimaryTransport.SetupConn(mTransaction, ent, status, mCaps, this,
rv = mPrimaryTransport.SetupConn(mTransaction, ent, status, mCaps,
getter_AddRefs(conn));
} else {
rv = mBackupTransport.SetupConn(mTransaction, ent, status, mCaps, this,
rv = mBackupTransport.SetupConn(mTransaction, ent, status, mCaps,
getter_AddRefs(conn));
}
@ -1021,8 +996,7 @@ nsresult DnsAndConnectSocket::TransportSetup::CheckConnectedResult(
nsresult DnsAndConnectSocket::TransportSetup::SetupConn(
nsAHttpTransaction* transaction, ConnectionEntry* ent, nsresult status,
uint32_t cap, DnsAndConnectSocket* dnsAndSock,
HttpConnectionBase** connection) {
uint32_t cap, HttpConnectionBase** connection) {
RefPtr<HttpConnectionBase> conn;
if (!ent->mConnInfo->IsHttp3()) {
conn = new nsHttpConnection();
@ -1030,10 +1004,7 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupConn(
conn = new HttpConnectionUDP();
}
if (dnsAndSock->mActivityDistributor) {
NotifyActivity(dnsAndSock->mActivityDistributor, ent->mConnInfo,
NS_HTTP_ACTIVITY_SUBTYPE_CONNECTION_CREATED);
}
NotifyActivity(ent->mConnInfo, NS_HTTP_ACTIVITY_SUBTYPE_CONNECTION_CREATED);
LOG(
("DnsAndConnectSocket::SocketTransport::SetupConn "
@ -1249,10 +1220,8 @@ nsresult DnsAndConnectSocket::TransportSetup::SetupStreams(
LOG(("Setting ECH"));
rv = socketTransport->SetEchConfig(ci->GetEchConfig());
NS_ENSURE_SUCCESS(rv, rv);
if (dnsAndSock->mActivityDistributor) {
NotifyActivity(dnsAndSock->mActivityDistributor, dnsAndSock->mConnInfo,
NS_HTTP_ACTIVITY_SUBTYPE_ECH_SET);
}
NotifyActivity(dnsAndSock->mConnInfo, NS_HTTP_ACTIVITY_SUBTYPE_ECH_SET);
}
RefPtr<ConnectionEntry> ent =

Просмотреть файл

@ -19,8 +19,6 @@
#include "nsITransport.h"
#include "nsWeakReference.h"
class nsIHttpActivityObserver;
namespace mozilla {
namespace net {
@ -177,7 +175,6 @@ class DnsAndConnectSocket final : public nsIOutputStreamCallback,
void CloseAll();
nsresult SetupConn(nsAHttpTransaction* transaction, ConnectionEntry* ent,
nsresult status, uint32_t cap,
DnsAndConnectSocket* dnsAndSock,
HttpConnectionBase** connection);
[[nodiscard]] nsresult SetupStreams(DnsAndConnectSocket* dnsAndSock);
nsresult ResolveHost(DnsAndConnectSocket* dnsAndSock);
@ -266,7 +263,6 @@ class DnsAndConnectSocket final : public nsIOutputStreamCallback,
bool mSkipDnsResolution = false;
bool mProxyNotTransparent = false;
bool mProxyTransparentResolvesHost = false;
nsCOMPtr<nsIHttpActivityObserver> mActivityDistributor;
};
NS_DEFINE_STATIC_IID_ACCESSOR(DnsAndConnectSocket, NS_DNSANDCONNECTSOCKET_IID)

Просмотреть файл

@ -12,6 +12,7 @@
#include "mozilla/RefPtr.h"
#include "mozilla/Telemetry.h"
#include "ASpdySession.h" // because of SoftStreamError()
#include "nsIHttpActivityObserver.h"
#include "nsIOService.h"
#include "nsISSLSocketControl.h"
#include "ScopedNSSTypes.h"
@ -160,6 +161,13 @@ nsresult Http3Session::Init(const nsHttpConnectionInfo* aConnInfo,
if (gHttpHandler->EchConfigEnabled(true)) {
mSocketControl->SetEchConfig(mConnInfo->GetEchConfig());
HttpConnectionActivity activity(
mConnInfo->HashKey(), mConnInfo->GetOrigin(), mConnInfo->OriginPort(),
mConnInfo->EndToEndSSL(), !mConnInfo->GetEchConfig().IsEmpty(),
mConnInfo->IsHttp3());
gHttpHandler->ObserveHttpActivityWithArgs(
activity, NS_ACTIVITY_TYPE_HTTP_CONNECTION,
NS_HTTP_ACTIVITY_SUBTYPE_ECH_SET, PR_Now(), 0, ""_ns);
}
// After this line, Http3Session and HttpConnectionUDP become a cycle. We put

Просмотреть файл

@ -139,16 +139,26 @@ nsHttpActivityDistributor::ObserveActivityWithArgs(
return NS_OK;
}
bool nsHttpActivityDistributor::Activated() { return mActivated; }
bool nsHttpActivityDistributor::ObserveProxyResponseEnabled() {
return mObserveProxyResponse;
}
bool nsHttpActivityDistributor::ObserveConnectionEnabled() {
return mObserveConnection;
}
NS_IMETHODIMP
nsHttpActivityDistributor::GetIsActive(bool* isActive) {
NS_ENSURE_ARG_POINTER(isActive);
MutexAutoLock lock(mLock);
if (XRE_IsSocketProcess()) {
*isActive = mActivated;
return NS_OK;
}
*isActive = !!mObservers.Length();
MutexAutoLock lock(mLock);
*isActive = mActivated = !!mObservers.Length();
return NS_OK;
}
@ -162,6 +172,10 @@ NS_IMETHODIMP nsHttpActivityDistributor::SetIsActive(bool aActived) {
NS_IMETHODIMP
nsHttpActivityDistributor::AddObserver(nsIHttpActivityObserver* aObserver) {
MOZ_ASSERT(XRE_IsParentProcess());
if (!NS_IsMainThread()) {
// We only support calling this from the main thread.
return NS_ERROR_FAILURE;
}
ObserverHandle observer(
new ObserverHolder("nsIHttpActivityObserver", aObserver));
@ -175,14 +189,17 @@ nsHttpActivityDistributor::AddObserver(nsIHttpActivityObserver* aObserver) {
mObservers.AppendElement(observer);
}
if (nsIOService::UseSocketProcess() && wasEmpty) {
auto task = []() {
SocketProcessParent* parent = SocketProcessParent::GetSingleton();
if (parent && parent->CanSend()) {
Unused << parent->SendOnHttpActivityDistributorActivated(true);
}
};
gIOService->CallOrWaitForSocketProcess(task);
if (wasEmpty) {
mActivated = true;
if (nsIOService::UseSocketProcess()) {
auto task = []() {
SocketProcessParent* parent = SocketProcessParent::GetSingleton();
if (parent && parent->CanSend()) {
Unused << parent->SendOnHttpActivityDistributorActivated(true);
}
};
gIOService->CallOrWaitForSocketProcess(task);
}
}
return NS_OK;
}
@ -190,18 +207,23 @@ nsHttpActivityDistributor::AddObserver(nsIHttpActivityObserver* aObserver) {
NS_IMETHODIMP
nsHttpActivityDistributor::RemoveObserver(nsIHttpActivityObserver* aObserver) {
MOZ_ASSERT(XRE_IsParentProcess());
if (!NS_IsMainThread()) {
// We only support calling this from the main thread.
return NS_ERROR_FAILURE;
}
ObserverHandle observer(
new ObserverHolder("nsIHttpActivityObserver", aObserver));
bool isEmpty = false;
{
MutexAutoLock lock(mLock);
if (!mObservers.RemoveElement(observer)) return NS_ERROR_FAILURE;
isEmpty = mObservers.IsEmpty();
if (!mObservers.RemoveElement(observer)) {
return NS_ERROR_FAILURE;
}
mActivated = mObservers.IsEmpty();
}
if (nsIOService::UseSocketProcess() && isEmpty) {
if (nsIOService::UseSocketProcess() && !mActivated) {
auto task = []() {
SocketProcessParent* parent = SocketProcessParent::GetSingleton();
if (parent && parent->CanSend()) {
@ -217,15 +239,18 @@ NS_IMETHODIMP
nsHttpActivityDistributor::GetObserveProxyResponse(
bool* aObserveProxyResponse) {
NS_ENSURE_ARG_POINTER(aObserveProxyResponse);
MutexAutoLock lock(mLock);
*aObserveProxyResponse = mObserveProxyResponse;
bool result = mObserveProxyResponse;
*aObserveProxyResponse = result;
return NS_OK;
}
NS_IMETHODIMP
nsHttpActivityDistributor::SetObserveProxyResponse(bool aObserveProxyResponse) {
MutexAutoLock lock(mLock);
if (!NS_IsMainThread()) {
// We only support calling this from the main thread.
return NS_ERROR_FAILURE;
}
mObserveProxyResponse = aObserveProxyResponse;
if (nsIOService::UseSocketProcess()) {
auto task = [aObserveProxyResponse]() {
@ -244,14 +269,17 @@ NS_IMETHODIMP
nsHttpActivityDistributor::GetObserveConnection(bool* aObserveConnection) {
NS_ENSURE_ARG_POINTER(aObserveConnection);
MutexAutoLock lock(mLock);
*aObserveConnection = mObserveConnection;
return NS_OK;
}
NS_IMETHODIMP
nsHttpActivityDistributor::SetObserveConnection(bool aObserveConnection) {
MutexAutoLock lock(mLock);
if (!NS_IsMainThread()) {
// We only support calling this from the main thread.
return NS_ERROR_FAILURE;
}
mObserveConnection = aObserveConnection;
if (nsIOService::UseSocketProcess()) {
auto task = [aObserveConnection]() {

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsIHttpActivityObserver.h"
#include "nsTArray.h"
#include "nsProxyRelease.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
namespace mozilla {
@ -28,9 +29,9 @@ class nsHttpActivityDistributor : public nsIHttpActivityDistributor {
ObserverArray mObservers;
Mutex mLock{"nsHttpActivityDistributor.mLock"};
bool mActivated{false};
bool mObserveProxyResponse{false};
bool mObserveConnection{false};
Atomic<bool, Relaxed> mActivated{false};
Atomic<bool, Relaxed> mObserveProxyResponse{false};
Atomic<bool, Relaxed> mObserveConnection{false};
};
} // namespace net

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsCOMPtr.h"
#include "nsNetCID.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Components.h"
#include "mozilla/Printf.h"
#include "mozilla/Sprintf.h"
#include "mozilla/StaticPrefs_general.h"
@ -47,6 +48,7 @@
#include "nsCRT.h"
#include "nsIParentalControlsService.h"
#include "nsPIDOMWindow.h"
#include "nsIHttpActivityObserver.h"
#include "nsHttpChannelAuthProvider.h"
#include "nsINetworkLinkService.h"
#include "nsNetUtil.h"
@ -393,6 +395,7 @@ nsresult nsHttpHandler::Init() {
usageOfHTTPSRRPrefs[2] = StaticPrefs::network_dns_echconfig_enabled();
Telemetry::ScalarSet(Telemetry::ScalarID::NETWORKING_HTTPS_RR_PREFS_USAGE,
static_cast<uint32_t>(usageOfHTTPSRRPrefs.to_ulong()));
mActivityDistributor = components::HttpActivityDistributor::Service();
}
auto initQLogDir = [&]() {
@ -2222,6 +2225,8 @@ nsHttpHandler::Observe(nsISupports* subject, const char* topic,
Telemetry::Accumulate(Telemetry::DNT_USAGE, 1);
}
}
mActivityDistributor = nullptr;
} else if (!strcmp(topic, "profile-change-net-restore")) {
// initialize connection manager
rv = InitConnectionMgr();
@ -2994,4 +2999,35 @@ bool nsHttpHandler::Is0RttTcpExcluded(const nsHttpConnectionInfo* ci) {
return mExcluded0RttTcpOrigins.Contains(ci->GetOrigin());
}
bool nsHttpHandler::HttpActivityDistributorActivated() {
if (!mActivityDistributor) {
return false;
}
return mActivityDistributor->Activated();
}
void nsHttpHandler::ObserveHttpActivityWithArgs(
const HttpActivityArgs& aArgs, uint32_t aActivityType,
uint32_t aActivitySubtype, PRTime aTimestamp, uint64_t aExtraSizeData,
const nsACString& aExtraStringData) {
if (!HttpActivityDistributorActivated()) {
return;
}
if (aActivitySubtype == NS_HTTP_ACTIVITY_SUBTYPE_PROXY_RESPONSE_HEADER &&
!mActivityDistributor->ObserveProxyResponseEnabled()) {
return;
}
if (aActivityType == NS_ACTIVITY_TYPE_HTTP_CONNECTION &&
!mActivityDistributor->ObserveConnectionEnabled()) {
return;
}
Unused << mActivityDistributor->ObserveActivityWithArgs(
aArgs, aActivityType, aActivitySubtype, aTimestamp, aExtraSizeData,
aExtraStringData);
}
} // namespace mozilla::net

Просмотреть файл

@ -36,6 +36,7 @@
#include "nsIChannel.h"
#include "nsIHttpChannel.h"
class nsIHttpActivityDistributor;
class nsIHttpUpgradeListener;
class nsIPrefBranch;
class nsICancelable;
@ -499,6 +500,13 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
// avoid first-use overhead
static void PresetAcceptLanguages();
bool HttpActivityDistributorActivated();
void ObserveHttpActivityWithArgs(const HttpActivityArgs& aArgs,
uint32_t aActivityType,
uint32_t aActivitySubtype, PRTime aTimestamp,
uint64_t aExtraSizeData,
const nsACString& aExtraStringData);
private:
nsHttpHandler();
@ -849,6 +857,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
// The pref set artificial altSvc-s for origin for testing.
// This maps an origin to an altSvc.
nsClassHashtable<nsCStringHashKey, nsCString> mAltSvcMappingTemptativeMap;
nsCOMPtr<nsIHttpActivityDistributor> mActivityDistributor;
};
extern StaticRefPtr<nsHttpHandler> gHttpHandler;

Просмотреть файл

@ -226,27 +226,6 @@ nsresult nsHttpTransaction::Init(
mTrafficCategory = trafficCategory;
mActivityDistributor = components::HttpActivityDistributor::Service();
if (!mActivityDistributor) {
return NS_ERROR_NOT_AVAILABLE;
}
bool activityDistributorActive;
rv = mActivityDistributor->GetIsActive(&activityDistributorActive);
if (NS_SUCCEEDED(rv) && activityDistributorActive) {
// there are some observers registered at activity distributor, gather
// nsISupports for the channel that called Init()
LOG(
("nsHttpTransaction::Init() "
"mActivityDistributor is active "
"this=%p",
this));
} else {
// there is no observer, so don't use it
activityDistributorActive = false;
mActivityDistributor = nullptr;
}
LOG1(("nsHttpTransaction %p SetRequestContext %p\n", this, requestContext));
mRequestContext = requestContext;
@ -284,18 +263,17 @@ nsresult nsHttpTransaction::Init(
}
// report the request header
if (mActivityDistributor) {
RefPtr<nsHttpTransaction> self = this;
if (gHttpHandler->HttpActivityDistributorActivated()) {
nsCString requestBuf(mReqHeaderBuf);
NS_DispatchToMainThread(
NS_NewRunnableFunction("ObserveActivityWithArgs", [self, requestBuf]() {
nsresult rv = self->mActivityDistributor->ObserveActivityWithArgs(
HttpActivityArgs(self->mChannelId),
NS_DispatchToMainThread(NS_NewRunnableFunction(
"ObserveHttpActivityWithArgs", [channelId(mChannelId), requestBuf]() {
if (!gHttpHandler) {
return;
}
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(channelId),
NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_HEADER, PR_Now(), 0, requestBuf);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
}));
}
@ -643,26 +621,19 @@ void nsHttpTransaction::OnTransportStatus(nsITransport* transport,
// Need to do this before the STATUS_RECEIVING_FROM check below, to make
// sure that the activity distributor gets told about all status events.
if (mActivityDistributor) {
// upon STATUS_WAITING_FOR; report request body sent
if ((mHasRequestBody) && (status == NS_NET_STATUS_WAITING_FOR)) {
nsresult rv = mActivityDistributor->ObserveActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_BODY_SENT, PR_Now(), 0, ""_ns);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
}
// report the status and progress
nsresult rv = mActivityDistributor->ObserveActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT,
static_cast<uint32_t>(status), PR_Now(), progress, ""_ns);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
// upon STATUS_WAITING_FOR; report request body sent
if ((mHasRequestBody) && (status == NS_NET_STATUS_WAITING_FOR)) {
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_BODY_SENT, PR_Now(), 0, ""_ns);
}
// report the status and progress
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT,
static_cast<uint32_t>(status), PR_Now(), progress, ""_ns);
// nsHttpChannel synthesizes progress events in OnDataAvailable
if (status == NS_NET_STATUS_RECEIVING_FROM) return;
@ -1408,27 +1379,19 @@ void nsHttpTransaction::Close(nsresult reason) {
mTokenBucketCancel = nullptr;
}
if (mActivityDistributor) {
// report the reponse is complete if not already reported
if (!mResponseIsComplete) {
nsresult rv = mActivityDistributor->ObserveActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, PR_Now(),
static_cast<uint64_t>(mContentRead), ""_ns);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
}
// report that this transaction is closing
nsresult rv = mActivityDistributor->ObserveActivityWithArgs(
// report the reponse is complete if not already reported
if (!mResponseIsComplete) {
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_TRANSACTION_CLOSE, PR_Now(), 0, ""_ns);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, PR_Now(),
static_cast<uint64_t>(mContentRead), ""_ns);
}
// report that this transaction is closing
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_TRANSACTION_CLOSE, PR_Now(), 0, ""_ns);
// we must no longer reference the connection! find out if the
// connection was being reused before letting it go.
bool connReused = false;
@ -2040,14 +2003,11 @@ nsresult nsHttpTransaction::ParseHead(char* buf, uint32_t count,
if (!mResponseHead) return NS_ERROR_OUT_OF_MEMORY;
// report that we have a least some of the response
if (mActivityDistributor && !mReportedStart) {
if (!mReportedStart) {
mReportedStart = true;
rv = mActivityDistributor->ObserveActivityWithArgs(
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_START, PR_Now(), 0, ""_ns);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
}
}
@ -2392,15 +2352,10 @@ nsresult nsHttpTransaction::HandleContent(char* buf, uint32_t count,
}
// report the entire response has arrived
if (mActivityDistributor) {
rv = mActivityDistributor->ObserveActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, PR_Now(),
static_cast<uint64_t>(mContentRead), ""_ns);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
}
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(mChannelId), NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, PR_Now(),
static_cast<uint64_t>(mContentRead), ""_ns);
}
return NS_OK;
@ -2440,32 +2395,19 @@ nsresult nsHttpTransaction::ProcessData(char* buf, uint32_t count,
// if buf has some content in it, shift bytes to top of buf.
if (count && bytesConsumed) memmove(buf, buf + bytesConsumed, count);
// report the completed response header
if (mActivityDistributor && mResponseHead && mHaveAllHeaders) {
if (mResponseHead && mHaveAllHeaders) {
auto reportResponseHeader = [&](uint32_t aSubType) {
nsAutoCString completeResponseHeaders;
mResponseHead->Flatten(completeResponseHeaders, false);
completeResponseHeaders.AppendLiteral("\r\n");
rv = mActivityDistributor->ObserveActivityWithArgs(
gHttpHandler->ObserveHttpActivityWithArgs(
HttpActivityArgs(mChannelId),
NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, aSubType, PR_Now(), 0,
completeResponseHeaders);
if (NS_FAILED(rv)) {
LOG3(("ObserveActivity failed (%08x)", static_cast<uint32_t>(rv)));
}
};
if (mConnection->IsProxyConnectInProgress()) {
nsCOMPtr<nsIHttpActivityDistributor> distributor =
do_QueryInterface(mActivityDistributor);
bool observeProxyResponse = false;
if (distributor) {
Unused << distributor->GetObserveProxyResponse(&observeProxyResponse);
if (observeProxyResponse) {
reportResponseHeader(
NS_HTTP_ACTIVITY_SUBTYPE_PROXY_RESPONSE_HEADER);
}
}
reportResponseHeader(NS_HTTP_ACTIVITY_SUBTYPE_PROXY_RESPONSE_HEADER);
} else if (!mReportedResponseHeader) {
mReportedResponseHeader = true;
reportResponseHeader(NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_HEADER);

Просмотреть файл

@ -27,7 +27,6 @@
//-----------------------------------------------------------------------------
class nsIHttpActivityObserver;
class nsIDNSHTTPSSVCRecord;
class nsIEventTarget;
class nsIInputStream;
@ -312,7 +311,6 @@ class nsHttpTransaction final : public nsAHttpTransaction,
nsCOMPtr<nsIRequestContext> mRequestContext;
uint64_t mChannelId{0};
nsCOMPtr<nsIHttpActivityObserver> mActivityDistributor;
nsCString mReqHeaderBuf; // flattened request headers
nsCOMPtr<nsIInputStream> mRequestStream;

Просмотреть файл

@ -193,6 +193,13 @@ interface nsIHttpActivityDistributor : nsIHttpActivityObserver
void addObserver(in nsIHttpActivityObserver aObserver);
void removeObserver(in nsIHttpActivityObserver aObserver);
/**
* C++ friendly getter
*/
[noscript, notxpcom] bool Activated();
[noscript, notxpcom] bool ObserveProxyResponseEnabled();
[noscript, notxpcom] bool ObserveConnectionEnabled();
/**
* When true, the ACTIVITY_SUBTYPE_PROXY_RESPONSE_HEADER will be sent to
* the observers.

Просмотреть файл

@ -300,6 +300,13 @@ async function H3ECHTest(echConfig) {
`https://foo.example.com:${trrServer.port}/dns-query`
);
let observerService = Cc[
"@mozilla.org/network/http-activity-distributor;1"
].getService(Ci.nsIHttpActivityDistributor);
let observer = new ActivityObserver();
observerService.addObserver(observer);
observerService.observeConnection = true;
// Only the last record is valid to use.
await trrServer.registerDoHAnswers("public.example.com", "HTTPS", {
answers: [
@ -351,6 +358,14 @@ async function H3ECHTest(echConfig) {
Assert.ok(securityInfo.isAcceptedEch, "This host should have accepted ECH");
await trrServer.stop();
observerService.removeObserver(observer);
observerService.observeConnection = false;
let filtered = observer.activites.filter(
activity => activity.host === "public.example.com"
);
checkHttpActivities(filtered);
}
add_task(async function testH3ConnectWithECH() {