Bug 526207: Make IP address and port information available to HTTP activity observers. r=biesi

This commit is contained in:
Honza Bambas 2011-04-10 10:33:08 -07:00
Родитель 5804acdde8
Коммит 27908b070b
11 изменённых файлов: 191 добавлений и 23 удалений

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

@ -1006,6 +1006,36 @@ HttpChannelChild::SetupFallbackChannel(const char *aFallbackKey)
DROP_DEAD(); DROP_DEAD();
} }
// The next four _should_ be implemented, but we need to figure out how
// to transfer the data from the chrome process first.
NS_IMETHODIMP
HttpChannelChild::GetRemoteAddress(nsACString & _result)
{
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
HttpChannelChild::GetRemotePort(PRInt32 * _result)
{
NS_ENSURE_ARG_POINTER(_result);
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
HttpChannelChild::GetLocalAddress(nsACString & _result)
{
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
HttpChannelChild::GetLocalPort(PRInt32 * _result)
{
NS_ENSURE_ARG_POINTER(_result);
return NS_ERROR_NOT_AVAILABLE;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// HttpChannelChild::nsICacheInfoChannel // HttpChannelChild::nsICacheInfoChannel
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

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

@ -109,6 +109,10 @@ public:
PRBool aMerge); PRBool aMerge);
// nsIHttpChannelInternal // nsIHttpChannelInternal
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey); NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
NS_IMETHOD GetLocalAddress(nsACString& addr);
NS_IMETHOD GetLocalPort(PRInt32* port);
NS_IMETHOD GetRemoteAddress(nsACString& addr);
NS_IMETHOD GetRemotePort(PRInt32* port);
// nsISupportsPriority // nsISupportsPriority
NS_IMETHOD SetPriority(PRInt32 value); NS_IMETHOD SetPriority(PRInt32 value);
// nsIResumableChannel // nsIResumableChannel

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

@ -45,6 +45,7 @@ class nsAHttpSegmentReader;
class nsAHttpSegmentWriter; class nsAHttpSegmentWriter;
class nsIInterfaceRequestor; class nsIInterfaceRequestor;
class nsIEventTarget; class nsIEventTarget;
class nsITransport;
class nsHttpRequestHead; class nsHttpRequestHead;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -62,13 +63,14 @@ public:
// called by the connection when it takes ownership of the transaction. // called by the connection when it takes ownership of the transaction.
virtual void SetConnection(nsAHttpConnection *) = 0; virtual void SetConnection(nsAHttpConnection *) = 0;
// called by the connection to get security callbacks to set on the // called by the connection to get security callbacks to set on the
// socket transport. // socket transport.
virtual void GetSecurityCallbacks(nsIInterfaceRequestor **, virtual void GetSecurityCallbacks(nsIInterfaceRequestor **,
nsIEventTarget **) = 0; nsIEventTarget **) = 0;
// called to report socket status (see nsITransportEventSink) // called to report socket status (see nsITransportEventSink)
virtual void OnTransportStatus(nsresult status, PRUint64 progress) = 0; virtual void OnTransportStatus(nsITransport* transport,
nsresult status, PRUint64 progress) = 0;
// called to check the transaction status. // called to check the transaction status.
virtual PRBool IsDone() = 0; virtual PRBool IsDone() = 0;
@ -99,7 +101,8 @@ public:
void SetConnection(nsAHttpConnection *); \ void SetConnection(nsAHttpConnection *); \
void GetSecurityCallbacks(nsIInterfaceRequestor **, \ void GetSecurityCallbacks(nsIInterfaceRequestor **, \
nsIEventTarget **); \ nsIEventTarget **); \
void OnTransportStatus(nsresult status, PRUint64 progress); \ void OnTransportStatus(nsITransport* transport, \
nsresult status, PRUint64 progress); \
PRBool IsDone(); \ PRBool IsDone(); \
nsresult Status(); \ nsresult Status(); \
PRUint32 Available(); \ PRUint32 Available(); \

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

@ -134,13 +134,16 @@ nsHttpChannel::nsHttpChannel()
, mRequestTimeInitialized(PR_FALSE) , mRequestTimeInitialized(PR_FALSE)
{ {
LOG(("Creating nsHttpChannel [this=%p]\n", this)); LOG(("Creating nsHttpChannel [this=%p]\n", this));
// Subfields of unions cannot be targeted in an initializer list
mSelfAddr.raw.family = PR_AF_UNSPEC;
mPeerAddr.raw.family = PR_AF_UNSPEC;
} }
nsHttpChannel::~nsHttpChannel() nsHttpChannel::~nsHttpChannel()
{ {
LOG(("Destroying nsHttpChannel [this=%p]\n", this)); LOG(("Destroying nsHttpChannel [this=%p]\n", this));
if (mAuthProvider) if (mAuthProvider)
mAuthProvider->Disconnect(NS_ERROR_ABORT); mAuthProvider->Disconnect(NS_ERROR_ABORT);
} }
@ -150,7 +153,7 @@ nsHttpChannel::Init(nsIURI *uri,
nsProxyInfo *proxyInfo) nsProxyInfo *proxyInfo)
{ {
nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo); nsresult rv = HttpBaseChannel::Init(uri, caps, proxyInfo);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
LOG(("nsHttpChannel::Init [this=%p]\n", this)); LOG(("nsHttpChannel::Init [this=%p]\n", this));
@ -158,7 +161,7 @@ nsHttpChannel::Init(nsIURI *uri,
mAuthProvider = mAuthProvider =
do_CreateInstance("@mozilla.org/network/http-channel-auth-provider;1", do_CreateInstance("@mozilla.org/network/http-channel-auth-provider;1",
&rv); &rv);
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
rv = mAuthProvider->Init(this); rv = mAuthProvider->Init(this);
@ -3711,6 +3714,66 @@ nsHttpChannel::SetupFallbackChannel(const char *aFallbackKey)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsHttpChannel::GetRemoteAddress(nsACString & _result)
{
if (mPeerAddr.raw.family == PR_AF_UNSPEC)
return NS_ERROR_NOT_AVAILABLE;
_result.SetCapacity(64);
PR_NetAddrToString(&mPeerAddr, _result.BeginWriting(), 64);
_result.SetLength(strlen(_result.BeginReading()));
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetRemotePort(PRInt32 * _result)
{
NS_ENSURE_ARG_POINTER(_result);
if (mPeerAddr.raw.family == PR_AF_INET) {
*_result = (PRInt32)PR_ntohs(mPeerAddr.inet.port);
}
else if (mPeerAddr.raw.family == PR_AF_INET6) {
*_result = (PRInt32)PR_ntohs(mPeerAddr.ipv6.port);
}
else
return NS_ERROR_NOT_AVAILABLE;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetLocalAddress(nsACString & _result)
{
if (mSelfAddr.raw.family == PR_AF_UNSPEC)
return NS_ERROR_NOT_AVAILABLE;
_result.SetCapacity(64);
PR_NetAddrToString(&mSelfAddr, _result.BeginWriting(), 64);
_result.SetLength(strlen(_result.BeginReading()));
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetLocalPort(PRInt32 * _result)
{
NS_ENSURE_ARG_POINTER(_result);
if (mSelfAddr.raw.family == PR_AF_INET) {
*_result = (PRInt32)PR_ntohs(mSelfAddr.inet.port);
}
else if (mSelfAddr.raw.family == PR_AF_INET6) {
*_result = (PRInt32)PR_ntohs(mSelfAddr.ipv6.port);
}
else
return NS_ERROR_NOT_AVAILABLE;
return NS_OK;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// nsHttpChannel::nsISupportsPriority // nsHttpChannel::nsISupportsPriority
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -4153,6 +4216,16 @@ nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status,
if (!mProgressSink) if (!mProgressSink)
GetCallback(mProgressSink); GetCallback(mProgressSink);
if (status == nsISocketTransport::STATUS_CONNECTED_TO ||
status == nsISocketTransport::STATUS_WAITING_FOR) {
nsCOMPtr<nsISocketTransport> socketTransport =
do_QueryInterface(trans);
if (socketTransport) {
socketTransport->GetSelfAddr(&mSelfAddr);
socketTransport->GetPeerAddr(&mPeerAddr);
}
}
// block socket status event after Cancel or OnStopRequest has been called. // block socket status event after Cancel or OnStopRequest has been called.
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) { if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) {
LOG(("sending status notification [this=%p status=%x progress=%llu/%llu]\n", LOG(("sending status notification [this=%p status=%x progress=%llu/%llu]\n",

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

@ -137,6 +137,10 @@ public:
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext); NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext);
// nsIHttpChannelInternal // nsIHttpChannelInternal
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey); NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey);
NS_IMETHOD GetLocalAddress(nsACString& addr);
NS_IMETHOD GetLocalPort(PRInt32* port);
NS_IMETHOD GetRemoteAddress(nsACString& addr);
NS_IMETHOD GetRemotePort(PRInt32* port);
// nsISupportsPriority // nsISupportsPriority
NS_IMETHOD SetPriority(PRInt32 value); NS_IMETHOD SetPriority(PRInt32 value);
// nsIResumableChannel // nsIResumableChannel
@ -347,6 +351,9 @@ private:
// the cache entry's expiration time. Otherwise, it is not(see bug 567360). // the cache entry's expiration time. Otherwise, it is not(see bug 567360).
PRUint32 mRequestTimeInitialized : 1; PRUint32 mRequestTimeInitialized : 1;
PRNetAddr mSelfAddr;
PRNetAddr mPeerAddr;
nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack; nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack;
nsCOMPtr<nsICryptoHash> mHasher; nsCOMPtr<nsICryptoHash> mHasher;

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

@ -615,7 +615,8 @@ nsHttpConnection::OnSocketWritable()
// here to reflect the fact that we are waiting. this message will be // here to reflect the fact that we are waiting. this message will be
// trumped (overwritten) if the server responds quickly. // trumped (overwritten) if the server responds quickly.
// //
mTransaction->OnTransportStatus(nsISocketTransport::STATUS_WAITING_FOR, mTransaction->OnTransportStatus(mSocketTransport,
nsISocketTransport::STATUS_WAITING_FOR,
LL_ZERO); LL_ZERO);
rv = mSocketIn->AsyncWait(this, 0, 0, nsnull); // start reading rv = mSocketIn->AsyncWait(this, 0, 0, nsnull); // start reading
@ -811,7 +812,7 @@ nsHttpConnection::OnTransportStatus(nsITransport *trans,
PRUint64 progressMax) PRUint64 progressMax)
{ {
if (mTransaction) if (mTransaction)
mTransaction->OnTransportStatus(status, progress); mTransaction->OnTransportStatus(trans, status, progress);
return NS_OK; return NS_OK;
} }

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

@ -1491,7 +1491,7 @@ nsHttpConnectionMgr::nsHalfOpenSocket::OnTransportStatus(nsITransport *trans,
PRUint64 progressMax) PRUint64 progressMax)
{ {
if (mTransaction) if (mTransaction)
mTransaction->OnTransportStatus(status, progress); mTransaction->OnTransportStatus(trans, status, progress);
return NS_OK; return NS_OK;
} }

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

@ -367,7 +367,8 @@ nsHttpPipeline::GetSecurityCallbacks(nsIInterfaceRequestor **result,
} }
void void
nsHttpPipeline::OnTransportStatus(nsresult status, PRUint64 progress) nsHttpPipeline::OnTransportStatus(nsITransport* transport,
nsresult status, PRUint64 progress)
{ {
LOG(("nsHttpPipeline::OnStatus [this=%x status=%x progress=%llu]\n", LOG(("nsHttpPipeline::OnStatus [this=%x status=%x progress=%llu]\n",
this, status, progress)); this, status, progress));
@ -377,10 +378,10 @@ nsHttpPipeline::OnTransportStatus(nsresult status, PRUint64 progress)
nsAHttpTransaction *trans; nsAHttpTransaction *trans;
switch (status) { switch (status) {
case NS_NET_STATUS_RECEIVING_FROM: case NS_NET_STATUS_RECEIVING_FROM:
// forward this only to the transaction currently recieving data // forward this only to the transaction currently recieving data
trans = Response(0); trans = Response(0);
if (trans) if (trans)
trans->OnTransportStatus(status, progress); trans->OnTransportStatus(transport, status, progress);
break; break;
default: default:
// forward other notifications to all transactions // forward other notifications to all transactions
@ -388,7 +389,7 @@ nsHttpPipeline::OnTransportStatus(nsresult status, PRUint64 progress)
for (i=0; i<count; ++i) { for (i=0; i<count; ++i) {
trans = Request(i); trans = Request(i);
if (trans) if (trans)
trans->OnTransportStatus(status, progress); trans->OnTransportStatus(transport, status, progress);
} }
break; break;
} }

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

@ -351,14 +351,15 @@ nsHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **cb,
} }
void void
nsHttpTransaction::OnTransportStatus(nsresult status, PRUint64 progress) nsHttpTransaction::OnTransportStatus(nsITransport* transport,
nsresult status, PRUint64 progress)
{ {
LOG(("nsHttpTransaction::OnSocketStatus [this=%x status=%x progress=%llu]\n", LOG(("nsHttpTransaction::OnSocketStatus [this=%x status=%x progress=%llu]\n",
this, status, progress)); this, status, progress));
if (!mTransportSink) if (!mTransportSink)
return; return;
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
// Need to do this before the STATUS_RECEIVING_FROM check below, to make // Need to do this before the STATUS_RECEIVING_FROM check below, to make
@ -410,7 +411,7 @@ nsHttpTransaction::OnTransportStatus(nsresult status, PRUint64 progress)
progressMax = 0; progressMax = 0;
} }
mTransportSink->OnTransportStatus(nsnull, status, progress, progressMax); mTransportSink->OnTransportStatus(transport, status, progress, progressMax);
} }
PRBool PRBool

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

@ -46,12 +46,12 @@ class nsCString;
interface nsIURI; interface nsIURI;
interface nsIProxyInfo; interface nsIProxyInfo;
/** /**
* Dumping ground for http. This interface will never be frozen. If you are * Dumping ground for http. This interface will never be frozen. If you are
* using any feature exposed by this interface, be aware that this interface * using any feature exposed by this interface, be aware that this interface
* will change and you will be broken. You have been warned. * will change and you will be broken. You have been warned.
*/ */
[scriptable, uuid(44e35ead-6656-4f9e-b51d-ebaf1bee6e2e)] [scriptable, uuid(12eb906a-71fe-4b79-b33a-6fe9ab57ea38)]
interface nsIHttpChannelInternal : nsISupports interface nsIHttpChannelInternal : nsISupports
{ {
/** /**
@ -91,17 +91,58 @@ interface nsIHttpChannelInternal : nsISupports
attribute boolean forceAllowThirdPartyCookie; attribute boolean forceAllowThirdPartyCookie;
/** /**
* Returns true iff the channel has been canceled. * True iff the channel has been canceled.
*/ */
readonly attribute boolean canceled; readonly attribute boolean canceled;
/** /**
* Lets externalhandler tell the channel it is open on behalf of a download * External handlers may set this to true to notify the channel
* that it is open on behalf of a download.
*/ */
attribute boolean channelIsForDownload; attribute boolean channelIsForDownload;
/** /**
* Transfer chain of redirected cache-keys * The local IP address to which this channel is bound, in the
* format produced by PR_NetAddrToString. May be IPv4 or IPv6.
* Note: in the presence of NAT, this may not be the same as the
* address that the remote host thinks it's talking to.
*
* May throw NS_ERROR_NOT_AVAILABLE if accessed when the channel's
* endpoints are not yet determined, or in any case when
* nsIHttpActivityObserver.isActive is false. See bugs 534698 and 526207.
*/
readonly attribute AUTF8String localAddress;
/**
* The local port number to which this channel is bound.
*
* May throw NS_ERROR_NOT_AVAILABLE if accessed when the channel's
* endpoints are not yet determined, or in any case when
* nsIHttpActivityObserver.isActive is false. See bugs 534698 and 526207.
*/
readonly attribute PRInt32 localPort;
/**
* The IP address of the remote host that this channel is
* connected to, in the format produced by PR_NetAddrToString.
*
* May throw NS_ERROR_NOT_AVAILABLE if accessed when the channel's
* endpoints are not yet determined, or in any case when
* nsIHttpActivityObserver.isActive is false. See bugs 534698 and 526207.
*/
readonly attribute AUTF8String remoteAddress;
/**
* The remote port number that this channel is connected to.
*
* May throw NS_ERROR_NOT_AVAILABLE if accessed when the channel's
* endpoints are not yet determined, or in any case when
* nsIHttpActivityObserver.isActive is false. See bugs 534698 and 526207.
*/
readonly attribute PRInt32 remotePort;
/**
* Transfer chain of redirected cache-keys.
*/ */
[noscript] void setCacheKeysRedirectChain(in StringArray cacheKeys); [noscript] void setCacheKeysRedirectChain(in StringArray cacheKeys);
}; };

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

@ -20,6 +20,13 @@ TracingListener.prototype = {
gotOnStartRequest = true; gotOnStartRequest = true;
request.QueryInterface(Components.interfaces.nsIHttpChannelInternal);
do_check_eq(request.localAddress, "127.0.0.1");
do_check_eq(request.localPort > 0, true);
do_check_neq(request.localPort, 4444);
do_check_eq(request.remoteAddress, "127.0.0.1");
do_check_eq(request.remotePort, 4444);
// Make sure listener can't be replaced after OnStartRequest was called. // Make sure listener can't be replaced after OnStartRequest was called.
request.QueryInterface(Components.interfaces.nsITraceableChannel); request.QueryInterface(Components.interfaces.nsITraceableChannel);
try { try {