зеркало из https://github.com/mozilla/gecko-dev.git
Http handler reorg to fix keep-alive raise condition and prepare for
pipeling changes. Also fix 32505, 31979. In case of a major bustage - http11_reorg_point is the tag before the checkin; r=gagan, a=warren
This commit is contained in:
Родитель
b529051831
Коммит
77aabe9130
|
@ -416,26 +416,6 @@ nsresult nsSocketTransport::Process(PRInt16 aSelectFlags)
|
|||
// this is ugly, but so as this state machine. It's too late in doWrite to do anything; let
|
||||
// me know if someone sees a better solution
|
||||
|
||||
if (mReuseCount > 0 && mReuseCount > mLastReuseCount
|
||||
&& GetWriteType() != eSocketWrite_None)
|
||||
{
|
||||
PRBool isalive = PR_FALSE;
|
||||
if (NS_SUCCEEDED (IsAlive (0, &isalive)) && !isalive)
|
||||
{
|
||||
if (mSocketFD)
|
||||
{
|
||||
PR_Close (mSocketFD);
|
||||
mSocketFD = nsnull;
|
||||
}
|
||||
|
||||
mCurrentState = eSocketState_WaitConnect;
|
||||
mLastReuseCount = mReuseCount;
|
||||
fireStatus (mCurrentState);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetReadType() != eSocketRead_None) {
|
||||
// Set the select flags for non-blocking reads...
|
||||
mSelectFlags |= PR_POLL_READ;
|
||||
|
@ -2113,7 +2093,7 @@ nsSocketTransport::IsAlive (PRUint32 seconds, PRBool *alive)
|
|||
{
|
||||
PRErrorCode code = PR_GetError ();
|
||||
|
||||
if (rval == 0 || code != PR_WOULD_BLOCK_ERROR)
|
||||
if (rval < 0 && code != PR_WOULD_BLOCK_ERROR)
|
||||
*alive = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ interface nsIHTTPProtocolHandler : nsIProtocolHandler
|
|||
in unsigned long encodeFlags);
|
||||
|
||||
attribute string acceptLanguages;
|
||||
attribute string acceptEncodings;
|
||||
attribute unsigned long httpVersion;
|
||||
/* i'll file a bug on the http guys to make nsAuthEngine scriptable
|
||||
and then we can get rid of this no script code! */
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "nsIProxy.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsISocketTransport.h"
|
||||
// FIXME - Temporary include. Delete this when cache is enabled on all
|
||||
// platforms
|
||||
#include "nsIPref.h"
|
||||
|
@ -92,7 +91,6 @@ nsHTTPChannel::nsHTTPChannel(nsIURI* i_URL,
|
|||
mState(HS_IDLE),
|
||||
mLoadAttributes(LOAD_NORMAL),
|
||||
mLoadGroup(nsnull),
|
||||
mTransport(nsnull),
|
||||
mCachedResponse(nsnull),
|
||||
mCachedContentIsAvailable(PR_FALSE),
|
||||
mCachedContentIsValid(PR_FALSE),
|
||||
|
@ -159,7 +157,7 @@ nsHTTPChannel::IsPending(PRBool *result)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPChannel::Cancel(void)
|
||||
nsHTTPChannel::Cancel (void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
@ -668,7 +666,7 @@ nsresult nsHTTPChannel::Init(nsILoadGroup *aLoadGroup)
|
|||
Set up a request object - later set to a clone of a default
|
||||
request from the handler. TODO
|
||||
*/
|
||||
mRequest = new nsHTTPRequest(mURI);
|
||||
mRequest = new nsHTTPRequest(mURI, mHandler, mBufferSegmentSize, mBufferMaxSize);
|
||||
if (!mRequest) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -942,7 +940,7 @@ nsHTTPChannel::ReadFromCache(PRUint32 aStartPosition, PRInt32 aReadCount)
|
|||
// Create a listener that intercepts cache reads and fires off
|
||||
// the appropriate events such as OnHeadersAvailable
|
||||
nsHTTPResponseListener* listener;
|
||||
listener = new nsHTTPCacheListener(this);
|
||||
listener = new nsHTTPCacheListener(this, mHandler);
|
||||
if (!listener)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(listener);
|
||||
|
@ -1141,105 +1139,93 @@ nsHTTPChannel::Open(void)
|
|||
}
|
||||
}
|
||||
|
||||
rv = mHandler->RequestTransport(mURI, this,
|
||||
mBufferSegmentSize, mBufferMaxSize,
|
||||
getter_AddRefs(mTransport));
|
||||
if (mState != HS_WAITING_FOR_OPEN)
|
||||
{
|
||||
// Check for any modules that want to set headers before we
|
||||
// send out a request.
|
||||
NS_WITH_SERVICE(nsINetModuleMgr, pNetModuleMgr, kNetModuleMgrCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (NS_ERROR_BUSY == rv) {
|
||||
nsCOMPtr<nsISimpleEnumerator> pModules;
|
||||
rv = pNetModuleMgr->EnumerateModules(
|
||||
NS_NETWORK_MODULE_MANAGER_HTTP_REQUEST_PROGID,
|
||||
getter_AddRefs(pModules));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Go through the external modules and notify each one.
|
||||
nsCOMPtr<nsISupports> supEntry;
|
||||
rv = pModules->GetNext(getter_AddRefs(supEntry));
|
||||
while (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsINetModRegEntry> entry = do_QueryInterface(supEntry, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsINetNotify> syncNotifier;
|
||||
entry->GetSyncProxy(getter_AddRefs(syncNotifier));
|
||||
nsCOMPtr<nsIHTTPNotify> pNotify = do_QueryInterface(syncNotifier, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// send off the notification, and block.
|
||||
// make the nsIHTTPNotify api call
|
||||
pNotify->ModifyRequest((nsISupports*)(nsIRequest*)this);
|
||||
// we could do something with the return code from the external
|
||||
// module, but what????
|
||||
}
|
||||
rv = pModules->GetNext(getter_AddRefs(supEntry)); // go around again
|
||||
}
|
||||
|
||||
// if using proxy...
|
||||
nsXPIDLCString requestSpec;
|
||||
rv = mRequest->GetOverrideRequestSpec(getter_Copies(requestSpec));
|
||||
// no one has overwritten this value as yet...
|
||||
if (!requestSpec && mProxy && *mProxy)
|
||||
{
|
||||
nsXPIDLCString strurl;
|
||||
if(NS_SUCCEEDED(mURI->GetSpec(getter_Copies(strurl))))
|
||||
mRequest->SetOverrideRequestSpec(strurl);
|
||||
}
|
||||
|
||||
// Check to see if an authentication header is required
|
||||
nsAuthEngine* pAuthEngine = nsnull;
|
||||
if (NS_SUCCEEDED(mHandler->GetAuthEngine(&pAuthEngine)) && pAuthEngine)
|
||||
{
|
||||
nsXPIDLCString authStr;
|
||||
if (NS_SUCCEEDED(pAuthEngine->GetAuthString(mURI,
|
||||
getter_Copies(authStr))))
|
||||
{
|
||||
if (authStr && *authStr)
|
||||
rv = mRequest->SetHeader(nsHTTPAtoms::Authorization, authStr);
|
||||
}
|
||||
|
||||
if (mProxy && *mProxy)
|
||||
{
|
||||
nsXPIDLCString proxyAuthStr;
|
||||
if (NS_SUCCEEDED(pAuthEngine->GetProxyAuthString(mProxy,
|
||||
mProxyPort,
|
||||
getter_Copies(proxyAuthStr))))
|
||||
{
|
||||
if (proxyAuthStr && *proxyAuthStr)
|
||||
rv = mRequest->SetHeader(nsHTTPAtoms::Proxy_Authorization,
|
||||
proxyAuthStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* WAITING_FOR_OPEN */
|
||||
|
||||
rv = mRequest -> WriteRequest ();
|
||||
|
||||
if (NS_ERROR_BUSY == rv)
|
||||
{
|
||||
mState = HS_WAITING_FOR_OPEN;
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
// Unable to create a transport... End the request...
|
||||
(void) ResponseCompleted(mResponseDataListener, rv, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// pass ourself in to act as a proxy for progress callbacks
|
||||
rv = mTransport->SetNotificationCallbacks(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Unable to create a transport... End the request...
|
||||
(void) ResponseCompleted(mResponseDataListener, rv, nsnull);
|
||||
(void) ReleaseTransport(mTransport);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Check for any modules that want to set headers before we
|
||||
// send out a request.
|
||||
NS_WITH_SERVICE(nsINetModuleMgr, pNetModuleMgr, kNetModuleMgrCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> pModules;
|
||||
rv = pNetModuleMgr->EnumerateModules(
|
||||
NS_NETWORK_MODULE_MANAGER_HTTP_REQUEST_PROGID,
|
||||
getter_AddRefs(pModules));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Go through the external modules and notify each one.
|
||||
nsCOMPtr<nsISupports> supEntry;
|
||||
rv = pModules->GetNext(getter_AddRefs(supEntry));
|
||||
while (NS_SUCCEEDED(rv))
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
nsCOMPtr<nsINetModRegEntry> entry = do_QueryInterface(supEntry, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsINetNotify> syncNotifier;
|
||||
entry->GetSyncProxy(getter_AddRefs(syncNotifier));
|
||||
nsCOMPtr<nsIHTTPNotify> pNotify = do_QueryInterface(syncNotifier, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// send off the notification, and block.
|
||||
// make the nsIHTTPNotify api call
|
||||
pNotify->ModifyRequest((nsISupports*)(nsIRequest*)this);
|
||||
// we could do something with the return code from the external
|
||||
// module, but what????
|
||||
}
|
||||
rv = pModules->GetNext(getter_AddRefs(supEntry)); // go around again
|
||||
ResponseCompleted (mResponseDataListener, rv, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
mRequest->SetTransport(mTransport);
|
||||
|
||||
// if using proxy...
|
||||
nsXPIDLCString requestSpec;
|
||||
rv = mRequest->GetOverrideRequestSpec(getter_Copies(requestSpec));
|
||||
// no one has overwritten this value as yet...
|
||||
if (!requestSpec && mProxy && *mProxy)
|
||||
{
|
||||
nsXPIDLCString strurl;
|
||||
if(NS_SUCCEEDED(mURI->GetSpec(getter_Copies(strurl))))
|
||||
mRequest->SetOverrideRequestSpec(strurl);
|
||||
}
|
||||
|
||||
// Check to see if an authentication header is required
|
||||
nsAuthEngine* pAuthEngine = nsnull;
|
||||
if (NS_SUCCEEDED(mHandler->GetAuthEngine(&pAuthEngine)) && pAuthEngine)
|
||||
{
|
||||
nsXPIDLCString authStr;
|
||||
if (NS_SUCCEEDED(pAuthEngine->GetAuthString(mURI,
|
||||
getter_Copies(authStr))))
|
||||
{
|
||||
if (authStr && *authStr)
|
||||
rv = mRequest->SetHeader(nsHTTPAtoms::Authorization, authStr);
|
||||
}
|
||||
|
||||
if (mProxy && *mProxy)
|
||||
{
|
||||
nsXPIDLCString proxyAuthStr;
|
||||
if (NS_SUCCEEDED(pAuthEngine->GetProxyAuthString(mProxy,
|
||||
mProxyPort,
|
||||
getter_Copies(proxyAuthStr))))
|
||||
{
|
||||
if (proxyAuthStr && *proxyAuthStr)
|
||||
rv = mRequest->SetHeader(nsHTTPAtoms::Proxy_Authorization,
|
||||
proxyAuthStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv = mRequest->WriteRequest();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
mState = HS_WAITING_FOR_RESPONSE;
|
||||
mConnected = PR_TRUE;
|
||||
|
@ -1404,17 +1390,6 @@ nsresult nsHTTPChannel::ResponseCompleted(nsIStreamListener *aListener,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsHTTPChannel::ReleaseTransport (nsIChannel *aTransport, PRBool keepAlive)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aTransport) {
|
||||
(void) mRequest->ReleaseTransport (aTransport);
|
||||
rv = mHandler->ReleaseTransport (aTransport, keepAlive);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsHTTPChannel::SetResponse(nsHTTPResponse* i_pResp)
|
||||
{
|
||||
NS_IF_RELEASE(mResponse);
|
||||
|
@ -1859,7 +1834,7 @@ nsHTTPChannel::ProcessNotModifiedResponse(nsIStreamListener *aListener)
|
|||
|
||||
// Create a new HTTPCacheListener...
|
||||
nsHTTPResponseListener *cacheListener;
|
||||
cacheListener = new nsHTTPCacheListener(this);
|
||||
cacheListener = new nsHTTPCacheListener(this, mHandler);
|
||||
if (!cacheListener) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -2020,15 +1995,19 @@ nsHTTPChannel::GetUsingProxy(PRBool *aUsingProxy)
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
||||
nsHTTPChannel::GetSecurityInfo (nsISupports * *aSecurityInfo)
|
||||
{
|
||||
*aSecurityInfo = nsnull;
|
||||
|
||||
if (!aSecurityInfo)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (!mTransport)
|
||||
return NS_OK;
|
||||
|
||||
return mTransport->GetSecurityInfo(aSecurityInfo);
|
||||
nsIChannel * trans;
|
||||
if (mRequest)
|
||||
{
|
||||
mRequest -> GetTransport (&trans);
|
||||
if (trans)
|
||||
return trans -> GetSecurityInfo (aSecurityInfo);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,6 @@ public:
|
|||
nsresult ResponseCompleted(nsIStreamListener* aListener,
|
||||
nsresult aStatus,
|
||||
const PRUnichar* aMsg);
|
||||
nsresult ReleaseTransport (nsIChannel *aTransport, PRBool keepAlive = PR_FALSE);
|
||||
|
||||
nsresult SetResponse(nsHTTPResponse* i_pResp);
|
||||
nsresult GetResponseContext(nsISupports** aContext);
|
||||
|
@ -149,8 +148,6 @@ protected:
|
|||
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
|
||||
nsCOMPtr<nsIChannel> mTransport;
|
||||
|
||||
// Cache-related members
|
||||
nsCOMPtr<nsICachedNetData> mCacheEntry;
|
||||
nsHTTPResponse* mCachedResponse;
|
||||
|
|
|
@ -347,7 +347,7 @@ nsHTTPHandler::NewPostDataStream(PRBool isFile,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPHandler::SetAcceptLanguages(const char* i_AcceptLanguages)
|
||||
nsHTTPHandler::SetAcceptLanguages (const char* i_AcceptLanguages)
|
||||
{
|
||||
CRTFREEIF(mAcceptLanguages);
|
||||
if (i_AcceptLanguages)
|
||||
|
@ -359,7 +359,7 @@ nsHTTPHandler::SetAcceptLanguages(const char* i_AcceptLanguages)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPHandler::GetAcceptLanguages(char* *o_AcceptLanguages)
|
||||
nsHTTPHandler::GetAcceptLanguages (char* *o_AcceptLanguages)
|
||||
{
|
||||
if (!o_AcceptLanguages)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -375,6 +375,36 @@ nsHTTPHandler::GetAcceptLanguages(char* *o_AcceptLanguages)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPHandler::SetAcceptEncodings (const char* i_AcceptEncodings)
|
||||
{
|
||||
CRTFREEIF (mAcceptEncodings);
|
||||
if (i_AcceptEncodings)
|
||||
{
|
||||
mAcceptEncodings = nsCRT::strdup (i_AcceptEncodings);
|
||||
return (mAcceptEncodings == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPHandler::GetAcceptEncodings (char* *o_AcceptEncodings)
|
||||
{
|
||||
if (!o_AcceptEncodings)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (mAcceptEncodings)
|
||||
{
|
||||
*o_AcceptEncodings = nsCRT::strdup(mAcceptEncodings);
|
||||
return (*o_AcceptEncodings == nsnull) ? NS_ERROR_OUT_OF_MEMORY : NS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*o_AcceptEncodings = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPHandler::SetHttpVersion (unsigned int i_HttpVersion)
|
||||
{
|
||||
|
@ -596,6 +626,7 @@ nsHTTPHandler::SetMisc(const PRUnichar* aMisc)
|
|||
|
||||
nsHTTPHandler::nsHTTPHandler():
|
||||
mAcceptLanguages(nsnull),
|
||||
mAcceptEncodings(nsnull),
|
||||
mHttpVersion(HTTP_ONE_ZERO),
|
||||
mDoKeepAlive(PR_FALSE),
|
||||
mKeepAliveTimeout(2*60),
|
||||
|
@ -786,38 +817,20 @@ nsHTTPHandler::~nsHTTPHandler()
|
|||
mPrefs->UnregisterCallback(NETWORK_PREFS,
|
||||
HTTPPrefsCallback, (void*)this);
|
||||
|
||||
CRTFREEIF(mAcceptLanguages);
|
||||
CRTFREEIF (mAcceptLanguages);
|
||||
CRTFREEIF (mAcceptEncodings);
|
||||
}
|
||||
|
||||
nsresult nsHTTPHandler::RequestTransport(nsIURI* i_Uri,
|
||||
nsHTTPChannel* i_Channel,
|
||||
PRUint32 bufferSegmentSize,
|
||||
PRUint32 bufferMaxSize,
|
||||
nsIChannel** o_pTrans)
|
||||
nsIChannel** o_pTrans,
|
||||
PRUint32 flags)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 count;
|
||||
|
||||
*o_pTrans = nsnull;
|
||||
|
||||
count = 0;
|
||||
mTransportList->Count(&count);
|
||||
if (count >= MAX_NUMBER_OF_OPEN_TRANSPORTS) {
|
||||
|
||||
// XXX this method incorrectly returns a bool
|
||||
rv = mPendingChannelList->AppendElement(
|
||||
(nsISupports*)(nsIRequest*)i_Channel)
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "AppendElement failed");
|
||||
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("nsHTTPHandler::RequestTransport."
|
||||
"\tAll socket transports are busy."
|
||||
"\tAdding nsHTTPChannel [%x] to pending list.\n",
|
||||
i_Channel));
|
||||
|
||||
return NS_ERROR_BUSY;
|
||||
}
|
||||
PRUint32 count = 0;
|
||||
|
||||
PRInt32 port;
|
||||
nsXPIDLCString host;
|
||||
|
@ -853,7 +866,7 @@ nsresult nsHTTPHandler::RequestTransport(nsIURI* i_Uri,
|
|||
// Check in the idle transports for a host/port match
|
||||
count = 0;
|
||||
PRInt32 index = 0;
|
||||
if (mDoKeepAlive)
|
||||
if (mDoKeepAlive && (flags & TRANSPORT_REUSE_ALIVE))
|
||||
{
|
||||
mIdleTransports -> Count (&count);
|
||||
|
||||
|
@ -914,16 +927,31 @@ nsresult nsHTTPHandler::RequestTransport(nsIURI* i_Uri,
|
|||
// if we didn't find any from the keep-alive idlelist
|
||||
if (trans == nsnull)
|
||||
{
|
||||
if (! (flags & TRANSPORT_OPEN_ALWAYS) )
|
||||
{
|
||||
count = 0;
|
||||
mTransportList -> Count (&count);
|
||||
if (count >= MAX_NUMBER_OF_OPEN_TRANSPORTS)
|
||||
{
|
||||
|
||||
// XXX this method incorrectly returns a bool
|
||||
rv = mPendingChannelList -> AppendElement((nsISupports*)(nsIRequest*)i_Channel)
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
NS_ASSERTION (NS_SUCCEEDED(rv), "AppendElement failed");
|
||||
|
||||
PR_LOG (gHTTPLog, PR_LOG_ALWAYS,
|
||||
("nsHTTPHandler::RequestTransport.""\tAll socket transports are busy."
|
||||
"\tAdding nsHTTPChannel [%x] to pending list.\n",
|
||||
i_Channel));
|
||||
return NS_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (usingProxy)
|
||||
{
|
||||
rv = CreateTransport(proxy, proxyPort, host,
|
||||
bufferSegmentSize, bufferMaxSize, &trans);
|
||||
}
|
||||
rv = CreateTransport (proxy, proxyPort, host, bufferSegmentSize, bufferMaxSize, &trans);
|
||||
else
|
||||
{
|
||||
rv = CreateTransport(host, port, host,
|
||||
bufferSegmentSize, bufferMaxSize, &trans);
|
||||
}
|
||||
rv = CreateTransport (host, port, host, bufferSegmentSize, bufferMaxSize, &trans);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
|
@ -1173,6 +1201,12 @@ nsHTTPHandler::PrefsChanged(const char* pref)
|
|||
if (NS_SUCCEEDED(rv))
|
||||
SetAcceptLanguages(acceptLanguages);
|
||||
}
|
||||
|
||||
nsXPIDLCString acceptEncodings;
|
||||
rv = mPrefs -> CopyCharPref ("network.http.accept-encoding", getter_Copies (acceptEncodings));
|
||||
if (NS_SUCCEEDED (rv))
|
||||
SetAcceptEncodings (acceptEncodings);
|
||||
|
||||
}
|
||||
|
||||
PRInt32 PR_CALLBACK HTTPPrefsCallback(const char* pref, void* instance)
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
class nsHashtable;
|
||||
class nsHTTPChannel;
|
||||
|
||||
#define TRANSPORT_REUSE_ALIVE 1
|
||||
#define TRANSPORT_OPEN_ALWAYS 2
|
||||
|
||||
class nsHTTPHandler : public nsIHTTPProtocolHandler
|
||||
{
|
||||
public:
|
||||
|
@ -67,7 +70,7 @@ public:
|
|||
nsHTTPChannel* i_Channel,
|
||||
PRUint32 bufferSegmentSize,
|
||||
PRUint32 bufferMaxSize,
|
||||
nsIChannel** o_pTrans);
|
||||
nsIChannel** o_pTrans, PRUint32 flags = TRANSPORT_REUSE_ALIVE);
|
||||
|
||||
/**
|
||||
* Called to create a transport from RequestTransport to accually
|
||||
|
@ -104,6 +107,7 @@ protected:
|
|||
nsCOMPtr<nsISupportsArray> mIdleTransports;
|
||||
|
||||
char* mAcceptLanguages;
|
||||
char* mAcceptEncodings;
|
||||
PRUint32 mHttpVersion;
|
||||
nsAuthEngine mAuthEngine;
|
||||
PRBool mDoKeepAlive;
|
||||
|
|
|
@ -99,13 +99,20 @@ nsHTTPHeaderArray::nsHTTPHeaderArray()
|
|||
(void)NS_NewISupportsArray(getter_AddRefs(mHTTPHeaders));
|
||||
}
|
||||
|
||||
void
|
||||
nsHTTPHeaderArray::Clear ()
|
||||
{
|
||||
if (mHTTPHeaders)
|
||||
mHTTPHeaders -> Clear ();
|
||||
}
|
||||
|
||||
|
||||
nsHTTPHeaderArray::~nsHTTPHeaderArray()
|
||||
{
|
||||
if (mHTTPHeaders) {
|
||||
mHTTPHeaders->Clear();
|
||||
}
|
||||
mHTTPHeaders = null_nsCOMPtr();
|
||||
if (mHTTPHeaders)
|
||||
mHTTPHeaders -> Clear ();
|
||||
|
||||
mHTTPHeaders = null_nsCOMPtr ();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
nsresult GetEnumerator(nsISimpleEnumerator** aResult);
|
||||
static void GetStandardHeaderName(nsIAtom* aHeader, const char** aResult);
|
||||
|
||||
void Clear ();
|
||||
|
||||
protected:
|
||||
PRInt32 GetEntry(nsIAtom* aHeader, nsHeaderEntry** aResult);
|
||||
PRBool IsHeaderMultiple(nsIAtom* aHeader);
|
||||
|
@ -80,7 +82,6 @@ public:
|
|||
NS_IMETHOD HasMoreElements(PRBool* aResult);
|
||||
NS_IMETHOD GetNext(nsISupports** aResult);
|
||||
|
||||
|
||||
// Class methods:
|
||||
nsHTTPHeaderEnumerator(nsISupportsArray* aHeaderArray);
|
||||
virtual ~nsHTTPHeaderEnumerator();
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsIIOService.h"
|
||||
#include "nsAuthEngine.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISocketTransport.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
|
@ -51,13 +52,18 @@ static NS_DEFINE_CID(kHTTPHandlerCID, NS_IHTTPHANDLER_CID);
|
|||
|
||||
extern nsresult DupString(char* *o_Dest, const char* i_Src);
|
||||
|
||||
nsHTTPRequest::nsHTTPRequest(nsIURI* i_URL, HTTPMethod i_Method):
|
||||
nsHTTPRequest::nsHTTPRequest(nsIURI* i_URL, nsHTTPHandler* i_Handler, PRUint32 bufferSegmentSize, PRUint32 bufferMaxSize, HTTPMethod i_Method)
|
||||
:
|
||||
mMethod(i_Method),
|
||||
mVersion(HTTP_ONE_ZERO),
|
||||
mRequestSpec(0),
|
||||
mDoKeepAlive(PR_FALSE),
|
||||
mKeepAliveTimeout (2*60)
|
||||
{
|
||||
mKeepAliveTimeout (2*60),
|
||||
mBufferSegmentSize(bufferSegmentSize),
|
||||
mBufferMaxSize(bufferMaxSize),
|
||||
mAttempts (0),
|
||||
mHandler (i_Handler)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
NS_ASSERTION(i_URL, "No URL for the request!!");
|
||||
|
@ -71,63 +77,10 @@ nsHTTPRequest::nsHTTPRequest(nsIURI* i_URL, HTTPMethod i_Method):
|
|||
("Creating nsHTTPRequest [this=%x] for URI: %s.\n",
|
||||
this, (const char *)urlCString));
|
||||
#endif
|
||||
|
||||
|
||||
nsXPIDLCString host;
|
||||
mURI->GetHost(getter_Copies(host));
|
||||
PRInt32 port = -1;
|
||||
mURI->GetPort(&port);
|
||||
|
||||
// Send Host header by default
|
||||
if (HTTP_ZERO_NINE != mVersion)
|
||||
{
|
||||
if (-1 != port)
|
||||
{
|
||||
char* tempHostPort =
|
||||
PR_smprintf("%s:%d", (const char*)host, port);
|
||||
if (tempHostPort)
|
||||
{
|
||||
SetHeader(nsHTTPAtoms::Host, tempHostPort);
|
||||
PR_smprintf_free(tempHostPort);
|
||||
tempHostPort = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
SetHeader(nsHTTPAtoms::Host, host);
|
||||
}
|
||||
|
||||
// Add the user-agent
|
||||
nsresult rv = NS_OK;
|
||||
NS_WITH_SERVICE(nsIHTTPProtocolHandler, httpHandler,
|
||||
kHTTPHandlerCID, &rv);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
nsXPIDLString ua;
|
||||
if (NS_SUCCEEDED(httpHandler->GetUserAgent(getter_Copies(ua))))
|
||||
{
|
||||
nsCAutoString uaString((const PRUnichar*)ua);
|
||||
SetHeader(nsHTTPAtoms::User_Agent, uaString.GetBuffer());
|
||||
}
|
||||
|
||||
// Send */*. We're no longer chopping MIME-types for acceptance.
|
||||
// MIME based content negotiation has died.
|
||||
// SetHeader(nsHTTPAtoms::Accept, "image/gif, image/x-xbitmap, image/jpeg,
|
||||
// image/pjpeg, image/png, */*");
|
||||
SetHeader(nsHTTPAtoms::Accept, "*/*");
|
||||
|
||||
nsXPIDLCString acceptLanguages;
|
||||
// Add the Accept-Language header
|
||||
rv = httpHandler->GetAcceptLanguages(
|
||||
getter_Copies(acceptLanguages));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (acceptLanguages && *acceptLanguages)
|
||||
SetHeader(nsHTTPAtoms::Accept_Language, acceptLanguages);
|
||||
}
|
||||
|
||||
httpHandler -> GetHttpVersion ( &mVersion );
|
||||
httpHandler -> GetDoKeepAlive (&mDoKeepAlive);
|
||||
httpHandler -> GetKeepAliveTimeout (&mKeepAliveTimeout);
|
||||
|
||||
mHandler -> GetHttpVersion ( &mVersion );
|
||||
mHandler -> GetDoKeepAlive (&mDoKeepAlive);
|
||||
mHandler -> GetKeepAliveTimeout (&mKeepAliveTimeout);
|
||||
}
|
||||
|
||||
|
||||
|
@ -201,7 +154,7 @@ nsHTTPRequest::Resume(void)
|
|||
|
||||
// Finally our own methods...
|
||||
|
||||
nsresult nsHTTPRequest::WriteRequest()
|
||||
nsresult nsHTTPRequest::WriteRequest ()
|
||||
{
|
||||
nsresult rv;
|
||||
if (!mURI) {
|
||||
|
@ -209,7 +162,22 @@ nsresult nsHTTPRequest::WriteRequest()
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mTransport, "No transport has been set on this request.");
|
||||
if (mAttempts > 2)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
rv = mHandler -> RequestTransport (mURI, mConnection, mBufferSegmentSize, mBufferMaxSize, getter_AddRefs (mTransport), mAttempts ? TRANSPORT_OPEN_ALWAYS : TRANSPORT_REUSE_ALIVE);
|
||||
|
||||
if (NS_FAILED (rv))
|
||||
return rv;
|
||||
|
||||
rv = mTransport -> SetNotificationCallbacks (mConnection);
|
||||
|
||||
if (NS_FAILED (rv))
|
||||
return rv;
|
||||
|
||||
mAttempts++;
|
||||
|
||||
formHeaders ();
|
||||
|
||||
PRUint32 loadAttributes;
|
||||
mConnection->GetLoadAttributes(&loadAttributes);
|
||||
|
@ -232,15 +200,6 @@ nsresult nsHTTPRequest::WriteRequest()
|
|||
SetHeader(nsHTTPAtoms::Cache_Control, "max-age=0");
|
||||
}
|
||||
|
||||
if (mDoKeepAlive)
|
||||
{
|
||||
char *p = PR_smprintf ("%d", mKeepAliveTimeout);
|
||||
|
||||
SetHeader (nsHTTPAtoms::Keep_Alive, p);
|
||||
PR_smprintf_free (p);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Build up the request into mRequestBuffer...
|
||||
//
|
||||
|
@ -257,7 +216,7 @@ nsresult nsHTTPRequest::WriteRequest()
|
|||
//
|
||||
// ie. Method SP Request-URI SP HTTP-Version CRLF
|
||||
//
|
||||
mRequestBuffer.Append(MethodToString(mMethod));
|
||||
mRequestBuffer.Append (MethodToString (mMethod));
|
||||
|
||||
// Request spec gets set for proxied cases-
|
||||
if (!mRequestSpec)
|
||||
|
@ -305,7 +264,7 @@ nsresult nsHTTPRequest::WriteRequest()
|
|||
// ie. field-name ":" [field-value] CRLF
|
||||
//
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
rv = mHeaders.GetEnumerator(getter_AddRefs(enumerator));
|
||||
rv = mHeaders.GetEnumerator (getter_AddRefs (enumerator));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool bMoreHeaders;
|
||||
|
@ -403,12 +362,12 @@ nsresult nsHTTPRequest::GetPriority()
|
|||
|
||||
nsresult nsHTTPRequest::SetHeader(nsIAtom* i_Header, const char* i_Value)
|
||||
{
|
||||
return mHeaders.SetHeader(i_Header, i_Value);
|
||||
return mHeaders.SetHeader (i_Header, i_Value);
|
||||
}
|
||||
|
||||
nsresult nsHTTPRequest::GetHeader(nsIAtom* i_Header, char* *o_Value)
|
||||
{
|
||||
return mHeaders.GetHeader(i_Header, o_Value);
|
||||
return mHeaders.GetHeader (i_Header, o_Value);
|
||||
}
|
||||
|
||||
|
||||
|
@ -459,57 +418,66 @@ nsHTTPRequest::OnStartRequest(nsIChannel* channel, nsISupports* i_Context)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPRequest::OnStopRequest(nsIChannel* channel, nsISupports* i_Context,
|
||||
nsresult iStatus,
|
||||
const PRUnichar* i_Msg)
|
||||
nsHTTPRequest::OnStopRequest (nsIChannel* channel, nsISupports* i_Context,
|
||||
nsresult iStatus,
|
||||
const PRUnichar* i_Msg)
|
||||
{
|
||||
nsresult rv = iStatus;
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISocketTransport> trans = do_QueryInterface (mTransport, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
//
|
||||
// Write the POST data out to the server...
|
||||
//
|
||||
if (mPostDataStream) {
|
||||
NS_ASSERTION(mMethod == HM_POST, "Post data without a POST method?");
|
||||
rv = iStatus;
|
||||
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("nsHTTPRequest [this=%x]. Writing POST data to the server.\n",
|
||||
this));
|
||||
if (NS_SUCCEEDED (rv))
|
||||
{
|
||||
PRBool isAlive = PR_TRUE;
|
||||
if (trans)
|
||||
trans -> IsAlive (0, &isAlive);
|
||||
|
||||
rv = mTransport->AsyncWrite(mPostDataStream, 0, -1,
|
||||
(nsISupports*)(nsIRequest*)mConnection, this);
|
||||
if (isAlive)
|
||||
{
|
||||
//
|
||||
// Write the POST data out to the server...
|
||||
//
|
||||
if (mPostDataStream)
|
||||
{
|
||||
NS_ASSERTION(mMethod == HM_POST, "Post data without a POST method?");
|
||||
|
||||
/* the mPostDataStream is released below... */
|
||||
}
|
||||
//
|
||||
// Prepare to receive the response...
|
||||
//
|
||||
else {
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("nsHTTPRequest [this=%x]. Finished writing request to server."
|
||||
"\tStatus: %x\n",
|
||||
this, iStatus));
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("nsHTTPRequest [this=%x]. Writing POST data to the server.\n", this));
|
||||
|
||||
nsHTTPResponseListener* pListener =
|
||||
new nsHTTPServerListener(mConnection);
|
||||
if (pListener) {
|
||||
NS_ADDREF(pListener);
|
||||
rv = mTransport->AsyncRead(0, -1, i_Context, pListener);
|
||||
NS_RELEASE(pListener);
|
||||
} else {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
rv = mTransport -> AsyncWrite (mPostDataStream, 0, -1, (nsISupports*)(nsIRequest*)mConnection, this);
|
||||
|
||||
/* the mPostDataStream is released below... */
|
||||
}
|
||||
//
|
||||
// Prepare to receive the response...
|
||||
//
|
||||
else
|
||||
{
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("nsHTTPRequest [this=%x]. Finished writing request to server." "\tStatus: %x\n", this, iStatus));
|
||||
|
||||
nsHTTPResponseListener* pListener = new nsHTTPServerListener (mConnection, mHandler);
|
||||
if (pListener)
|
||||
{
|
||||
NS_ADDREF (pListener);
|
||||
rv = mTransport -> AsyncRead (0, -1, i_Context, pListener);
|
||||
NS_RELEASE (pListener);
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_FAILURE; /* isAlive */
|
||||
} /* NS_SUCCEEDED */
|
||||
|
||||
//
|
||||
// An error occurred when trying to write the request to the server!
|
||||
//
|
||||
else {
|
||||
PR_LOG(gHTTPLog, PR_LOG_ERROR,
|
||||
("nsHTTPRequest [this=%x]. Error writing request to server."
|
||||
"\tStatus: %x\n",
|
||||
this, iStatus));
|
||||
|
||||
else
|
||||
{
|
||||
PR_LOG (gHTTPLog, PR_LOG_ERROR, ("nsHTTPRequest [this=%x]. Error writing request to server." "\tStatus: %x\n", this, iStatus));
|
||||
rv = iStatus;
|
||||
}
|
||||
|
||||
|
@ -517,23 +485,34 @@ nsHTTPRequest::OnStopRequest(nsIChannel* channel, nsISupports* i_Context,
|
|||
// An error occurred... Finish the transaction and notify the consumer
|
||||
// of the failure...
|
||||
//
|
||||
if (NS_FAILED(rv)) {
|
||||
if (NS_FAILED (rv))
|
||||
{
|
||||
PRUint32 wasKeptAlive = 0;
|
||||
|
||||
if (trans)
|
||||
trans -> GetReuseCount (&wasKeptAlive);
|
||||
|
||||
mHandler -> ReleaseTransport (mTransport, PR_FALSE);
|
||||
|
||||
if (wasKeptAlive)
|
||||
{
|
||||
rv = WriteRequest ();
|
||||
|
||||
if (NS_SUCCEEDED (rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Notify the HTTPChannel that the request has finished
|
||||
nsCOMPtr<nsIStreamListener> consumer;
|
||||
|
||||
mConnection->GetResponseDataListener(getter_AddRefs(consumer));
|
||||
|
||||
mConnection->ResponseCompleted(consumer, rv, i_Msg);
|
||||
mConnection->ReleaseTransport(mTransport);
|
||||
|
||||
NS_ASSERTION(!mTransport, "nsHTTRequest::ReleaseTransport() "
|
||||
"was not called!");
|
||||
mConnection -> GetResponseDataListener (getter_AddRefs (consumer));
|
||||
mConnection -> ResponseCompleted (consumer, rv, i_Msg);
|
||||
}
|
||||
|
||||
//
|
||||
// These resouces are no longer needed...
|
||||
//
|
||||
mRequestBuffer.Truncate();
|
||||
mRequestBuffer.Truncate ();
|
||||
mPostDataStream = null_nsCOMPtr();
|
||||
|
||||
return rv;
|
||||
|
@ -546,12 +525,18 @@ nsresult nsHTTPRequest::SetConnection(nsHTTPChannel* i_Connection)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsHTTPRequest::SetTransport(nsIChannel *aTransport)
|
||||
nsresult nsHTTPRequest::SetTransport (nsIChannel * aTransport)
|
||||
{
|
||||
mTransport = aTransport;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsHTTPRequest::GetTransport (nsIChannel **aTransport)
|
||||
{
|
||||
*aTransport = mTransport;
|
||||
return NS_OK;
|
||||
}
|
||||
/*
|
||||
nsresult nsHTTPRequest::ReleaseTransport(nsIChannel *aTransport)
|
||||
{
|
||||
if (aTransport == mTransport.get()) {
|
||||
|
@ -559,10 +544,10 @@ nsresult nsHTTPRequest::ReleaseTransport(nsIChannel *aTransport)
|
|||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*/
|
||||
nsresult nsHTTPRequest::GetHeaderEnumerator(nsISimpleEnumerator** aResult)
|
||||
{
|
||||
return mHeaders.GetEnumerator(aResult);
|
||||
return mHeaders.GetEnumerator (aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -578,3 +563,82 @@ nsHTTPRequest::GetOverrideRequestSpec(char** o_Spec)
|
|||
return DupString(o_Spec, mRequestSpec);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTTPRequest::formHeaders ()
|
||||
{
|
||||
nsXPIDLCString host;
|
||||
mURI -> GetHost (getter_Copies (host));
|
||||
PRInt32 port = -1;
|
||||
mURI -> GetPort (&port);
|
||||
|
||||
mHeaders.Clear ();
|
||||
|
||||
// Send Host header by default
|
||||
if (HTTP_ZERO_NINE != mVersion)
|
||||
{
|
||||
if (-1 != port)
|
||||
{
|
||||
char* tempHostPort =
|
||||
PR_smprintf("%s:%d", (const char*)host, port);
|
||||
if (tempHostPort)
|
||||
{
|
||||
SetHeader(nsHTTPAtoms::Host, tempHostPort);
|
||||
PR_smprintf_free (tempHostPort);
|
||||
tempHostPort = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
SetHeader(nsHTTPAtoms::Host, host);
|
||||
}
|
||||
|
||||
// Add the user-agent
|
||||
nsresult rv = NS_OK;
|
||||
NS_WITH_SERVICE(nsIHTTPProtocolHandler, httpHandler, kHTTPHandlerCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsXPIDLString ua;
|
||||
if (NS_SUCCEEDED (httpHandler -> GetUserAgent (getter_Copies(ua))))
|
||||
{
|
||||
nsCAutoString uaString ((const PRUnichar*)ua);
|
||||
SetHeader (nsHTTPAtoms::User_Agent, uaString.GetBuffer ());
|
||||
}
|
||||
|
||||
// Send */*. We're no longer chopping MIME-types for acceptance.
|
||||
// MIME based content negotiation has died.
|
||||
// SetHeader(nsHTTPAtoms::Accept, "image/gif, image/x-xbitmap, image/jpeg,
|
||||
// image/pjpeg, image/png, */*");
|
||||
SetHeader (nsHTTPAtoms::Accept, "*/*");
|
||||
|
||||
nsXPIDLCString acceptLanguages;
|
||||
// Add the Accept-Language header
|
||||
rv = httpHandler->GetAcceptLanguages (getter_Copies(acceptLanguages));
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (acceptLanguages && *acceptLanguages)
|
||||
SetHeader (nsHTTPAtoms::Accept_Language, acceptLanguages);
|
||||
}
|
||||
|
||||
nsXPIDLCString acceptEncodings;
|
||||
rv = httpHandler -> GetAcceptEncodings (getter_Copies (acceptEncodings));
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (acceptEncodings && *acceptEncodings)
|
||||
SetHeader (nsHTTPAtoms::Accept_Encoding, acceptEncodings);
|
||||
}
|
||||
|
||||
if (mDoKeepAlive)
|
||||
{
|
||||
char *p = PR_smprintf ("%d", mKeepAliveTimeout);
|
||||
|
||||
SetHeader (nsHTTPAtoms::Keep_Alive, p);
|
||||
PR_smprintf_free (p);
|
||||
|
||||
SetHeader (nsHTTPAtoms::Connection, "keep-alive");
|
||||
}
|
||||
else
|
||||
SetHeader (nsHTTPAtoms::Connection, "close");
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -32,6 +32,7 @@
|
|||
#include "nsIChannel.h"
|
||||
#include "nsHTTPHeaderArray.h"
|
||||
#include "nsHTTPEnums.h"
|
||||
#include "nsHTTPHandler.h"
|
||||
|
||||
class nsIInputStream;
|
||||
class nsHTTPChannel;
|
||||
|
@ -64,7 +65,7 @@ class nsHTTPRequest : public nsIStreamObserver,
|
|||
public:
|
||||
|
||||
// Constructor
|
||||
nsHTTPRequest(nsIURI* i_URL, HTTPMethod i_Method=HM_GET);
|
||||
nsHTTPRequest(nsIURI* i_URL, nsHTTPHandler* i_Handler, PRUint32 bufferSegmentSize, PRUint32 bufferMaxSize, HTTPMethod i_Method=HM_GET);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
|
@ -104,8 +105,9 @@ public:
|
|||
|
||||
nsresult SetConnection(nsHTTPChannel* i_Connection);
|
||||
|
||||
nsresult SetTransport(nsIChannel *aTransport);
|
||||
nsresult ReleaseTransport(nsIChannel *aTransport);
|
||||
nsresult SetTransport (nsIChannel * aTransport);
|
||||
nsresult GetTransport (nsIChannel **aTransport);
|
||||
// nsresult ReleaseTransport(nsIChannel *aTransport);
|
||||
|
||||
// Build the actual request string based on the settings.
|
||||
nsresult WriteRequest();
|
||||
|
@ -144,18 +146,23 @@ protected:
|
|||
nsCOMPtr<nsIURL> mURI;
|
||||
PRUint32 mVersion;
|
||||
PRUint32 mKeepAliveTimeout;
|
||||
PRUint32 mAttempts;
|
||||
PRBool mDoKeepAlive;
|
||||
nsCOMPtr<nsIChannel> mTransport;
|
||||
nsHTTPChannel* mConnection;
|
||||
|
||||
nsHTTPHeaderArray mHeaders;
|
||||
|
||||
nsCString mRequestBuffer;
|
||||
nsCOMPtr<nsIInputStream> mPostDataStream;
|
||||
nsCString mRequestBuffer;
|
||||
nsCOMPtr<nsIInputStream> mPostDataStream;
|
||||
char* mRequestSpec;
|
||||
|
||||
nsHTTPHandler* mHandler;
|
||||
|
||||
PRUint32 mBufferSegmentSize;
|
||||
PRUint32 mBufferMaxSize;
|
||||
|
||||
nsresult formHeaders ();
|
||||
};
|
||||
|
||||
#define NS_HTTP_REQUEST_SEGMENT_SIZE (4*1024)
|
||||
#define NS_HTTP_REQUEST_BUFFER_SIZE (16*1024)
|
||||
|
||||
#endif /* _nsHTTPRequest_h_ */
|
||||
|
|
|
@ -58,8 +58,8 @@ static const int kMAX_HEADER_SIZE = 60000;
|
|||
|
||||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
|
||||
nsHTTPResponseListener::nsHTTPResponseListener(nsHTTPChannel *aChannel)
|
||||
: mChannel(aChannel)
|
||||
nsHTTPResponseListener::nsHTTPResponseListener(nsHTTPChannel *aChannel, nsHTTPHandler *handler)
|
||||
: mChannel(aChannel), mHandler (handler)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
|
@ -114,8 +114,8 @@ NS_IMPL_QUERY_INTERFACE2(nsHTTPResponseListener,
|
|||
// the cache.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
nsHTTPCacheListener::nsHTTPCacheListener(nsHTTPChannel* aChannel)
|
||||
: nsHTTPResponseListener(aChannel)
|
||||
nsHTTPCacheListener::nsHTTPCacheListener(nsHTTPChannel* aChannel, nsHTTPHandler *handler)
|
||||
: nsHTTPResponseListener(aChannel, handler)
|
||||
{
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("Creating nsHTTPCacheListener [this=%x].\n", this));
|
||||
|
@ -210,13 +210,14 @@ nsresult nsHTTPCacheListener::Abort()
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel)
|
||||
: nsHTTPResponseListener(aChannel),
|
||||
nsHTTPServerListener::nsHTTPServerListener(nsHTTPChannel* aChannel, nsHTTPHandler *handler)
|
||||
: nsHTTPResponseListener (aChannel, handler),
|
||||
mResponse(nsnull),
|
||||
mFirstLineParsed(PR_FALSE),
|
||||
mHeadersDone(PR_FALSE),
|
||||
mBytesReceived(0),
|
||||
mBodyBytesReceived (0)
|
||||
mBodyBytesReceived (0),
|
||||
mCompressHeaderChecked (PR_FALSE)
|
||||
{
|
||||
mChannel->mHTTPServerListener = this;
|
||||
|
||||
|
@ -373,6 +374,33 @@ nsHTTPServerListener::OnDataAvailable(nsIChannel* channel,
|
|||
mChunkConverterPushed = PR_TRUE;
|
||||
}
|
||||
|
||||
if (!mCompressHeaderChecked)
|
||||
{
|
||||
rv = mResponse -> GetHeader (nsHTTPAtoms::Content_Encoding, getter_Copies (mCompressHeader));
|
||||
mCompressHeaderChecked = PR_TRUE;
|
||||
|
||||
if (NS_SUCCEEDED (rv) && mCompressHeader)
|
||||
{
|
||||
NS_WITH_SERVICE (nsIStreamConverterService,
|
||||
StreamConvService, kStreamConverterServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsString2 fromStr ( mCompressHeader );
|
||||
nsString2 toStr ( "uncompressed" );
|
||||
|
||||
nsCOMPtr<nsIStreamListener> converterListener;
|
||||
rv = StreamConvService->AsyncConvertData(
|
||||
fromStr.GetUnicode(),
|
||||
toStr.GetUnicode(),
|
||||
mResponseDataListener,
|
||||
channel,
|
||||
getter_AddRefs (converterListener));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mResponseDataListener = converterListener;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PR_LOG(gHTTPLog, PR_LOG_ALWAYS,
|
||||
("\tOnDataAvailable [this=%x]. Calling consumer "
|
||||
"OnDataAvailable.\tlength:%d\n", this, i_Length));
|
||||
|
@ -478,7 +506,7 @@ nsHTTPServerListener::OnStopRequest(nsIChannel* channel,
|
|||
}
|
||||
}
|
||||
|
||||
mChannel -> ReleaseTransport (channel, keepAlive);
|
||||
mHandler -> ReleaseTransport (channel, keepAlive);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mChannel);
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsHTTPHandler.h"
|
||||
|
||||
class nsIBufferInputStream;
|
||||
class nsHTTPResponse;
|
||||
|
@ -53,7 +55,7 @@ class nsHTTPChannel;
|
|||
class nsHTTPResponseListener : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
nsHTTPResponseListener(nsHTTPChannel* aConnection);
|
||||
nsHTTPResponseListener (nsHTTPChannel* aConnection, nsHTTPHandler *handler);
|
||||
virtual ~nsHTTPResponseListener();
|
||||
|
||||
// nsISupport methods...
|
||||
|
@ -69,8 +71,9 @@ public:
|
|||
void SetListener(nsIStreamListener *aListener);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIStreamListener> mResponseDataListener;
|
||||
nsHTTPChannel* mChannel;
|
||||
nsCOMPtr<nsIStreamListener> mResponseDataListener;
|
||||
nsHTTPChannel* mChannel;
|
||||
nsHTTPHandler* mHandler;
|
||||
};
|
||||
|
||||
|
||||
|
@ -82,7 +85,7 @@ class nsHTTPServerListener : public nsHTTPResponseListener
|
|||
|
||||
public:
|
||||
|
||||
nsHTTPServerListener(nsHTTPChannel* aConnection);
|
||||
nsHTTPServerListener(nsHTTPChannel* aConnection, nsHTTPHandler *handler);
|
||||
virtual ~nsHTTPServerListener();
|
||||
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
|
@ -116,6 +119,9 @@ protected:
|
|||
PRUint32 mBytesReceived;
|
||||
PRBool mChunkConverterPushed;
|
||||
PRInt32 mBodyBytesReceived;
|
||||
|
||||
nsXPIDLCString mCompressHeader;
|
||||
PRBool mCompressHeaderChecked;
|
||||
};
|
||||
|
||||
|
||||
|
@ -125,7 +131,7 @@ protected:
|
|||
class nsHTTPCacheListener : public nsHTTPResponseListener
|
||||
{
|
||||
public:
|
||||
nsHTTPCacheListener(nsHTTPChannel* aChannel);
|
||||
nsHTTPCacheListener(nsHTTPChannel* aChannel, nsHTTPHandler *handler);
|
||||
virtual ~nsHTTPCacheListener();
|
||||
|
||||
// nsIStreamObserver methods...
|
||||
|
|
|
@ -30,7 +30,7 @@ MODULE = converters
|
|||
LIBRARY_NAME = converters
|
||||
IS_COMPONENT = 1
|
||||
|
||||
REQUIRES = xpcom
|
||||
REQUIRES = xpcom zlib
|
||||
|
||||
CPPSRCS = \
|
||||
nsMultiMixedConv.cpp \
|
||||
|
@ -39,6 +39,7 @@ CPPSRCS = \
|
|||
mozTXTToHTMLConv.cpp \
|
||||
nsUnknownDecoder.cpp \
|
||||
nsHTTPChunkConv.cpp \
|
||||
nsHTTPCompressConv.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
|
|
|
@ -28,17 +28,19 @@ DLLNAME=cnvts
|
|||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
|
||||
EXPORTS = \
|
||||
nsMultiMixedConv.h \
|
||||
nsFTPDirListingConv.h \
|
||||
nsHTTPChunkConv.h \
|
||||
nsMultiMixedConv.h \
|
||||
nsFTPDirListingConv.h \
|
||||
nsHTTPChunkConv.h \
|
||||
nsHTTPCompressConv.h \
|
||||
$(NULL)
|
||||
|
||||
LLIBS= $(LLIBS) \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(LIBNSPR) \
|
||||
!ifdef MOZ_PERF
|
||||
$(DIST)\lib\util.lib \
|
||||
$(DIST)\lib\util.lib \
|
||||
!endif
|
||||
$(DIST)\lib\zlib.lib \
|
||||
$(NULL)
|
||||
|
||||
#
|
||||
|
@ -57,10 +59,11 @@ CPP_OBJS = \
|
|||
.\$(OBJDIR)\nsConvFactories.obj \
|
||||
.\$(OBJDIR)\mozTXTToHTMLConv.obj \
|
||||
.\$(OBJDIR)\nsHTTPChunkConv.obj \
|
||||
.\$(OBJDIR)\nsHTTPCompressConv.obj \
|
||||
.\$(OBJDIR)\nsUnknownDecoder.obj \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES=-I.
|
||||
LOCAL_INCLUDES=-I. -I$(XPDIST)\public\zlib
|
||||
|
||||
INCLUDES = $(LOCAL_INCLUDES)
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nsFTPDirListingConv.h"
|
||||
#include "nsMultiMixedConv.h"
|
||||
#include "nsHTTPChunkConv.h"
|
||||
#include "nsHTTPCompressConv.h"
|
||||
#include "mozTXTToHTMLConv.h"
|
||||
#include "nsUnknownDecoder.h"
|
||||
|
||||
|
@ -34,7 +35,7 @@ nsresult NS_NewFTPDirListingConv(nsFTPDirListingConv** result);
|
|||
nsresult NS_NewMultiMixedConv (nsMultiMixedConv** result);
|
||||
nsresult MOZ_NewTXTToHTMLConv (mozTXTToHTMLConv** result);
|
||||
nsresult NS_NewHTTPChunkConv (nsHTTPChunkConv ** result);
|
||||
|
||||
nsresult NS_NewHTTPCompressConv (nsHTTPCompressConv ** result);
|
||||
|
||||
static NS_IMETHODIMP
|
||||
CreateNewFTPDirListingConv(nsISupports* aOuter, REFNSIID aIID, void **aResult)
|
||||
|
@ -132,6 +133,30 @@ CreateNewHTTPChunkConvFactory (nsISupports* aOuter, REFNSIID aIID, void **aResul
|
|||
return rv;
|
||||
}
|
||||
|
||||
static NS_IMETHODIMP
|
||||
CreateNewHTTPCompressConvFactory (nsISupports* aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (!aResult) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
if (aOuter) {
|
||||
*aResult = nsnull;
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
}
|
||||
nsHTTPCompressConv* inst = nsnull;
|
||||
nsresult rv = NS_NewHTTPCompressConv (&inst);
|
||||
if (NS_FAILED(rv)) {
|
||||
*aResult = nsnull;
|
||||
return rv;
|
||||
}
|
||||
rv = inst->QueryInterface(aIID, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
*aResult = nsnull;
|
||||
}
|
||||
NS_RELEASE(inst); /* get rid of extra refcnt */
|
||||
return rv;
|
||||
}
|
||||
|
||||
static NS_IMETHODIMP
|
||||
CreateNewUnknownDecoderFactory(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
|
@ -211,6 +236,32 @@ static nsModuleComponentInfo components[] =
|
|||
CreateNewHTTPChunkConvFactory
|
||||
},
|
||||
|
||||
{ "HttpCompressConverter",
|
||||
NS_HTTPCOMPRESSCONVERTER_CID,
|
||||
NS_ISTREAMCONVERTER_KEY "?from=gzip?to=uncompressed",
|
||||
CreateNewHTTPCompressConvFactory
|
||||
},
|
||||
|
||||
{ "HttpCompressConverter",
|
||||
NS_HTTPCOMPRESSCONVERTER_CID,
|
||||
NS_ISTREAMCONVERTER_KEY "?from=x-gzip?to=uncompressed",
|
||||
CreateNewHTTPCompressConvFactory
|
||||
},
|
||||
{ "HttpCompressConverter",
|
||||
NS_HTTPCOMPRESSCONVERTER_CID,
|
||||
NS_ISTREAMCONVERTER_KEY "?from=compress?to=uncompressed",
|
||||
CreateNewHTTPCompressConvFactory
|
||||
},
|
||||
{ "HttpCompressConverter",
|
||||
NS_HTTPCOMPRESSCONVERTER_CID,
|
||||
NS_ISTREAMCONVERTER_KEY "?from=x-compress?to=uncompressed",
|
||||
CreateNewHTTPCompressConvFactory
|
||||
},
|
||||
{ "HttpCompressConverter",
|
||||
NS_HTTPCOMPRESSCONVERTER_CID,
|
||||
NS_ISTREAMCONVERTER_KEY "?from=deflate?to=uncompressed",
|
||||
CreateNewHTTPCompressConvFactory
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE("nsConvModule", components);
|
||||
|
|
Загрузка…
Ссылка в новой задаче