Commit 1dd2cdfb authored by darin%netscape.com's avatar darin%netscape.com
Browse files

fixes bug 92224 "8.2.4 Client Behavior if Server Prematurely Closes Connection"

r=bbaetz, sr=mscott
parent fda1d4c4
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -44,21 +44,28 @@
extern PRLogModuleInfo *gHttpLog;
#endif

// http logging
#define LOG1(args) PR_LOG(gHttpLog, 1, args)
#define LOG2(args) PR_LOG(gHttpLog, 2, args)
#define LOG3(args) PR_LOG(gHttpLog, 3, args)
#define LOG4(args) PR_LOG(gHttpLog, 4, args)
#define LOG(args) LOG4(args)

// http default buffer geometry
#define NS_HTTP_SEGMENT_SIZE 4096
#define NS_HTTP_BUFFER_SIZE  4096*4 // 16k maximum

enum nsHttpVersion {
    NS_HTTP_VERSION_UNKNOWN,
    NS_HTTP_VERSION_0_9,
    NS_HTTP_VERSION_1_0,
    NS_HTTP_VERSION_1_1
};
// http version codes
#define NS_HTTP_VERSION_UNKNOWN  0
#define NS_HTTP_VERSION_0_9      9
#define NS_HTTP_VERSION_1_0     10
#define NS_HTTP_VERSION_1_1     11

typedef PRUint8 nsHttpVersion;

// http connection capabilities
#define NS_HTTP_ALLOW_KEEPALIVE  (1<<0)
#define NS_HTTP_ALLOW_PIPELINING (1<<1)

//-----------------------------------------------------------------------------
// http atoms...
@@ -117,4 +124,8 @@ PRTimeToSeconds(PRTime t_usec)

#define NowInSeconds() PRTimeToSeconds(PR_Now())

#endif
// ripped from glib.h
#undef  CLAMP
#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))

#endif // nsHttp_h__
+4 −5
Original line number Diff line number Diff line
@@ -52,8 +52,8 @@ nsHttpChannel::nsHttpChannel()
    , mPrevTransaction(nsnull)
    , mConnectionInfo(nsnull)
    , mLoadFlags(LOAD_NORMAL)
    , mCapabilities(0)
    , mStatus(NS_OK)
    , mCapabilities(0)
    , mReferrerType(REFERRER_NONE)
    , mCachedResponseHead(nsnull)
    , mCacheAccess(0)
@@ -98,7 +98,7 @@ nsHttpChannel::~nsHttpChannel()

nsresult
nsHttpChannel::Init(nsIURI *uri,
                    PRUint32 caps,
                    PRUint8 caps,
                    const char *proxyHost,
                    PRInt32 proxyPort,
                    const char *proxyType)
@@ -171,8 +171,7 @@ nsHttpChannel::Init(nsIURI *uri,
    PRBool useProxy = (proxyHost && !PL_strcmp(proxyType, "http"));

    rv = nsHttpHandler::get()->AddStandardRequestHeaders(&mRequestHead.Headers(),
                                                         caps,
                                                         useProxy);
                                                         caps, useProxy);
    if (NS_FAILED(rv)) return rv;

    // check to see if authorization headers should be included
@@ -1922,7 +1921,7 @@ nsHttpChannel::SetReferrer(nsIURI *referrer, PRUint32 referrerType)
    mReferrer = referrer;

    // save a copy of the referrer type for redirects
    mReferrerType = referrerType;
    mReferrerType = (PRUint8) referrerType;

    // clear the old referer first
    mRequestHead.SetHeader(nsHttp::Referer, nsnull);
+3 −3
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ public:
    virtual ~nsHttpChannel();

    nsresult Init(nsIURI *uri,
                  PRUint32 capabilities,
                  PRUint8 capabilities,
                  const char *proxyHost=0,
                  PRInt32 proxyPort=-1,
                  const char *proxyType=0);
@@ -133,9 +133,9 @@ private:
    nsXPIDLCString                    mSpec;

    PRUint32                          mLoadFlags;
    PRUint32                          mCapabilities;
    PRUint32                          mStatus;
    PRUint32                          mReferrerType;
    PRUint8                           mCapabilities;
    PRUint8                           mReferrerType;

    // cache specific data
    nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry;
+9 −21
Original line number Diff line number Diff line
@@ -47,10 +47,8 @@ nsHttpConnection::nsHttpConnection()
    : mTransaction(0)
    , mConnectionInfo(0)
    , mLock(nsnull)
    , mReuseCount(0)
    , mMaxReuseCount(0)
    , mIdleTimeout(0)
    , mLastActiveTime(0)
    , mIdleTimeout(0)
    , mKeepAlive(0)
    , mWriteDone(0)
    , mReadDone(0)
@@ -166,30 +164,20 @@ nsHttpConnection::OnHeadersAvailable(nsHttpTransaction *trans, PRBool *reset)
    // if this connection is persistent, then the server may send a "Keep-Alive"
    // header specifying the maximum number of times the connection can be
    // reused as well as the maximum amount of time the connection can be idle
    // before the server will close it.  If this header is not present, then we
    // pick a suitably large number. Technically, any number > 0 will do, since
    // we reset this each time, and with HTTP/1.1 connections continue until we
    // get a {Proxy-,}Connection: close header. Don't just use 1 though, because
    // of pipelining
    // before the server will close it.  we ignore the max reuse count, because
    // a "keep-alive" connection is by definition capable of being reused, and
    // we only care about being able to reuse it once.  if a timeout is not 
    // specified then we use our advertized timeout value.
    if (mKeepAlive) {
        val = trans->ResponseHead()->PeekHeader(nsHttp::Keep_Alive);

        LOG(("val = [%s]\n", val));

        const char *cp = PL_strcasestr(val, "max=");
        if (cp)
            mMaxReuseCount = (PRUint32) atoi(cp + 4);
        else
            mMaxReuseCount = 100;

        cp = PL_strcasestr(val, "timeout=");
        const char *cp = PL_strcasestr(val, "timeout=");
        if (cp)
            mIdleTimeout = (PRUint32) atoi(cp + 8);
        else
            mIdleTimeout = nsHttpHandler::get()->IdleTimeout();
        
        LOG(("Connection can be reused [this=%x max-reuse=%u "
             "keep-alive-timeout=%u\n", this, mMaxReuseCount, mIdleTimeout));
        LOG(("Connection can be reused [this=%x idle-timeout=%u\n", this, mIdleTimeout));
    }

    // if we're doing an SSL proxy connect, then we need to check whether or not
@@ -302,8 +290,8 @@ nsHttpConnection::ProxyStepUp()
PRBool
nsHttpConnection::CanReuse()
{
    return mKeepAlive && (mReuseCount < mMaxReuseCount) && 
           (NowInSeconds() - mLastActiveTime < mIdleTimeout) && IsAlive();
    return mKeepAlive && (NowInSeconds() - mLastActiveTime < mIdleTimeout)
                      && IsAlive();
}

PRBool
+2 −8
Original line number Diff line number Diff line
@@ -86,13 +86,9 @@ public:
    PRBool   CanReuse(); // can this connection be reused?
    PRBool   IsAlive();
    PRBool   IsKeepAlive()   { return mKeepAlive; }
    PRUint32 ReuseCount()    { return mReuseCount; }
    PRUint32 MaxReuseCount() { return mMaxReuseCount; }
    PRUint32 IdleTimeout()   { return mIdleTimeout; }
    PRUint16 IdleTimeout()   { return mIdleTimeout; }

    void     DontReuse()     { mKeepAlive = PR_FALSE;
                               mReuseCount = 0;
                               mMaxReuseCount = 0;
                               mIdleTimeout = 0; }

    void DropTransaction();
@@ -126,10 +122,8 @@ private:

    PRLock                         *mLock;

    PRUint32                        mReuseCount;
    PRUint32                        mMaxReuseCount; // value of keep-alive: max=
    PRUint32                        mIdleTimeout;   // value of keep-alive: timeout=
    PRUint32                        mLastActiveTime;
    PRUint16                        mIdleTimeout;   // value of keep-alive: timeout=

    PRPackedBool                    mKeepAlive;
    PRPackedBool                    mWriteDone;
Loading