☠☠ backed out by f9eaf23fddf5 ☠ ☠ | |
author | Christian Biesinger <cbiesinger@gmail.com> |
Mon, 29 Nov 2010 15:28:40 -0800 | |
changeset 58352 | dd249f45dc3d1c9661c24ea5d7ae8728a3b46d98 |
parent 58351 | 82f2a2e86728efad2c08abd9a1b7a916817426a7 |
child 58353 | f9eaf23fddf57bc994cfa976e9992ad66213806b |
push id | 17259 |
push user | cbiesinger@gmail.com |
push date | Mon, 29 Nov 2010 23:32:45 +0000 |
treeherder | mozilla-central@dd249f45dc3d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 614717, 369787 |
milestone | 2.0b8pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/netwerk/base/public/Makefile.in +++ b/netwerk/base/public/Makefile.in @@ -108,16 +108,17 @@ XPIDLSRCS = \ nsIRequestObserverProxy.idl \ nsISecurityInfoProvider.idl \ nsIStreamListenerTee.idl \ nsISimpleStreamListener.idl \ nsIStreamTransportService.idl \ nsIStreamLoader.idl \ nsISyncStreamListener.idl \ nsISystemProxySettings.idl \ + nsITimedChannel.idl \ nsIUnicharStreamLoader.idl \ nsIUploadChannel2.idl \ nsIStandardURL.idl \ nsINestedURI.idl \ nsIURLParser.idl \ nsIURIChecker.idl \ nsISecurityEventSink.idl \ nsISecretDecoderRing.idl \
--- a/netwerk/base/public/nsISocketTransport.idl +++ b/netwerk/base/public/nsISocketTransport.idl @@ -124,16 +124,17 @@ interface nsISocketTransport : nsITransp * The values of these status codes must never change. * * The status codes appear in near-chronological order (not in numeric * order). STATUS_RESOLVING may be skipped if the host does not need to be * resolved. STATUS_WAITING_FOR is an optional status code, which the impl * 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; const unsigned long STATUS_WAITING_FOR = 0x804b000a; const unsigned long STATUS_RECEIVING_FROM = 0x804b0006; /** * connectionFlags is a bitmask that can be used to modify underlying
new file mode 100644 --- /dev/null +++ b/netwerk/base/public/nsITimedChannel.idl @@ -0,0 +1,65 @@ +/* ***** 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" + +// 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; + + readonly attribute unsigned long long channelCreationTime; + readonly attribute unsigned long long asyncOpenTime; + + // The following are only set when the document is not (only) read from the + // cache + readonly attribute unsigned long long domainLookupStart; + readonly attribute unsigned long long domainLookupEnd; + readonly attribute unsigned long long connectStart; + readonly attribute unsigned long long connectEnd; + readonly attribute unsigned long long requestStart; + readonly attribute unsigned long long responseStart; + readonly attribute unsigned long long responseEnd; + + // The following are only set if the document is (partially) read from the + // cache + readonly attribute unsigned long long cacheReadStart; + readonly attribute unsigned long long cacheReadEnd; +};
--- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -1426,16 +1426,19 @@ nsSocketTransport::OnSocketEvent(PRUint3 // if (mState == STATE_CLOSED) mCondition = ResolveHost(); else SOCKET_LOG((" ignoring redundant event\n")); 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) { mDNSRecord = static_cast<nsIDNSRecord *>(param); mDNSRecord->GetNextAddr(SocketPort(), &mNetAddr); } // status contains DNS lookup status if (NS_FAILED(status)) {
--- a/netwerk/locales/en-US/necko.properties +++ b/netwerk/locales/en-US/necko.properties @@ -43,16 +43,17 @@ 3=Looking up %1$S… 4=Connected to %1$S… 5=Sending request to %1$S… 6=Transferring data from %1$S… 7=Connecting to %1$S… 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 UnsupportedFTPServer=The FTP server %1$S is currently unsupported. RepostFormData=This web page is being redirected to a new location. Would you like to resend the form data you have typed to the new location? # Directory listing strings
new file mode 100644 --- /dev/null +++ b/netwerk/protocol/http/TimingStruct.h @@ -0,0 +1,59 @@ +/* ***** 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_ + +struct TimingStruct { + TimingStruct() { + memset(this, 0, sizeof(TimingStruct)); + } + + PRTime channelCreation; + PRTime asyncOpen; + + PRTime domainLookupStart; + PRTime domainLookupEnd; + PRTime connectStart; + PRTime connectEnd; + PRTime requestStart; + PRTime responseStart; + PRTime responseEnd; +}; + +#endif
--- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -130,18 +130,23 @@ nsHttpChannel::nsHttpChannel() , mCacheForOfflineUse(PR_FALSE) , mCachingOpportunistically(PR_FALSE) , mFallbackChannel(PR_FALSE) , mTracingEnabled(PR_TRUE) , mCustomConditionalRequest(PR_FALSE) , mFallingBack(PR_FALSE) , mWaitingForRedirectCallback(PR_FALSE) , mRequestTimeInitialized(PR_FALSE) + , mTimingEnabled(PR_FALSE) + , mAsyncOpenTime(0) + , mCacheReadStart(0) + , mCacheReadEnd(0) { LOG(("Creating nsHttpChannel [this=%p]\n", this)); + mChannelCreationTime = PR_Now(); } nsHttpChannel::~nsHttpChannel() { LOG(("Destroying nsHttpChannel [this=%p]\n", this)); if (mAuthProvider) mAuthProvider->Disconnect(NS_ERROR_ABORT); @@ -2813,16 +2818,19 @@ nsHttpChannel::ReadFromCache() rv = nsInputStreamPump::Create(getter_AddRefs(mCachePump), stream, nsInt64(-1), nsInt64(-1), 0, 0, PR_TRUE); if (NS_FAILED(rv)) return rv; rv = mCachePump->AsyncRead(this, mListenerContext); if (NS_FAILED(rv)) return rv; + if (mTimingEnabled) + mCacheReadStart = PR_Now(); + PRUint32 suspendCount = mSuspendCount; while (suspendCount--) mCachePump->Suspend(); return NS_OK; } void @@ -3598,16 +3606,19 @@ nsHttpChannel::AsyncOpen(nsIStreamListen NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); nsresult rv; if (mCanceled) return mStatus; + if (mTimingEnabled) + mAsyncOpenTime = PR_Now(); + rv = NS_CheckPortSafety(mURI); if (NS_FAILED(rv)) return rv; if (!(mConnectionInfo && mConnectionInfo->UsingHttpProxy())) { // Start a DNS lookup very early in case the real open is queued the DNS can // happen in parallel. Do not do so in the presence of an HTTP proxy as // all lookups other than for the proxy itself are done by the proxy. @@ -3742,16 +3753,119 @@ nsHttpChannel::GetProxyInfo(nsIProxyInfo else { *result = mConnectionInfo->ProxyInfo(); NS_IF_ADDREF(*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::GetChannelCreationTime(PRUint64* _retval) { + *_retval = mChannelCreationTime; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetAsyncOpenTime(PRUint64* _retval) { + *_retval = mAsyncOpenTime; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetDomainLookupStart(PRUint64* _retval) { + if (mTransaction) + *_retval = mTransaction->Timings().domainLookupStart; + else + *_retval = mTransactionTimings.domainLookupStart; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetDomainLookupEnd(PRUint64* _retval) { + if (mTransaction) + *_retval = mTransaction->Timings().domainLookupEnd; + else + *_retval = mTransactionTimings.domainLookupEnd; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetConnectStart(PRUint64* _retval) { + if (mTransaction) + *_retval = mTransaction->Timings().connectStart; + else + *_retval = mTransactionTimings.connectStart; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetConnectEnd(PRUint64* _retval) { + if (mTransaction) + *_retval = mTransaction->Timings().connectEnd; + else + *_retval = mTransactionTimings.connectEnd; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetRequestStart(PRUint64* _retval) { + if (mTransaction) + *_retval = mTransaction->Timings().requestStart; + else + *_retval = mTransactionTimings.requestStart; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetResponseStart(PRUint64* _retval) { + if (mTransaction) + *_retval = mTransaction->Timings().responseStart; + else + *_retval = mTransactionTimings.responseStart; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetResponseEnd(PRUint64* _retval) { + if (mTransaction) + *_retval = mTransaction->Timings().responseEnd; + else + *_retval = mTransactionTimings.responseEnd; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetCacheReadStart(PRUint64* _retval) { + *_retval = mCacheReadStart; + return NS_OK; +} + +NS_IMETHODIMP +nsHttpChannel::GetCacheReadEnd(PRUint64* _retval) { + *_retval = mCacheReadEnd; + return NS_OK; +} + +//----------------------------------------------------------------------------- // nsHttpChannel::nsIHttpAuthenticableChannel //----------------------------------------------------------------------------- NS_IMETHODIMP nsHttpChannel::GetIsSSL(PRBool *aIsSSL) { *aIsSSL = mConnectionInfo->UsingSSL(); return NS_OK; @@ -3936,16 +4050,20 @@ nsHttpChannel::ContinueOnStartRequest3(n } NS_IMETHODIMP nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult status) { LOG(("nsHttpChannel::OnStopRequest [this=%p request=%p status=%x]\n", this, request, status)); + if (mTimingEnabled && request == mCachePump) { + mCacheReadEnd = PR_Now(); + } + // honor the cancelation status even if the underlying transaction completed. if (mCanceled || NS_FAILED(mStatus)) status = mStatus; if (mCachedContentIsPartial) { if (NS_SUCCEEDED(status)) { // mTransactionPump should be suspended NS_ASSERTION(request != mTransactionPump, @@ -3986,16 +4104,17 @@ nsHttpChannel::OnStopRequest(nsIRequest // This is so far a workaround to fix leak when reusing unpersistent // connection for authentication retry. See bug 459620 comment 4 // for details. if (conn && !conn->IsPersistent()) conn = nsnull; } // at this point, we're done with the transaction + mTransactionTimings = mTransaction->Timings(); mTransaction = nsnull; mTransactionPump = 0; // handle auth retry... if (authRetry) { mAuthRetryPending = PR_FALSE; status = DoAuthRetry(conn); if (NS_SUCCEEDED(status))
--- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -59,16 +59,18 @@ #include "nsIResumableChannel.h" #include "nsIProtocolProxyCallback.h" #include "nsICancelable.h" #include "nsIHttpAuthenticableChannel.h" #include "nsITraceableChannel.h" #include "nsIHttpChannelAuthProvider.h" #include "nsIAsyncVerifyRedirectCallback.h" #include "nsICryptoHash.h" +#include "nsITimedChannel.h" +#include "TimingStruct.h" class nsAHttpConnection; class AutoRedirectVetoNotifier; using namespace mozilla::net; //----------------------------------------------------------------------------- // nsHttpChannel @@ -79,31 +81,33 @@ class nsHttpChannel : public HttpBaseCha , public nsICachingChannel , public nsICacheListener , public nsITransportEventSink , public nsIProtocolProxyCallback , public nsIHttpAuthenticableChannel , public nsITraceableChannel , public nsIApplicationCacheChannel , public nsIAsyncVerifyRedirectCallback + , public nsITimedChannel { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSISTREAMLISTENER NS_DECL_NSICACHEINFOCHANNEL NS_DECL_NSICACHINGCHANNEL NS_DECL_NSICACHELISTENER NS_DECL_NSITRANSPORTEVENTSINK NS_DECL_NSIPROTOCOLPROXYCALLBACK NS_DECL_NSIPROXIEDCHANNEL NS_DECL_NSITRACEABLECHANNEL 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 // others. NS_IMETHOD GetIsSSL(PRBool *aIsSSL); NS_IMETHOD GetProxyMethodIsConnect(PRBool *aProxyMethodIsConnect); NS_IMETHOD GetServerResponseHeader(nsACString & aServerResponseHeader); NS_IMETHOD GetProxyChallenges(nsACString & aChallenges); @@ -341,19 +345,29 @@ private: // headers. In such a case we must not override them in the cache code // and also we want to pass possible 304 code response through. PRUint32 mCustomConditionalRequest : 1; PRUint32 mFallingBack : 1; PRUint32 mWaitingForRedirectCallback : 1; // True if mRequestTime has been set. In such a case it is safe to update // the cache entry's expiration time. Otherwise, it is not(see bug 567360). PRUint32 mRequestTimeInitialized : 1; + // True if timing collection is enabled + PRUint32 mTimingEnabled : 1; nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack; nsCOMPtr<nsICryptoHash> mHasher; + PRTime mChannelCreationTime; + PRTime mAsyncOpenTime; + PRTime mCacheReadStart; + PRTime 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); }; #endif // nsHttpChannel_h__
--- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -352,16 +352,28 @@ nsHttpTransaction::GetSecurityCallbacks( } void nsHttpTransaction::OnTransportStatus(nsresult status, PRUint64 progress) { LOG(("nsHttpTransaction::OnSocketStatus [this=%x status=%x progress=%llu]\n", this, status, progress)); + if (TimingEnabled()) { + if (status == nsISocketTransport::STATUS_RESOLVING) { + mTimings.domainLookupStart = PR_Now(); + } else if (status == nsISocketTransport::STATUS_RESOLVED) { + mTimings.domainLookupEnd = PR_Now(); + } else if (status == nsISocketTransport::STATUS_CONNECTING_TO) { + mTimings.connectStart = PR_Now(); + } else if (status == nsISocketTransport::STATUS_CONNECTED_TO) { + mTimings.connectEnd = PR_Now(); + } + } + if (!mTransportSink) return; NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); // 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) { @@ -442,16 +454,20 @@ nsHttpTransaction::ReadRequestSegment(ns PRUint32 offset, PRUint32 count, PRUint32 *countRead) { nsHttpTransaction *trans = (nsHttpTransaction *) closure; nsresult rv = trans->mReader->OnReadSegment(buf, count, countRead); if (NS_FAILED(rv)) return rv; + if (trans->TimingEnabled() && !trans->mTimings.requestStart) { + // First data we're sending -> this is requestStart + trans->mTimings.requestStart = PR_Now(); + } trans->mSentData = PR_TRUE; return NS_OK; } nsresult nsHttpTransaction::ReadSegments(nsAHttpSegmentReader *reader, PRUint32 count, PRUint32 *countRead) { @@ -501,16 +517,20 @@ nsHttpTransaction::WritePipeSegment(nsIO PRUint32 count, PRUint32 *countWritten) { nsHttpTransaction *trans = (nsHttpTransaction *) closure; if (trans->mTransactionDone) return NS_BASE_STREAM_CLOSED; // stop iterating + if (trans->TimingEnabled() && !trans->mTimings.responseStart) { + trans->mTimings.responseStart = PR_Now(); + } + nsresult rv; // // OK, now let the caller fill this segment with data. // rv = trans->mWriter->OnWriteSegment(buf, count, countWritten); if (NS_FAILED(rv)) return rv; // caller didn't want to write anything NS_ASSERTION(*countWritten > 0, "bad writer"); @@ -563,16 +583,18 @@ nsHttpTransaction::Close(nsresult reason NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread"); if (mClosed) { LOG((" already closed\n")); return; } + mTimings.responseEnd = PR_Now(); + if (mActivityDistributor) { // report the reponse is complete if not already reported if (!mResponseIsComplete) mActivityDistributor->ObserveActivity( mChannel, NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE, PR_Now(),
--- a/netwerk/protocol/http/nsHttpTransaction.h +++ b/netwerk/protocol/http/nsHttpTransaction.h @@ -48,16 +48,17 @@ #include "nsIPipe.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" #include "nsIInterfaceRequestor.h" #include "nsISocketTransportService.h" #include "nsITransport.h" #include "nsIEventTarget.h" +#include "TimingStruct.h" //----------------------------------------------------------------------------- class nsHttpTransaction; class nsHttpRequestHead; class nsHttpResponseHead; class nsHttpChunkedDecoder; class nsIHttpActivityObserver; @@ -132,31 +133,35 @@ public: void SetSSLConnectFailed() { mSSLConnectFailed = PR_TRUE; } PRBool SSLConnectFailed() { return mSSLConnectFailed; } // These methods may only be used by the connection manager. void SetPriority(PRInt32 priority) { mPriority = priority; } PRInt32 Priority() { return mPriority; } + const TimingStruct& Timings() const { return mTimings; } + private: nsresult Restart(); void ParseLine(char *line); nsresult ParseLineSegment(char *seg, PRUint32 len); nsresult ParseHead(char *, PRUint32 count, PRUint32 *countRead); nsresult HandleContentStart(); nsresult HandleContent(char *, PRUint32 count, PRUint32 *contentRead, PRUint32 *contentRemaining); nsresult ProcessData(char *, PRUint32, PRUint32 *); void DeleteSelfOnConsumerThread(); static NS_METHOD ReadRequestSegment(nsIInputStream *, void *, const char *, PRUint32, PRUint32, PRUint32 *); static NS_METHOD WritePipeSegment(nsIOutputStream *, void *, char *, PRUint32, PRUint32, PRUint32 *); + PRBool TimingEnabled() const { return PR_TRUE; } + private: nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsCOMPtr<nsITransportEventSink> mTransportSink; nsCOMPtr<nsIEventTarget> mConsumerTarget; nsCOMPtr<nsISupports> mSecurityInfo; nsCOMPtr<nsIAsyncInputStream> mPipeIn; nsCOMPtr<nsIAsyncOutputStream> mPipeOut; @@ -177,16 +182,18 @@ private: nsCString mLineBuf; // may contain a partial line nsInt64 mContentLength; // equals -1 if unknown nsInt64 mContentRead; // count of consumed content bytes nsHttpChunkedDecoder *mChunkedDecoder; + TimingStruct mTimings; + nsresult mStatus; PRInt16 mPriority; PRUint16 mRestartCount; // the number of times this transaction has been restarted PRUint8 mCaps; // state flags
--- a/netwerk/test/unit/test_bug369787.js +++ b/netwerk/test/unit/test_bug369787.js @@ -11,20 +11,33 @@ function change_content_type() { do_check_eq(channel.contentType, newType); channel.contentType = origType; do_check_eq(channel.contentType, origType); } function TestListener() { } TestListener.prototype.onStartRequest = function(request, context) { - change_content_type(); + try { + // request might be different from channel + channel = request.QueryInterface(Components.interfaces.nsIChannel); + + change_content_type(); + } catch (ex) { + print(ex); + throw ex; + } } TestListener.prototype.onStopRequest = function(request, context, status) { - change_content_type(); + try { + change_content_type(); + } catch (ex) { + print(ex); + // don't re-throw ex to avoid hanging the test + } do_timeout(0, after_channel_closed); } function after_channel_closed() { try { change_content_type(); } finally {