mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Landing first cut of http pipelining (2487). Don't turn it on yet. Also fix
sockettransport leakage (33929). In case of major bustage - pipelining_reorg_point is the tag before the check in.
This commit is contained in:
parent
da78ce03ea
commit
5db8127f56
@ -77,6 +77,7 @@ static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL, nsHTTPHandler* i_Handler):
|
||||
mResponse(nsnull),
|
||||
mRequest (nsnull),
|
||||
mHandler(dont_QueryInterface(i_Handler)),
|
||||
mHTTPServerListener(nsnull),
|
||||
mResponseContext(nsnull),
|
||||
@ -95,7 +96,8 @@ nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL, nsHTTPHandler* i_Handler):
|
||||
mProxyPort(-1),
|
||||
mBufferSegmentSize(0),
|
||||
mBufferMaxSize(0),
|
||||
mStatus(NS_OK)
|
||||
mStatus(NS_OK),
|
||||
mPipeliningAllowed (PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
@ -466,15 +468,18 @@ nsHTTPChannel::GetShouldCache(PRBool *aShouldCache)
|
||||
NS_IMETHODIMP
|
||||
nsHTTPChannel::GetPipeliningAllowed(PRBool *aPipeliningAllowed)
|
||||
{
|
||||
*aPipeliningAllowed = PR_FALSE;
|
||||
if (aPipeliningAllowed == NULL)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aPipeliningAllowed = mPipeliningAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPChannel::SetPipeliningAllowed(PRBool aPipeliningAllowed)
|
||||
{
|
||||
NS_NOTREACHED("SetPipeliningAllowed");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
mPipeliningAllowed = aPipeliningAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1303,17 +1308,42 @@ nsHTTPChannel::Open(void)
|
||||
}
|
||||
} /* WAITING_FOR_OPEN */
|
||||
|
||||
rv = mRequest -> WriteRequest ();
|
||||
nsCOMPtr<nsHTTPPipelinedRequest> pReq = mPipelinedRequest;
|
||||
|
||||
if (NS_ERROR_BUSY == rv)
|
||||
if (!pReq)
|
||||
{
|
||||
mState = HS_WAITING_FOR_OPEN;
|
||||
return NS_OK;
|
||||
mHandler -> GetPipelinedRequest (this, getter_AddRefs (pReq));
|
||||
pReq -> AddToPipeline (mRequest);
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
|
||||
PRBool commit = PR_FALSE;
|
||||
pReq -> GetMustCommit ( &commit);
|
||||
|
||||
if (!commit && !mPipeliningAllowed)
|
||||
commit = PR_TRUE;
|
||||
|
||||
if (commit)
|
||||
{
|
||||
ResponseCompleted (mResponseDataListener, rv, nsnull);
|
||||
return rv;
|
||||
if (!mPipelinedRequest)
|
||||
mPipelinedRequest = pReq;
|
||||
|
||||
rv = pReq -> WriteRequest ();
|
||||
|
||||
if (NS_ERROR_BUSY == rv)
|
||||
{
|
||||
mState = HS_WAITING_FOR_OPEN;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_FAILED (rv))
|
||||
{
|
||||
ResponseCompleted (mResponseDataListener, rv, nsnull);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mHandler -> AddPipelinedRequest (pReq);
|
||||
}
|
||||
|
||||
mState = HS_WAITING_FOR_RESPONSE;
|
||||
@ -2104,10 +2134,11 @@ nsHTTPChannel::GetSecurityInfo (nsISupports * *aSecurityInfo)
|
||||
if (!aSecurityInfo)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsIChannel * trans;
|
||||
nsCOMPtr<nsIChannel> trans;
|
||||
|
||||
if (mRequest)
|
||||
{
|
||||
mRequest -> GetTransport (&trans);
|
||||
mRequest -> GetTransport (getter_AddRefs (trans));
|
||||
if (trans)
|
||||
return trans -> GetSecurityInfo (aSecurityInfo);
|
||||
}
|
||||
|
@ -171,6 +171,9 @@ protected:
|
||||
nsresult mStatus;
|
||||
|
||||
nsCOMPtr<nsIChannel> mCacheTransport;
|
||||
nsCOMPtr<nsHTTPPipelinedRequest> mPipelinedRequest;
|
||||
|
||||
PRBool mPipeliningAllowed;
|
||||
};
|
||||
|
||||
#endif /* _nsHTTPChannel_h_ */
|
||||
|
@ -48,6 +48,8 @@
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#include "nsHTTPRequest.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/utsname.h>
|
||||
#endif /* XP_UNIX */
|
||||
@ -767,6 +769,9 @@ nsHTTPHandler::Init()
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mIdleTransports));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(mPipelinedRequests));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
// Startup the http category
|
||||
// Bring alive the objects in the http-protocol-startup category
|
||||
@ -781,10 +786,11 @@ nsHTTPHandler::~nsHTTPHandler()
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("Deleting nsHTTPHandler [this=%x].\n", this));
|
||||
|
||||
mConnections->Clear();
|
||||
mIdleTransports->Clear();
|
||||
mPendingChannelList->Clear();
|
||||
mTransportList->Clear();
|
||||
mConnections -> Clear ();
|
||||
mIdleTransports -> Clear ();
|
||||
mPendingChannelList -> Clear ();
|
||||
mTransportList -> Clear ();
|
||||
mPipelinedRequests -> Clear ();
|
||||
|
||||
// Release the Atoms used by the HTTP protocol...
|
||||
nsHTTPAtoms::ReleaseAtoms();
|
||||
@ -802,7 +808,6 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
|
||||
PRUint32 bufferSegmentSize,
|
||||
PRUint32 bufferMaxSize,
|
||||
nsIChannel** o_pTrans,
|
||||
PRUint32 * o_Capabilities,
|
||||
PRUint32 flags)
|
||||
{
|
||||
nsresult rv;
|
||||
@ -826,9 +831,6 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
|
||||
|
||||
rv = i_Channel -> GetProxyPort (&proxyPort);
|
||||
if (NS_FAILED (rv)) return rv;
|
||||
|
||||
if (o_Capabilities != NULL)
|
||||
*o_Capabilities = getCapabilities (proxy, proxyPort, DEFAULT_PROXY_CAPABILITIES);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -840,9 +842,6 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
|
||||
|
||||
if (port == -1)
|
||||
GetDefaultPort (&port);
|
||||
|
||||
if (o_Capabilities != NULL)
|
||||
*o_Capabilities = getCapabilities (host, port, DEFAULT_SERVER_CAPABILITIES);
|
||||
}
|
||||
|
||||
nsIChannel* trans = nsnull;
|
||||
@ -855,57 +854,64 @@ nsresult nsHTTPHandler::RequestTransport (nsIURI* i_Uri,
|
||||
|
||||
// remove old and dead transports first
|
||||
|
||||
for (index = count - 1; index >= 0; --index)
|
||||
if (count > 0)
|
||||
{
|
||||
nsIChannel* cTrans = (nsIChannel*) mIdleTransports -> ElementAt (index);
|
||||
|
||||
if (cTrans)
|
||||
for (index = count - 1; index >= 0; --index)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISocketTransport> sTrans = do_QueryInterface (cTrans, &rv);
|
||||
PRBool isAlive = PR_TRUE;
|
||||
nsCOMPtr<nsIChannel> cTrans = dont_AddRef ((nsIChannel*) mIdleTransports -> ElementAt (index) );
|
||||
|
||||
if (NS_FAILED (rv) || NS_FAILED (sTrans -> IsAlive (mKeepAliveTimeout, &isAlive))
|
||||
|| !isAlive)
|
||||
mIdleTransports -> RemoveElement (cTrans);
|
||||
if (cTrans)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISocketTransport> sTrans = do_QueryInterface (cTrans, &rv);
|
||||
PRBool isAlive = PR_TRUE;
|
||||
|
||||
if (NS_FAILED (rv) || NS_FAILED (sTrans -> IsAlive (mKeepAliveTimeout, &isAlive))
|
||||
|| !isAlive)
|
||||
mIdleTransports -> RemoveElement (cTrans);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mIdleTransports -> Count (&count);
|
||||
|
||||
for (index = count - 1; index >= 0; --index)
|
||||
if (count > 0)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsIChannel* cTrans = (nsIChannel*) mIdleTransports -> ElementAt (index);
|
||||
|
||||
if (cTrans &&
|
||||
(NS_SUCCEEDED (cTrans -> GetURI (getter_AddRefs (uri)))))
|
||||
for (index = count - 1; index >= 0; --index)
|
||||
{
|
||||
nsXPIDLCString idlehost;
|
||||
if (NS_SUCCEEDED (uri -> GetHost (getter_Copies (idlehost))))
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIChannel> cTrans = dont_AddRef ((nsIChannel*) mIdleTransports -> ElementAt (index) );
|
||||
|
||||
if (cTrans &&
|
||||
(NS_SUCCEEDED (cTrans -> GetURI (getter_AddRefs (uri)))))
|
||||
{
|
||||
if (!PL_strcasecmp (usingProxy ? proxy : host, idlehost))
|
||||
nsXPIDLCString idlehost;
|
||||
if (NS_SUCCEEDED (uri -> GetHost (getter_Copies (idlehost))))
|
||||
{
|
||||
PRInt32 idleport;
|
||||
if (NS_SUCCEEDED (uri -> GetPort (&idleport)))
|
||||
if (!PL_strcasecmp (usingProxy ? proxy : host, idlehost))
|
||||
{
|
||||
if (idleport == -1)
|
||||
GetDefaultPort (&idleport);
|
||||
|
||||
if (idleport == usingProxy ? proxyPort : port)
|
||||
PRInt32 idleport;
|
||||
if (NS_SUCCEEDED (uri -> GetPort (&idleport)))
|
||||
{
|
||||
// Addref it before removing it!
|
||||
NS_ADDREF (cTrans);
|
||||
// Remove it from the idle
|
||||
mIdleTransports -> RemoveElement (cTrans);
|
||||
trans = cTrans;
|
||||
break;// break out of the for loop
|
||||
if (idleport == -1)
|
||||
GetDefaultPort (&idleport);
|
||||
|
||||
if (idleport == usingProxy ? proxyPort : port)
|
||||
{
|
||||
// Addref it before removing it!
|
||||
trans = cTrans;
|
||||
NS_ADDREF (trans);
|
||||
// Remove it from the idle
|
||||
mIdleTransports -> RemoveElement (trans);
|
||||
break;// break out of the for loop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
} /* for */
|
||||
} /* count > 0 */
|
||||
}
|
||||
// if we didn't find any from the keep-alive idlelist
|
||||
if (trans == nsnull)
|
||||
@ -1289,3 +1295,81 @@ nsHTTPHandler::getCapabilities (const char *host, PRInt32 port, PRUint32 defCap)
|
||||
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTTPHandler::GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req, PRBool checkExists)
|
||||
{
|
||||
if (o_Req == NULL)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsXPIDLCString host;
|
||||
PRInt32 port = -1;
|
||||
nsresult rv = i_Channel -> GetURI (getter_AddRefs (uri));
|
||||
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
rv = uri -> GetHost (getter_Copies (host));
|
||||
if (NS_SUCCEEDED (rv) && host)
|
||||
{
|
||||
uri -> GetPort (&port);
|
||||
if (port == -1)
|
||||
GetDefaultPort (&port);
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32 count = 0;
|
||||
PRUint32 index = 0;
|
||||
mPipelinedRequests -> Count (&count);
|
||||
|
||||
nsHTTPPipelinedRequest *pReq = nsnull;
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
nsHTTPPipelinedRequest *pReq = (nsHTTPPipelinedRequest *)mPipelinedRequests -> ElementAt (index);
|
||||
if (pReq != NULL)
|
||||
{
|
||||
PRBool same = PR_TRUE;
|
||||
pReq -> GetSameRequest (host, port, &same);
|
||||
if (same)
|
||||
{
|
||||
mPipelinedRequests -> RemoveElement (pReq);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_RELEASE (pReq);
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
|
||||
if (!checkExists && pReq == nsnull)
|
||||
{
|
||||
PRBool usingProxy = PR_FALSE;
|
||||
i_Channel -> GetUsingProxy (&usingProxy);
|
||||
PRUint32 capabilities;
|
||||
|
||||
if (usingProxy)
|
||||
capabilities = getCapabilities (host, port, DEFAULT_PROXY_CAPABILITIES );
|
||||
else
|
||||
capabilities = getCapabilities (host, port, DEFAULT_SERVER_CAPABILITIES);
|
||||
|
||||
pReq = new nsHTTPPipelinedRequest (this, host, port, capabilities);
|
||||
NS_ADDREF (pReq);
|
||||
}
|
||||
*o_Req = pReq;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTTPHandler::AddPipelinedRequest (nsHTTPPipelinedRequest *pReq)
|
||||
{
|
||||
if (pReq == NULL)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
mPipelinedRequests -> AppendElement (pReq);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -61,6 +61,9 @@ class nsHTTPChannel;
|
||||
// because of HTTP/1.1 is default now
|
||||
#define DEFAULT_ALLOWED_CAPABILITIES (DEFAULT_PROXY_CAPABILITIES|DEFAULT_SERVER_CAPABILITIES)
|
||||
|
||||
class nsHTTPPipelinedRequest;
|
||||
class nsIHTTPChannel;
|
||||
|
||||
class nsHTTPHandler : public nsIHTTPProtocolHandler
|
||||
{
|
||||
public:
|
||||
@ -79,7 +82,7 @@ public:
|
||||
nsHTTPChannel* i_Channel,
|
||||
PRUint32 bufferSegmentSize,
|
||||
PRUint32 bufferMaxSize,
|
||||
nsIChannel** o_pTrans, PRUint32 *capabilities, PRUint32 flags = TRANSPORT_REUSE_ALIVE);
|
||||
nsIChannel** o_pTrans, PRUint32 flags = TRANSPORT_REUSE_ALIVE);
|
||||
|
||||
/**
|
||||
* Called to create a transport from RequestTransport to accually
|
||||
@ -103,6 +106,9 @@ public:
|
||||
|
||||
PRUint32 ReferrerLevel(void) { return mReferrerLevel; } ;
|
||||
|
||||
nsresult AddPipelinedRequest (nsHTTPPipelinedRequest *pReq);
|
||||
nsresult GetPipelinedRequest (nsIHTTPChannel* i_Channel, nsHTTPPipelinedRequest ** o_Req, PRBool checkExists = PR_FALSE);
|
||||
|
||||
protected:
|
||||
virtual ~nsHTTPHandler();
|
||||
nsresult InitUserAgentComponents();
|
||||
@ -112,6 +118,7 @@ protected:
|
||||
nsCOMPtr<nsISupportsArray> mConnections;
|
||||
nsCOMPtr<nsISupportsArray> mPendingChannelList;
|
||||
nsCOMPtr<nsISupportsArray> mTransportList;
|
||||
nsCOMPtr<nsISupportsArray> mPipelinedRequests;
|
||||
// Transports that are idle (ready to be used again)
|
||||
nsCOMPtr<nsISupportsArray> mIdleTransports;
|
||||
|
||||
@ -142,6 +149,8 @@ protected:
|
||||
nsCString mProduct;
|
||||
nsCString mProductSub;
|
||||
nsCString mProductComment;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
nsHashtable mCapTable;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,8 @@
|
||||
#include "nsHTTPHeaderArray.h"
|
||||
#include "nsHTTPEnums.h"
|
||||
#include "nsHTTPHandler.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
class nsIInputStream;
|
||||
class nsHTTPChannel;
|
||||
@ -58,8 +60,10 @@ class nsHTTPChannel;
|
||||
|
||||
-Gagan Saksena 03/29/99
|
||||
*/
|
||||
class nsHTTPRequest : public nsIStreamObserver,
|
||||
public nsIRequest
|
||||
|
||||
class nsHTTPPipelinedRequest;
|
||||
|
||||
class nsHTTPRequest : public nsIRequest
|
||||
{
|
||||
|
||||
public:
|
||||
@ -68,7 +72,6 @@ public:
|
||||
nsHTTPRequest(nsIURI* i_URL, nsHTTPHandler* i_Handler, PRUint32 bufferSegmentSize, PRUint32 bufferMaxSize, HTTPMethod i_Method=HM_GET);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSIREQUEST
|
||||
|
||||
// Finally our own methods...
|
||||
@ -103,13 +106,13 @@ public:
|
||||
|
||||
nsresult GetHeaderEnumerator(nsISimpleEnumerator** aResult);
|
||||
|
||||
nsresult SetConnection(nsHTTPChannel* i_Connection);
|
||||
nsresult GetConnection(nsHTTPChannel** o_Connection);
|
||||
nsresult SetConnection(nsHTTPChannel* i_Connection);
|
||||
|
||||
nsresult SetTransport (nsIChannel * aTransport);
|
||||
nsresult GetTransport (nsIChannel **aTransport);
|
||||
|
||||
// Build the actual request string based on the settings.
|
||||
nsresult WriteRequest();
|
||||
|
||||
nsresult GetPostDataStream(nsIInputStream* *aResult);
|
||||
nsresult SetPostDataStream(nsIInputStream* aStream);
|
||||
@ -117,6 +120,18 @@ public:
|
||||
nsresult SetOverrideRequestSpec(const char* i_Spec);
|
||||
nsresult GetOverrideRequestSpec(char** o_Spec);
|
||||
|
||||
PRUint32 mBufferSegmentSize;
|
||||
PRUint32 mBufferMaxSize;
|
||||
|
||||
nsCOMPtr<nsIInputStream> mPostDataStream;
|
||||
|
||||
nsresult formHeaders (PRUint32 capabilities);
|
||||
nsresult formBuffer (nsCString * reqBuffer);
|
||||
|
||||
nsHTTPPipelinedRequest* mPipelinedRequest;
|
||||
nsHTTPChannel* mConnection;
|
||||
nsCOMPtr<nsIURL> mURI;
|
||||
|
||||
protected:
|
||||
virtual ~nsHTTPRequest();
|
||||
|
||||
@ -142,27 +157,69 @@ protected:
|
||||
}
|
||||
|
||||
HTTPMethod mMethod;
|
||||
nsCOMPtr<nsIURL> mURI;
|
||||
PRUint32 mVersion;
|
||||
PRUint32 mKeepAliveTimeout;
|
||||
PRUint32 mAttempts;
|
||||
PRUint32 mCapabilities;
|
||||
nsCOMPtr<nsIChannel> mTransport;
|
||||
nsHTTPChannel* mConnection;
|
||||
|
||||
nsHTTPHeaderArray mHeaders;
|
||||
|
||||
nsCString mRequestBuffer;
|
||||
nsCOMPtr<nsIInputStream> mPostDataStream;
|
||||
char* mRequestSpec;
|
||||
|
||||
nsHTTPHandler* mHandler;
|
||||
|
||||
PRUint32 mBufferSegmentSize;
|
||||
PRUint32 mBufferMaxSize;
|
||||
nsresult mAbortStatus;
|
||||
};
|
||||
|
||||
nsresult formHeaders ();
|
||||
class nsHTTPPipelinedRequest : public nsIStreamObserver
|
||||
{
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
nsHTTPPipelinedRequest (nsHTTPHandler* i_Handler, const char *host, PRInt32 port, PRUint32 capabilities);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
|
||||
nsresult SetTransport (nsIChannel * aTransport);
|
||||
nsresult GetTransport (nsIChannel **aTransport);
|
||||
|
||||
// Build the actual request string based on the settings.
|
||||
nsresult WriteRequest ();
|
||||
|
||||
nsresult AddToPipeline(nsHTTPRequest *aRequest);
|
||||
nsresult GetRequestCount (PRUint32 * aReqCount);
|
||||
|
||||
nsresult GetMustCommit (PRBool * aMustCommit);
|
||||
nsresult GetSameRequest(const char *host, PRInt32 port, PRBool * aSame);
|
||||
|
||||
nsresult GetCurrentRequest (nsHTTPRequest ** o_Req);
|
||||
nsresult AdvanceToNextRequest ();
|
||||
|
||||
nsresult IsPending (PRBool *result);
|
||||
nsresult Cancel (nsresult status );
|
||||
nsresult Suspend ();
|
||||
nsresult Resume ();
|
||||
|
||||
protected:
|
||||
virtual ~nsHTTPPipelinedRequest ();
|
||||
|
||||
PRUint32 mCapabilities;
|
||||
PRUint32 mAttempts;
|
||||
nsCOMPtr<nsIChannel> mTransport;
|
||||
|
||||
PRUint32 mBufferSegmentSize;
|
||||
PRUint32 mBufferMaxSize;
|
||||
PRBool mMustCommit;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISupportsArray> mRequests;
|
||||
|
||||
nsHTTPRequest* mCurReq;
|
||||
nsHTTPHandler* mHandler;
|
||||
nsCString mRequestBuffer;
|
||||
|
||||
nsCOMPtr<nsIInputStream> mPostDataStream;
|
||||
|
||||
nsXPIDLCString mHost;
|
||||
PRInt32 mPort;
|
||||
};
|
||||
|
||||
#endif /* _nsHTTPRequest_h_ */
|
||||
|
@ -210,7 +210,7 @@ nsresult nsHTTPCacheListener::Abort()
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandler *handler)
|
||||
nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandler *handler, nsHTTPPipelinedRequest * request)
|
||||
: nsHTTPResponseListener (aChannel, handler),
|
||||
mResponse(nsnull),
|
||||
mFirstLineParsed(PR_FALSE),
|
||||
@ -218,9 +218,11 @@ nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandle
|
||||
mBytesReceived(0),
|
||||
mBodyBytesReceived (0),
|
||||
mCompressHeaderChecked (PR_FALSE),
|
||||
mChunkHeaderChecked (PR_FALSE)
|
||||
mChunkHeaderChecked (PR_FALSE),
|
||||
mPipelinedRequest (request)
|
||||
{
|
||||
mChannel->mHTTPServerListener = this;
|
||||
nsHTTPRequest * req = nsnull;
|
||||
mChannel -> mHTTPServerListener = this;
|
||||
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("Creating nsHTTPServerListener [this=%x].\n", this));
|
||||
@ -319,7 +321,15 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
|
||||
|
||||
// XXX/ruslan: will be replace with the new Cancel (code)
|
||||
if (NS_SUCCEEDED (rv))
|
||||
trans -> SetBytesExpected (0);
|
||||
{
|
||||
PRUint32 count = 0;
|
||||
mPipelinedRequest -> GetRequestCount (&count);
|
||||
|
||||
if (count == 1)
|
||||
trans -> SetBytesExpected (0);
|
||||
else
|
||||
OnStopRequest (nsnull, context, NS_OK, nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -352,20 +362,6 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (i_Length) {
|
||||
|
||||
PRInt32 cl = -1;
|
||||
mResponse -> GetContentLength (&cl);
|
||||
|
||||
mBodyBytesReceived += i_Length;
|
||||
|
||||
if (cl != -1 && cl - mBodyBytesReceived == 0)
|
||||
{
|
||||
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
|
||||
|
||||
// XXX/ruslan: will be replaced with the new Cancel (code)
|
||||
if (NS_SUCCEEDED (rv))
|
||||
trans -> SetBytesExpected (0);
|
||||
}
|
||||
|
||||
if (!mCompressHeaderChecked)
|
||||
{
|
||||
nsXPIDLCString compressHeader;
|
||||
@ -433,6 +429,29 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
|
||||
("\tOnDataAvailable [this=%x]. Consumer failed!"
|
||||
"Status: %x\n", this, rv));
|
||||
}
|
||||
|
||||
PRInt32 cl = -1;
|
||||
mResponse -> GetContentLength (&cl);
|
||||
|
||||
mBodyBytesReceived += i_Length;
|
||||
|
||||
if (cl != -1 && cl - mBodyBytesReceived == 0)
|
||||
{
|
||||
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (channel, &rv);
|
||||
|
||||
// XXX/ruslan: will be replaced with the new Cancel (code)
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
PRUint32 count = 0;
|
||||
mPipelinedRequest -> GetRequestCount (&count);
|
||||
|
||||
if (count == 1)
|
||||
trans -> SetBytesExpected (0);
|
||||
else
|
||||
OnStopRequest (nsnull, context, NS_OK, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // end !mChannel->mOpenObserver
|
||||
@ -442,8 +461,7 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPServerListener::OnStartRequest(nsIChannel* channel,
|
||||
nsISupports* i_pContext)
|
||||
nsHTTPServerListener::OnStartRequest (nsIChannel* channel, nsISupports* i_pContext)
|
||||
{
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("nsHTTPServerListener::OnStartRequest [this=%x].\n", this));
|
||||
@ -451,15 +469,36 @@ nsHTTPServerListener::OnStartRequest(nsIChannel* channel,
|
||||
// Initialize header varaibles...
|
||||
mHeadersDone = PR_FALSE;
|
||||
mFirstLineParsed = PR_FALSE;
|
||||
mCompressHeaderChecked = PR_FALSE;
|
||||
mChunkHeaderChecked = PR_FALSE;
|
||||
mBytesReceived = 0;
|
||||
mBodyBytesReceived = 0;
|
||||
|
||||
NS_IF_RELEASE (mResponse);
|
||||
NS_IF_RELEASE ( mChannel);
|
||||
|
||||
mResponse = nsnull;
|
||||
mChannel = nsnull;
|
||||
mResponseDataListener = null_nsCOMPtr ();
|
||||
|
||||
nsCOMPtr<nsHTTPRequest> req;
|
||||
mPipelinedRequest -> GetCurrentRequest (getter_AddRefs (req));
|
||||
|
||||
if (req)
|
||||
{
|
||||
mChannel = req -> mConnection;
|
||||
if (mChannel)
|
||||
{
|
||||
mChannel -> mHTTPServerListener = this;
|
||||
NS_ADDREF (mChannel);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
|
||||
nsISupports* i_pContext,
|
||||
nsresult i_Status,
|
||||
const PRUnichar* i_pMsg)
|
||||
nsHTTPServerListener::OnStopRequest (nsIChannel* channel, nsISupports* i_pContext, nsresult i_Status, const PRUnichar* i_pMsg)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@ -467,7 +506,8 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
|
||||
("nsHTTPServerListener::OnStopRequest [this=%x]."
|
||||
"\tStatus = %x\n", this, i_Status));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !mHeadersDone) {
|
||||
if (NS_SUCCEEDED(rv) && !mHeadersDone)
|
||||
{
|
||||
//
|
||||
// Oh great!! The server has closed the connection without sending
|
||||
// an entity. Assume that it has sent all the response headers and
|
||||
@ -491,15 +531,37 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
|
||||
if (mResponse)
|
||||
mResponse -> GetStatus(&status);
|
||||
|
||||
if (!mChannel -> mCachedResponse)
|
||||
if (status != 304 || !mChannel -> mCachedResponse)
|
||||
{
|
||||
mChannel -> ResponseCompleted (mResponseDataListener, i_Status, i_pMsg);
|
||||
mChannel -> mHTTPServerListener = 0;
|
||||
}
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
rv = mPipelinedRequest -> AdvanceToNextRequest ();
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
OnStartRequest (nsnull, nsnull);
|
||||
if (!channel)
|
||||
return NS_OK;
|
||||
|
||||
if (mResponse)
|
||||
FinishedResponseHeaders ();
|
||||
|
||||
if (status != 304 || !mChannel -> mCachedResponse)
|
||||
{
|
||||
mChannel -> ResponseCompleted (mResponseDataListener, i_Status, i_pMsg);
|
||||
mChannel -> mHTTPServerListener = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
PRUint32 capabilities = 0;
|
||||
|
||||
if (mResponse)
|
||||
if (mResponse && channel) // this is the actual response from the transport
|
||||
{
|
||||
HTTPVersion ver;
|
||||
rv = mResponse -> GetServerVersion (&ver);
|
||||
@ -533,11 +595,12 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
|
||||
}
|
||||
}
|
||||
|
||||
mHandler -> ReleaseTransport (channel, capabilities);
|
||||
if (channel)
|
||||
mHandler -> ReleaseTransport (channel, capabilities);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mChannel);
|
||||
NS_IF_RELEASE(mResponse);
|
||||
NS_IF_RELEASE (mChannel );
|
||||
NS_IF_RELEASE (mResponse);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -786,25 +849,26 @@ nsresult nsHTTPServerListener::ParseHTTPHeader(nsIBufferInputStream* in,
|
||||
return mResponse->ParseHeader(mHeaderBuffer);
|
||||
}
|
||||
|
||||
nsresult nsHTTPServerListener::FinishedResponseHeaders(void)
|
||||
nsresult
|
||||
nsHTTPServerListener::FinishedResponseHeaders ()
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv;
|
||||
|
||||
rv = mChannel->FinishedResponseHeaders();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = mChannel -> FinishedResponseHeaders ();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//
|
||||
// Fire the OnStartRequest notification - now that user data is available
|
||||
//
|
||||
if (NS_SUCCEEDED(rv) && mResponseDataListener) {
|
||||
rv = mResponseDataListener->OnStartRequest(mChannel,
|
||||
mChannel->mResponseContext);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(gHTTPLog, PR_LOG_ERROR,
|
||||
("\tOnStartRequest [this=%x]. Consumer failed!"
|
||||
"Status: %x\n", this, rv));
|
||||
}
|
||||
}
|
||||
//
|
||||
// Fire the OnStartRequest notification - now that user data is available
|
||||
//
|
||||
if (NS_SUCCEEDED(rv) && mResponseDataListener)
|
||||
{
|
||||
rv = mResponseDataListener -> OnStartRequest (mChannel, mChannel -> mResponseContext);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
PR_LOG(gHTTPLog, PR_LOG_ERROR, ("\tOnStartRequest [this=%x]. Consumer failed!"
|
||||
"Status: %x\n", this, rv));
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
return rv;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsHTTPHandler.h"
|
||||
#include "nsHTTPRequest.h"
|
||||
|
||||
class nsIBufferInputStream;
|
||||
class nsHTTPResponse;
|
||||
@ -85,7 +86,7 @@ class nsHTTPServerListener : public nsHTTPResponseListener
|
||||
|
||||
public:
|
||||
|
||||
nsHTTPServerListener(nsHTTPChannel* aConnection, nsHTTPHandler *handler);
|
||||
nsHTTPServerListener (nsHTTPChannel* aConnection, nsHTTPHandler *handler, nsHTTPPipelinedRequest * request);
|
||||
virtual ~nsHTTPServerListener();
|
||||
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
@ -121,6 +122,7 @@ protected:
|
||||
|
||||
PRBool mCompressHeaderChecked;
|
||||
PRBool mChunkHeaderChecked;
|
||||
nsHTTPPipelinedRequest* mPipelinedRequest;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user