Bug 576006 - Implement timing interface for channels

r=jduell sr=bz
This commit is contained in:
Christian Biesinger 2011-05-21 03:03:36 -07:00
Родитель c4c3837042
Коммит a6e0fccb1f
17 изменённых файлов: 400 добавлений и 3 удалений

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

@ -1021,6 +1021,7 @@ NS_IMETHODIMP nsWebBrowserPersist::OnStatus(
switch ( status )
{
case NS_NET_STATUS_RESOLVING_HOST:
case NS_NET_STATUS_RESOLVED_HOST:
case NS_NET_STATUS_BEGIN_FTP_TRANSACTION:
case NS_NET_STATUS_END_FTP_TRANSACTION:
case NS_NET_STATUS_CONNECTING_TO:

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

@ -112,6 +112,7 @@ XPIDLSRCS = \
nsIStreamLoader.idl \
nsISyncStreamListener.idl \
nsISystemProxySettings.idl \
nsITimedChannel.idl \
nsIUnicharStreamLoader.idl \
nsIUploadChannel2.idl \
nsIStandardURL.idl \

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

@ -133,6 +133,7 @@ interface nsISocketTransport : nsITransport
* of this interface may choose not to generate.
*/
const unsigned long STATUS_RESOLVING = 0x804b0003;
const unsigned long STATUS_RESOLVED = 0x804b000b;
const unsigned long STATUS_CONNECTING_TO = 0x804b0007;
const unsigned long STATUS_CONNECTED_TO = 0x804b0004;
const unsigned long STATUS_SENDING_TO = 0x804b0005;
@ -179,6 +180,7 @@ interface nsISocketTransport : nsITransport
* #define's for compatibility
*/
#define NS_NET_STATUS_RESOLVING_HOST nsISocketTransport::STATUS_RESOLVING
#define NS_NET_STATUS_RESOLVED_HOST nsISocketTransport::STATUS_RESOLVED
#define NS_NET_STATUS_CONNECTED_TO nsISocketTransport::STATUS_CONNECTED_TO
#define NS_NET_STATUS_SENDING_TO nsISocketTransport::STATUS_SENDING_TO
#define NS_NET_STATUS_RECEIVING_FROM nsISocketTransport::STATUS_RECEIVING_FROM

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

@ -0,0 +1,85 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla networking code.
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christian Biesinger <cbiesinger@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
%{C++
namespace mozilla {
class TimeStamp;
}
%}
native TimeStamp(mozilla::TimeStamp);
// All properties return zero if the value is not available
[scriptable, uuid(c259b593-a9bf-4d08-8149-ef89e1977dc4)]
interface nsITimedChannel : nsISupports {
// Set this attribute to true to enable collection of timing data.
// channelCreationTime will be available even with this attribute set to
// false.
attribute boolean timingEnabled;
[notxpcom] readonly attribute TimeStamp channelCreation;
[notxpcom] readonly attribute TimeStamp asyncOpen;
// The following are only set when the document is not (only) read from the
// cache
[notxpcom] readonly attribute TimeStamp domainLookupStart;
[notxpcom] readonly attribute TimeStamp domainLookupEnd;
[notxpcom] readonly attribute TimeStamp connectStart;
[notxpcom] readonly attribute TimeStamp connectEnd;
[notxpcom] readonly attribute TimeStamp requestStart;
[notxpcom] readonly attribute TimeStamp responseStart;
[notxpcom] readonly attribute TimeStamp responseEnd;
// The following are only set if the document is (partially) read from the
// cache
[notxpcom] readonly attribute TimeStamp cacheReadStart;
[notxpcom] readonly attribute TimeStamp cacheReadEnd;
// All following are PRTime versions of the above.
readonly attribute PRTime channelCreationTime;
readonly attribute PRTime asyncOpenTime;
readonly attribute PRTime domainLookupStartTime;
readonly attribute PRTime domainLookupEndTime;
readonly attribute PRTime connectStartTime;
readonly attribute PRTime connectEndTime;
readonly attribute PRTime requestStartTime;
readonly attribute PRTime responseStartTime;
readonly attribute PRTime responseEndTime;
readonly attribute PRTime cacheReadStartTime;
readonly attribute PRTime cacheReadEndTime;
};

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

@ -943,14 +943,12 @@ nsSocketTransport::ResolveHost()
if (mConnectionFlags & nsSocketTransport::BYPASS_CACHE)
dnsFlags = nsIDNSService::RESOLVE_BYPASS_CACHE;
SendStatus(STATUS_RESOLVING);
rv = dns->AsyncResolve(SocketHost(), dnsFlags, this, nsnull,
getter_AddRefs(mDNSRequest));
if (NS_SUCCEEDED(rv)) {
SOCKET_LOG((" advancing to STATE_RESOLVING\n"));
mState = STATE_RESOLVING;
// only report that we are resolving if we are still resolving...
if (mResolving)
SendStatus(STATUS_RESOLVING);
}
return rv;
}
@ -1439,6 +1437,9 @@ nsSocketTransport::OnSocketEvent(PRUint32 type, nsresult status, nsISupports *pa
break;
case MSG_DNS_LOOKUP_COMPLETE:
if (mDNSRequest) // only send this if we actually resolved anything
SendStatus(STATUS_RESOLVED);
SOCKET_LOG((" MSG_DNS_LOOKUP_COMPLETE\n"));
mDNSRequest = 0;
if (param) {

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

@ -48,6 +48,7 @@
8=Read %1$S
9=Wrote %1$S
10=Waiting for %1$S…
11=Looked up %1$S…
27=Beginning FTP transaction…
28=Finished FTP transaction

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

@ -2015,6 +2015,7 @@ nsFtpState::OnTransportStatus(nsITransport *transport, nsresult status,
if (mControlConnection && transport == mControlConnection->Transport()) {
switch (status) {
case NS_NET_STATUS_RESOLVING_HOST:
case NS_NET_STATUS_RESOLVED_HOST:
case NS_NET_STATUS_CONNECTING_TO:
case NS_NET_STATUS_CONNECTED_TO:
break;

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

@ -48,6 +48,7 @@
#include "nsICachingChannel.h"
#include "nsISeekableStream.h"
#include "nsITimedChannel.h"
#include "nsIEncodedChannel.h"
#include "nsIResumableChannel.h"
#include "nsIApplicationCacheChannel.h"
@ -78,6 +79,7 @@ HttpBaseChannel::HttpBaseChannel()
, mChooseApplicationCache(PR_FALSE)
, mLoadedFromApplicationCache(PR_FALSE)
, mChannelIsForDownload(PR_FALSE)
, mTimingEnabled(PR_FALSE)
, mRedirectedCachekeys(nsnull)
{
LOG(("Creating HttpBaseChannel @%x\n", this));
@ -1490,6 +1492,11 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
if (bag)
mPropertyHash.EnumerateRead(CopyProperties, bag.get());
// transfer timed channel enabled status
nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(newChannel));
if (timed)
timed->SetTimingEnabled(mTimingEnabled);
return NS_OK;
}

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

@ -274,6 +274,8 @@ protected:
PRUint32 mChooseApplicationCache : 1;
PRUint32 mLoadedFromApplicationCache : 1;
PRUint32 mChannelIsForDownload : 1;
// True if timing collection is enabled
PRUint32 mTimingEnabled : 1;
nsTArray<nsCString> *mRedirectedCachekeys;
};

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

@ -0,0 +1,57 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla networking code.
*
* The Initial Developer of the Original Code is
* Google Inc.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Christian Biesinger <cbiesinger@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef TimingStruct_h_
#define TimingStruct_h_
#include "mozilla/TimeStamp.h"
struct TimingStruct {
mozilla::TimeStamp channelCreation;
mozilla::TimeStamp asyncOpen;
mozilla::TimeStamp domainLookupStart;
mozilla::TimeStamp domainLookupEnd;
mozilla::TimeStamp connectStart;
mozilla::TimeStamp connectEnd;
mozilla::TimeStamp requestStart;
mozilla::TimeStamp responseStart;
mozilla::TimeStamp responseEnd;
};
#endif

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

@ -123,6 +123,9 @@ typedef PRUint8 nsHttpVersion;
// to the server (see bug #466080), but is may also be used for other things
#define NS_HTTP_LOAD_ANONYMOUS (1<<4)
// a transaction with this caps flag keeps timing information
#define NS_HTTP_TIMING_ENABLED (1<<5)
//-----------------------------------------------------------------------------
// some default values
//-----------------------------------------------------------------------------

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

@ -45,7 +45,9 @@
*
* ***** END LICENSE BLOCK ***** */
#ifdef MOZ_IPC
#include "base/basictypes.h"
#endif
#include "nsHttpChannel.h"
#include "nsHttpHandler.h"
@ -68,6 +70,7 @@
#include "nsDNSPrefetch.h"
#include "nsChannelClassifier.h"
#include "nsIRedirectResultListener.h"
#include "mozilla/TimeStamp.h"
// True if the local cache should be bypassed when processing a request.
#define BYPASS_LOCAL_CACHE(loadFlags) \
@ -134,6 +137,8 @@ nsHttpChannel::nsHttpChannel()
, mRequestTimeInitialized(PR_FALSE)
{
LOG(("Creating nsHttpChannel [this=%p]\n", this));
mChannelCreationTime = PR_Now();
mChannelCreationTimestamp = mozilla::TimeStamp::Now();
// Subfields of unions cannot be targeted in an initializer list
mSelfAddr.raw.family = PR_AF_UNSPEC;
mPeerAddr.raw.family = PR_AF_UNSPEC;
@ -663,6 +668,9 @@ nsHttpChannel::SetupTransaction()
if (mLoadFlags & LOAD_ANONYMOUS)
mCaps |= NS_HTTP_LOAD_ANONYMOUS;
if (mTimingEnabled)
mCaps |= NS_HTTP_TIMING_ENABLED;
mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
if (mUpgradeProtocolCallback) {
@ -2857,6 +2865,9 @@ nsHttpChannel::ReadFromCache()
rv = mCachePump->AsyncRead(this, mListenerContext);
if (NS_FAILED(rv)) return rv;
if (mTimingEnabled)
mCacheReadStart = mozilla::TimeStamp::Now();
PRUint32 suspendCount = mSuspendCount;
while (suspendCount--)
mCachePump->Suspend();
@ -3545,6 +3556,7 @@ NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheContainer)
NS_INTERFACE_MAP_ENTRY(nsIApplicationCacheChannel)
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
NS_INTERFACE_MAP_ENTRY(nsITimedChannel)
NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)
//-----------------------------------------------------------------------------
@ -3642,6 +3654,9 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
if (mCanceled)
return mStatus;
if (mTimingEnabled)
mAsyncOpenTime = mozilla::TimeStamp::Now();
rv = NS_CheckPortSafety(mURI);
if (NS_FAILED(rv))
return rv;
@ -3785,6 +3800,137 @@ nsHttpChannel::GetProxyInfo(nsIProxyInfo **result)
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsHttpChannel::nsITimedChannel
//-----------------------------------------------------------------------------
NS_IMETHODIMP
nsHttpChannel::SetTimingEnabled(PRBool enabled) {
mTimingEnabled = enabled;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetTimingEnabled(PRBool* _retval) {
*_retval = mTimingEnabled;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetChannelCreation(mozilla::TimeStamp* _retval) {
*_retval = mChannelCreationTimestamp;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetAsyncOpen(mozilla::TimeStamp* _retval) {
*_retval = mAsyncOpenTime;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetDomainLookupStart(mozilla::TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->Timings().domainLookupStart;
else
*_retval = mTransactionTimings.domainLookupStart;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetDomainLookupEnd(mozilla::TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->Timings().domainLookupEnd;
else
*_retval = mTransactionTimings.domainLookupEnd;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetConnectStart(mozilla::TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->Timings().connectStart;
else
*_retval = mTransactionTimings.connectStart;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetConnectEnd(mozilla::TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->Timings().connectEnd;
else
*_retval = mTransactionTimings.connectEnd;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetRequestStart(mozilla::TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->Timings().requestStart;
else
*_retval = mTransactionTimings.requestStart;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetResponseStart(mozilla::TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->Timings().responseStart;
else
*_retval = mTransactionTimings.responseStart;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetResponseEnd(mozilla::TimeStamp* _retval) {
if (mTransaction)
*_retval = mTransaction->Timings().responseEnd;
else
*_retval = mTransactionTimings.responseEnd;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetCacheReadStart(mozilla::TimeStamp* _retval) {
*_retval = mCacheReadStart;
return NS_OK;
}
NS_IMETHODIMP
nsHttpChannel::GetCacheReadEnd(mozilla::TimeStamp* _retval) {
*_retval = mCacheReadEnd;
return NS_OK;
}
#define IMPL_TIMING_ATTR(name) \
NS_IMETHODIMP \
nsHttpChannel::Get##name##Time(PRTime* _retval) { \
mozilla::TimeStamp stamp; \
Get##name(&stamp); \
if (stamp.IsNull()) { \
*_retval = 0; \
return NS_OK; \
} \
*_retval = mChannelCreationTime + \
(stamp - mChannelCreationTimestamp).ToSeconds() * 1e6; \
return NS_OK; \
}
IMPL_TIMING_ATTR(ChannelCreation)
IMPL_TIMING_ATTR(AsyncOpen)
IMPL_TIMING_ATTR(DomainLookupStart)
IMPL_TIMING_ATTR(DomainLookupEnd)
IMPL_TIMING_ATTR(ConnectStart)
IMPL_TIMING_ATTR(ConnectEnd)
IMPL_TIMING_ATTR(RequestStart)
IMPL_TIMING_ATTR(ResponseStart)
IMPL_TIMING_ATTR(ResponseEnd)
IMPL_TIMING_ATTR(CacheReadStart)
IMPL_TIMING_ATTR(CacheReadEnd)
#undef IMPL_TIMING_ATTR
//-----------------------------------------------------------------------------
// nsHttpChannel::nsIHttpAuthenticableChannel
//-----------------------------------------------------------------------------
@ -3981,6 +4127,10 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
LOG(("nsHttpChannel::OnStopRequest [this=%p request=%p status=%x]\n",
this, request, status));
if (mTimingEnabled && request == mCachePump) {
mCacheReadEnd = mozilla::TimeStamp::Now();
}
// allow content to be cached if it was loaded successfully (bug #482935)
PRBool contentComplete = NS_SUCCEEDED(status);
@ -4037,6 +4187,7 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
stickyConn = mTransaction->Connection();
// at this point, we're done with the transaction
mTransactionTimings = mTransaction->Timings();
mTransaction = nsnull;
mTransactionPump = 0;

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

@ -64,6 +64,8 @@
#include "nsIHttpChannelAuthProvider.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsICryptoHash.h"
#include "nsITimedChannel.h"
#include "TimingStruct.h"
class nsAHttpConnection;
class AutoRedirectVetoNotifier;
@ -84,6 +86,7 @@ class nsHttpChannel : public HttpBaseChannel
, public nsITraceableChannel
, public nsIApplicationCacheChannel
, public nsIAsyncVerifyRedirectCallback
, public nsITimedChannel
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -99,6 +102,7 @@ public:
NS_DECL_NSIAPPLICATIONCACHECONTAINER
NS_DECL_NSIAPPLICATIONCACHECHANNEL
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
NS_DECL_NSITIMEDCHANNEL
// nsIHttpAuthenticableChannel. We can't use
// NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and
@ -351,6 +355,15 @@ private:
nsCOMPtr<nsICryptoHash> mHasher;
PRTime mChannelCreationTime;
mozilla::TimeStamp mChannelCreationTimestamp;
mozilla::TimeStamp mAsyncOpenTime;
mozilla::TimeStamp mCacheReadStart;
mozilla::TimeStamp mCacheReadEnd;
// copied from the transaction before we null out mTransaction
// so that the timing can still be queried from OnStopRequest
TimingStruct mTransactionTimings;
nsresult WaitForRedirectCallback();
void PushRedirectAsyncFunc(nsContinueRedirectionFunc func);
void PopRedirectAsyncFunc(nsContinueRedirectionFunc func);

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

@ -360,6 +360,18 @@ nsHttpTransaction::OnTransportStatus(nsITransport* transport,
LOG(("nsHttpTransaction::OnSocketStatus [this=%x status=%x progress=%llu]\n",
this, status, progress));
if (TimingEnabled()) {
if (status == nsISocketTransport::STATUS_RESOLVING) {
mTimings.domainLookupStart = mozilla::TimeStamp::Now();
} else if (status == nsISocketTransport::STATUS_RESOLVED) {
mTimings.domainLookupEnd = mozilla::TimeStamp::Now();
} else if (status == nsISocketTransport::STATUS_CONNECTING_TO) {
mTimings.connectStart = mozilla::TimeStamp::Now();
} else if (status == nsISocketTransport::STATUS_CONNECTED_TO) {
mTimings.connectEnd = mozilla::TimeStamp::Now();
}
}
if (!mTransportSink)
return;
@ -450,6 +462,10 @@ nsHttpTransaction::ReadRequestSegment(nsIInputStream *stream,
nsresult rv = trans->mReader->OnReadSegment(buf, count, countRead);
if (NS_FAILED(rv)) return rv;
if (trans->TimingEnabled() && trans->mTimings.requestStart.IsNull()) {
// First data we're sending -> this is requestStart
trans->mTimings.requestStart = mozilla::TimeStamp::Now();
}
trans->mSentData = PR_TRUE;
return NS_OK;
}
@ -509,6 +525,10 @@ nsHttpTransaction::WritePipeSegment(nsIOutputStream *stream,
if (trans->mTransactionDone)
return NS_BASE_STREAM_CLOSED; // stop iterating
if (trans->TimingEnabled() && trans->mTimings.responseStart.IsNull()) {
trans->mTimings.responseStart = mozilla::TimeStamp::Now();
}
nsresult rv;
//
// OK, now let the caller fill this segment with data.
@ -571,6 +591,8 @@ nsHttpTransaction::Close(nsresult reason)
return;
}
mTimings.responseEnd = mozilla::TimeStamp::Now();
if (mActivityDistributor) {
// report the reponse is complete if not already reported
if (!mResponseIsComplete)

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

@ -52,6 +52,7 @@
#include "nsISocketTransportService.h"
#include "nsITransport.h"
#include "nsIEventTarget.h"
#include "TimingStruct.h"
//-----------------------------------------------------------------------------
@ -134,6 +135,8 @@ public:
void SetPriority(PRInt32 priority) { mPriority = priority; }
PRInt32 Priority() { return mPriority; }
const TimingStruct& Timings() const { return mTimings; }
private:
nsresult Restart();
char *LocateHttpStart(char *buf, PRUint32 len,
@ -151,6 +154,8 @@ private:
static NS_METHOD WritePipeSegment(nsIOutputStream *, void *, char *,
PRUint32, PRUint32, PRUint32 *);
PRBool TimingEnabled() const { return mCaps & NS_HTTP_TIMING_ENABLED; }
private:
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsITransportEventSink> mTransportSink;
@ -188,6 +193,8 @@ private:
nsHttpChunkedDecoder *mChunkedDecoder;
TimingStruct mTimings;
nsresult mStatus;
PRInt16 mPriority;

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

@ -79,6 +79,7 @@
#include "nsIPrefBranch.h"
#include "nsIPropertyBag2.h"
#include "nsIWritablePropertyBag2.h"
#include "nsITimedChannel.h"
#include "nsChannelProperties.h"
#include "nsISimpleEnumerator.h"
@ -154,6 +155,39 @@ SetPACFile(const char* pacURL)
return NS_OK;
}
//-----------------------------------------------------------------------------
// Timing information
//-----------------------------------------------------------------------------
void PrintTimingInformation(nsITimedChannel* channel) {
#define PRINT_VALUE(property) \
{ \
PRTime value; \
channel->Get##property(&value); \
if (value) { \
PRExplodedTime exploded; \
PR_ExplodeTime(value, PR_LocalTimeParameters, &exploded); \
char buf[256]; \
PR_FormatTime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &exploded); \
LOG((" " #property ":\t%s (%i usec)", buf, exploded.tm_usec)); \
} else { \
LOG((" " #property ":\t0")); \
} \
}
LOG(("Timing data:"));
PRINT_VALUE(ChannelCreationTime)
PRINT_VALUE(AsyncOpenTime)
PRINT_VALUE(DomainLookupStartTime)
PRINT_VALUE(DomainLookupEndTime)
PRINT_VALUE(ConnectStartTime)
PRINT_VALUE(ConnectEndTime)
PRINT_VALUE(RequestStartTime)
PRINT_VALUE(ResponseStartTime)
PRINT_VALUE(ResponseEndTime)
PRINT_VALUE(CacheReadStartTime)
PRINT_VALUE(CacheReadEndTime)
}
//-----------------------------------------------------------------------------
// HeaderVisitor
//-----------------------------------------------------------------------------
@ -545,6 +579,10 @@ InputTestConsumer::OnStopRequest(nsIRequest *request, nsISupports* context,
} else {
LOG(("\tThroughput: REAL FAST!!\n"));
}
nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(request));
if (timed)
PrintTimingInformation(timed);
} else {
LOG(("\nFinished loading: UNKNOWN URL. Status Code: %x\n", aStatus));
}
@ -631,6 +669,10 @@ nsresult StartLoadingURL(const char* aUrlString)
return rv;
}
nsCOMPtr<nsITimedChannel> timed(do_QueryInterface(pChannel));
if (timed)
timed->SetTimingEnabled(PR_TRUE);
nsCOMPtr<nsIWritablePropertyBag2> props = do_QueryInterface(pChannel);
if (props) {
rv = props->SetPropertyAsInterface(NS_LITERAL_STRING("test.foo"),

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

@ -2513,6 +2513,7 @@ HUD_SERVICE.prototype =
0x5006: "TRANSACTION_CLOSE",
0x804b0003: "STATUS_RESOLVING",
0x804b000b: "STATUS_RESOLVED",
0x804b0007: "STATUS_CONNECTING_TO",
0x804b0004: "STATUS_CONNECTED_TO",
0x804b0005: "STATUS_SENDING_TO",