Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes
nsHttpTransaction Class Reference

#include <nsHttpTransaction.h>

Inheritance diagram for nsHttpTransaction:
Inheritance graph
[legend]
Collaboration diagram for nsHttpTransaction:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSAHTTPTRANSACTION
NS_DECL_NSIINPUTSTREAMCALLBACK
NS_DECL_NSIOUTPUTSTREAMCALLBACK 
nsHttpTransaction ()
virtual ~nsHttpTransaction ()
nsresult Init (PRUint8 caps, nsHttpConnectionInfo *connInfo, nsHttpRequestHead *reqHeaders, nsIInputStream *reqBody, PRBool reqBodyIncludesHeaders, nsIEventQueue *consumerEventQ, nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink, nsIAsyncInputStream **responseBody)
PRUint8 Caps ()
nsHttpConnectionInfoConnectionInfo ()
nsHttpRequestHeadRequestHead ()
nsHttpResponseHeadResponseHead ()
nsISupports * SecurityInfo ()
nsIInterfaceRequestorCallbacks ()
nsIEventQueueConsumerEventQ ()
nsAHttpConnectionConnection ()
nsHttpResponseHeadTakeResponseHead ()
PRBool ResponseIsComplete ()
void SetSSLConnectFailed ()
PRBool SSLConnectFailed ()
void SetPriority (PRInt32 priority)
PRInt32 Priority ()
virtual void SetConnection (nsAHttpConnection *)=0
virtual void GetSecurityCallbacks (nsIInterfaceRequestor **)=0
virtual void OnTransportStatus (nsresult status, PRUint64 progress)=0
virtual PRBool IsDone ()=0
virtual nsresult Status ()=0
virtual PRUint32 Available ()=0
virtual nsresult ReadSegments (nsAHttpSegmentReader *reader, PRUint32 count, PRUint32 *countRead)=0
virtual nsresult WriteSegments (nsAHttpSegmentWriter *writer, PRUint32 count, PRUint32 *countWritten)=0
virtual void Close (nsresult reason)=0
void onInputStreamReady (in nsIAsyncInputStream aStream)
 Called to indicate that the stream is either readable or closed.
void onOutputStreamReady (in nsIAsyncOutputStream aStream)
 Called to indicate that the stream is either writable or closed.

Private Member Functions

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 Private Member Functions

static void *PR_CALLBACK TransportStatus_Handler (PLEvent *)
static void PR_CALLBACK TransportStatus_Cleanup (PLEvent *)
static void *PR_CALLBACK DeleteThis_Handler (PLEvent *)
static void PR_CALLBACK DeleteThis_Cleanup (PLEvent *)
static NS_METHOD ReadRequestSegment (nsIInputStream *, void *, const char *, PRUint32, PRUint32, PRUint32 *)
static NS_METHOD WritePipeSegment (nsIOutputStream *, void *, char *, PRUint32, PRUint32, PRUint32 *)

Private Attributes

nsCOMPtr< nsIInterfaceRequestormCallbacks
nsCOMPtr< nsITransportEventSinkmTransportSink
nsCOMPtr< nsIEventQueuemConsumerEventQ
nsCOMPtr< nsISupports > mSecurityInfo
nsCOMPtr< nsIAsyncInputStreammPipeIn
nsCOMPtr< nsIAsyncOutputStreammPipeOut
nsCOMPtr< nsISupports > mChannel
nsCOMPtr< nsIHttpActivityObservermActivityDistributor
nsCString mReqHeaderBuf
nsCOMPtr< nsIInputStreammRequestStream
PRUint32 mRequestSize
nsAHttpConnectionmConnection
nsHttpConnectionInfomConnInfo
nsHttpRequestHeadmRequestHead
nsHttpResponseHeadmResponseHead
nsAHttpSegmentReadermReader
nsAHttpSegmentWritermWriter
nsCString mLineBuf
nsInt64 mContentLength
nsInt64 mContentRead
nsHttpChunkedDecodermChunkedDecoder
nsresult mStatus
PRInt16 mPriority
PRUint16 mRestartCount
PRUint8 mCaps
PRUint32 mClosed: 1
PRUint32 mDestroying: 1
PRUint32 mConnected: 1
PRUint32 mHaveStatusLine: 1
PRUint32 mHaveAllHeaders: 1
PRUint32 mTransactionDone: 1
PRUint32 mResponseIsComplete: 1
PRUint32 mDidContentStart: 1
PRUint32 mNoContent: 1
PRUint32 mSentData: 1
PRUint32 mReceivedData: 1
PRUint32 mStatusEventPending: 1
PRUint32 mHasRequestBody: 1
PRUint32 mSSLConnectFailed: 1

Detailed Description

Definition at line 70 of file nsHttpTransaction.h.


Constructor & Destructor Documentation

Definition at line 152 of file nsHttpTransaction.cpp.

{
    LOG(("Destroying nsHttpTransaction @%x\n", this));

    NS_IF_RELEASE(mConnection);
    NS_IF_RELEASE(mConnInfo);

    delete mResponseHead;
    delete mChunkedDecoder;
}

Member Function Documentation

virtual PRUint32 nsAHttpTransaction::Available ( ) [pure virtual, inherited]

Here is the caller graph for this function:

Definition at line 122 of file nsHttpTransaction.h.

{ return mCallbacks; } 

Definition at line 116 of file nsHttpTransaction.h.

{ return mCaps; }

Here is the caller graph for this function:

virtual void nsAHttpTransaction::Close ( nsresult  reason) [pure virtual, inherited]

Here is the caller graph for this function:

Definition at line 124 of file nsHttpTransaction.h.

{ return mConnection; }

Here is the caller graph for this function:

Definition at line 117 of file nsHttpTransaction.h.

{ return mConnInfo; }

Here is the caller graph for this function:

Definition at line 123 of file nsHttpTransaction.h.

{ return mConsumerEventQ; }

Definition at line 1034 of file nsHttpTransaction.cpp.

{
    nsCOMPtr<nsIEventQueueService> eqs;
    nsCOMPtr<nsIEventQueue> currentEventQ;

    LOG(("nsHttpTransaction::DeleteSelfOnConsumerThread [this=%x]\n", this));
    
    NS_ASSERTION(!mDestroying, "deleting self again");
    mDestroying = PR_TRUE;

    gHttpHandler->GetCurrentEventQ(getter_AddRefs(currentEventQ));

    if (currentEventQ == mConsumerEventQ)
        delete this;
    else {
        LOG(("proxying delete to consumer thread...\n"));

        PLEvent *event = new PLEvent;
        if (!event) {
            NS_WARNING("out of memory");
            // probably better to leak |this| than to delete it on this thread.
            return;
        }

        PL_InitEvent(event, this, DeleteThis_Handler, DeleteThis_Cleanup);

        nsresult status = mConsumerEventQ->PostEvent(event);
        if (NS_FAILED(status))
            NS_ERROR("PostEvent failed");
    }
}

Here is the call graph for this function:

Definition at line 1079 of file nsHttpTransaction.cpp.

{
    delete ev;
}

Here is the caller graph for this function:

Definition at line 1067 of file nsHttpTransaction.cpp.

{
    nsHttpTransaction *trans =
            NS_STATIC_CAST(nsHttpTransaction *, PL_GetEventOwner(ev));

    LOG(("nsHttpTransaction::DeleteThis_EventHandlerFunc [trans=%x]\n", trans));

    delete trans;
    return nsnull;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void nsAHttpTransaction::GetSecurityCallbacks ( nsIInterfaceRequestor **  ) [pure virtual, inherited]
nsresult nsHttpTransaction::HandleContent ( char *  buf,
PRUint32  count,
PRUint32 contentRead,
PRUint32 contentRemaining 
) [private]

Definition at line 874 of file nsHttpTransaction.cpp.

{
    nsresult rv;

    LOG(("nsHttpTransaction::HandleContent [this=%x count=%u]\n", this, count));

    *contentRead = 0;
    *contentRemaining = 0;

    NS_ASSERTION(mConnection, "no connection");

    if (!mDidContentStart) {
        rv = HandleContentStart();
        if (NS_FAILED(rv)) return rv;
        // Do not write content to the pipe if we haven't started streaming yet
        if (!mDidContentStart)
            return NS_OK;
    }

    if (mChunkedDecoder) {
        // give the buf over to the chunked decoder so it can reformat the
        // data and tell us how much is really there.
        rv = mChunkedDecoder->HandleChunkedContent(buf, count, contentRead, contentRemaining);
        if (NS_FAILED(rv)) return rv;
    }
    else if (mContentLength >= nsInt64(0)) {
        // HTTP/1.0 servers have been known to send erroneous Content-Length
        // headers. So, unless the connection is persistent, we must make
        // allowances for a possibly invalid Content-Length header. Thus, if
        // NOT persistent, we simply accept everything in |buf|.
        if (mConnection->IsPersistent()) {
            nsInt64 remaining = mContentLength - mContentRead;
            nsInt64 count64 = count;
            *contentRead = PR_MIN(count64, remaining);
            *contentRemaining = count - *contentRead;
        }
        else {
            *contentRead = count;
            // mContentLength might need to be increased...
            nsInt64 position = mContentRead + nsInt64(count);
            if (position > mContentLength) {
                mContentLength = position;
                //mResponseHead->SetContentLength(mContentLength);
            }
        }
    }
    else {
        // when we are just waiting for the server to close the connection...
        // (no explicit content-length given)
        *contentRead = count;
    }

    if (*contentRead) {
        // update count of content bytes read and report progress...
        mContentRead += *contentRead;
        /* when uncommenting, take care of 64-bit integers w/ PR_MAX...
        if (mProgressSink)
            mProgressSink->OnProgress(nsnull, nsnull, mContentRead, PR_MAX(0, mContentLength));
        */
    }

    LOG(("nsHttpTransaction::HandleContent [this=%x count=%u read=%u mContentRead=%lld mContentLength=%lld]\n",
        this, count, *contentRead, mContentRead.mValue, mContentLength.mValue));

    // check for end-of-file
    if ((mContentRead == mContentLength) ||
        (mChunkedDecoder && mChunkedDecoder->ReachedEOF())) {
        // the transaction is done with a complete response.
        mTransactionDone = PR_TRUE;
        mResponseIsComplete = PR_TRUE;

        // report the entire response has arrived
        if (mActivityDistributor)
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_COMPLETE,
                LL_ZERO,
                NS_STATIC_CAST(PRUint64, mContentRead.mValue),
                EmptyCString());
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 799 of file nsHttpTransaction.cpp.

{
    LOG(("nsHttpTransaction::HandleContentStart [this=%x]\n", this));

    if (mResponseHead) {
#if defined(PR_LOGGING)
        if (LOG3_ENABLED()) {
            LOG3(("http response [\n"));
            nsCAutoString headers;
            mResponseHead->Flatten(headers, PR_FALSE);
            LogHeaders(headers.get());
            LOG3(("]\n"));
        }
#endif
        // notify the connection, give it a chance to cause a reset.
        PRBool reset = PR_FALSE;
        mConnection->OnHeadersAvailable(this, mRequestHead, mResponseHead, &reset);

        // looks like we should ignore this response, resetting...
        if (reset) {
            LOG(("resetting transaction's response head\n"));
            mHaveAllHeaders = PR_FALSE;
            mHaveStatusLine = PR_FALSE;
            mReceivedData = PR_FALSE;
            mSentData = PR_FALSE;
            mResponseHead->Reset();
            // wait to be called again...
            return NS_OK;
        }

        // check if this is a no-content response
        switch (mResponseHead->Status()) {
        case 204:
        case 205:
        case 304:
            mNoContent = PR_TRUE;
            LOG(("this response should not contain a body.\n"));
            break;
        }

        if (mNoContent)
            mContentLength = 0;
        else {
            // grab the content-length from the response headers
            mContentLength = mResponseHead->ContentLength();

            // handle chunked encoding here, so we'll know immediately when
            // we're done with the socket.  please note that _all_ other
            // decoding is done when the channel receives the content data
            // so as not to block the socket transport thread too much.
            // ignore chunked responses from HTTP/1.0 servers and proxies.
            const char *val = mResponseHead->PeekHeader(nsHttp::Transfer_Encoding);
            if (mResponseHead->Version() >= NS_HTTP_VERSION_1_1 &&
                PL_strcasestr(val, "chunked")) {
                // we only support the "chunked" transfer encoding right now.
                mChunkedDecoder = new nsHttpChunkedDecoder();
                if (!mChunkedDecoder)
                    return NS_ERROR_OUT_OF_MEMORY;
                LOG(("chunked decoder created\n"));
                // Ignore server specified Content-Length.
                mContentLength = -1;
            }
#if defined(PR_LOGGING)
            else if (mContentLength == nsInt64(-1))
                LOG(("waiting for the server to close the connection.\n"));
#endif
        }
    }

    mDidContentStart = PR_TRUE;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsHttpTransaction::Init ( PRUint8  caps,
nsHttpConnectionInfo connInfo,
nsHttpRequestHead reqHeaders,
nsIInputStream reqBody,
PRBool  reqBodyIncludesHeaders,
nsIEventQueue consumerEventQ,
nsIInterfaceRequestor callbacks,
nsITransportEventSink eventsink,
nsIAsyncInputStream **  responseBody 
)

Definition at line 164 of file nsHttpTransaction.cpp.

{
    nsresult rv;

    LOG(("nsHttpTransaction::Init [this=%x caps=%x]\n", this, caps));

    NS_ASSERTION(cinfo, "ouch");
    NS_ASSERTION(requestHead, "ouch");
    NS_ASSERTION(queue, "ouch");

    // create transport event sink proxy that coalesces all events
    rv = net_NewTransportEventSinkProxy(getter_AddRefs(mTransportSink),
                                        eventsink, queue, PR_TRUE);
    if (NS_FAILED(rv)) return rv;

    // try to get the nsIHttpActivityObserver distributor
    mActivityDistributor = do_GetService(NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &rv);

    // mActivityDistributor may not be valid
    if (NS_SUCCEEDED(rv) && mActivityDistributor) {
        // the service is valid, now check if it is active
        PRBool active;
        rv = mActivityDistributor->GetIsActive(&active);
        if (NS_SUCCEEDED(rv) && active) {
            // the service is valid and active, gather nsISupports
            // for the channel that called Init()
            mChannel = do_QueryInterface(eventsink);
            LOG(("nsHttpTransaction::Init() " \
                 "mActivityDistributor is active " \
                 "this=%x", this));
        } else
            // the interface in valid but not active, so don't use it
            mActivityDistributor = nsnull;
    }

    NS_ADDREF(mConnInfo = cinfo);
    mCallbacks = callbacks;
    mConsumerEventQ = queue;
    mCaps = caps;

    if (requestHead->Method() == nsHttp::Head)
        mNoContent = PR_TRUE;

    // grab a weak reference to the request head
    mRequestHead = requestHead;

    // make sure we eliminate any proxy specific headers from 
    // the request if we are talking HTTPS via a SSL tunnel.
    PRBool pruneProxyHeaders = cinfo->UsingSSL() &&
                               cinfo->UsingHttpProxy();
    mReqHeaderBuf.Truncate();
    requestHead->Flatten(mReqHeaderBuf, pruneProxyHeaders);

#if defined(PR_LOGGING)
    if (LOG3_ENABLED()) {
        LOG3(("http request [\n"));
        LogHeaders(mReqHeaderBuf.get());
        LOG3(("]\n"));
    }
#endif

    // If the request body does not include headers or if there is no request
    // body, then we must add the header/body separator manually.
    if (!requestBodyHasHeaders || !requestBody)
        mReqHeaderBuf.AppendLiteral("\r\n");

    // report the request header
    if (mActivityDistributor)
        mActivityDistributor->ObserveActivity(
            mChannel,
            NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
            NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_HEADER,
            LL_ZERO, LL_ZERO,
            mReqHeaderBuf);

    // Create a string stream for the request header buf (the stream holds
    // a non-owning reference to the request header data, so we MUST keep
    // mReqHeaderBuf around).
    nsCOMPtr<nsIInputStream> headers;
    rv = NS_NewByteInputStream(getter_AddRefs(headers),
                               mReqHeaderBuf.get(),
                               mReqHeaderBuf.Length());
    if (NS_FAILED(rv)) return rv;

    if (requestBody) {
        mHasRequestBody = PR_TRUE;

        // wrap the headers and request body in a multiplexed input stream.
        nsCOMPtr<nsIMultiplexInputStream> multi =
            do_CreateInstance(kMultiplexInputStream, &rv);
        if (NS_FAILED(rv)) return rv;

        rv = multi->AppendStream(headers);
        if (NS_FAILED(rv)) return rv;

        rv = multi->AppendStream(requestBody);
        if (NS_FAILED(rv)) return rv;

        mRequestStream = multi;
    }
    else
        mRequestStream = headers;

    rv = mRequestStream->Available(&mRequestSize);
    if (NS_FAILED(rv)) return rv;

    // create pipe for response stream
    rv = NS_NewPipe2(getter_AddRefs(mPipeIn),
                     getter_AddRefs(mPipeOut),
                     PR_TRUE, PR_TRUE,
                     NS_HTTP_SEGMENT_SIZE,
                     NS_HTTP_SEGMENT_COUNT,
                     nsIOService::gBufferCache);
    if (NS_FAILED(rv)) return rv;

    NS_ADDREF(*responseBody = mPipeIn);
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual PRBool nsAHttpTransaction::IsDone ( ) [pure virtual, inherited]

Here is the caller graph for this function:

Called to indicate that the stream is either readable or closed.

Parameters:
aStreamThe stream whose asyncWait method was called.

Called to indicate that the stream is either writable or closed.

Parameters:
aStreamThe stream whose asyncWait method was called.
virtual void nsAHttpTransaction::OnTransportStatus ( nsresult  status,
PRUint64  progress 
) [pure virtual, inherited]

Here is the caller graph for this function:

nsresult nsHttpTransaction::ParseHead ( char *  buf,
PRUint32  count,
PRUint32 countRead 
) [private]

Definition at line 709 of file nsHttpTransaction.cpp.

{
    nsresult rv;
    PRUint32 len;
    char *eol;

    LOG(("nsHttpTransaction::ParseHead [count=%u]\n", count));

    *countRead = 0;

    NS_PRECONDITION(!mHaveAllHeaders, "oops");
        
    // allocate the response head object if necessary
    if (!mResponseHead) {
        mResponseHead = new nsHttpResponseHead();
        if (!mResponseHead)
            return NS_ERROR_OUT_OF_MEMORY;

        // report that we have a least some of the response
        if (mActivityDistributor)
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_START,
                LL_ZERO, LL_ZERO, EmptyCString());
    }

    // if we don't have a status line and the line buf is empty, then
    // this must be the first time we've been called.
    if (!mHaveStatusLine && mLineBuf.IsEmpty()) {
        // tolerate some junk before the status line
        char *p = LocateHttpStart(buf, PR_MIN(count, 8));
        if (!p) {
            // Treat any 0.9 style response of a put as a failure.
            if (mRequestHead->Method() == nsHttp::Put)
                return NS_ERROR_ABORT;

            mResponseHead->ParseStatusLine("");
            mHaveStatusLine = PR_TRUE;
            mHaveAllHeaders = PR_TRUE;
            return NS_OK;
        }
        if (p > buf) {
            // skip over the junk
            *countRead = p - buf;
            buf = p;
        }
    }
    // otherwise we can assume that we don't have a HTTP/0.9 response.

    while ((eol = NS_STATIC_CAST(char *, memchr(buf, '\n', count - *countRead))) != nsnull) {
        // found line in range [buf:eol]
        len = eol - buf + 1;

        *countRead += len;

        // actually, the line is in the range [buf:eol-1]
        if ((eol > buf) && (*(eol-1) == '\r'))
            len--;

        buf[len-1] = '\n';
        rv = ParseLineSegment(buf, len);
        if (NS_FAILED(rv))
            return rv;

        if (mHaveAllHeaders)
            return NS_OK;

        // skip over line
        buf = eol + 1;
    }

    // do something about a partial header line
    if (!mHaveAllHeaders && (len = count - *countRead)) {
        *countRead = count;
        // ignore a trailing carriage return, and don't bother calling
        // ParseLineSegment if buf only contains a carriage return.
        if ((buf[len-1] == '\r') && (--len == 0))
            return NS_OK;
        rv = ParseLineSegment(buf, len);
        if (NS_FAILED(rv))
            return rv;
    }
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsHttpTransaction::ParseLine ( char *  line) [private]

Definition at line 654 of file nsHttpTransaction.cpp.

{
    LOG(("nsHttpTransaction::ParseLine [%s]\n", line));

    if (!mHaveStatusLine) {
        mResponseHead->ParseStatusLine(line);
        mHaveStatusLine = PR_TRUE;
        // XXX this should probably never happen
        if (mResponseHead->Version() == NS_HTTP_VERSION_0_9)
            mHaveAllHeaders = PR_TRUE;
    }
    else
        mResponseHead->ParseHeaderLine(line);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsHttpTransaction::ParseLineSegment ( char *  seg,
PRUint32  len 
) [private]

Definition at line 670 of file nsHttpTransaction.cpp.

{
    NS_PRECONDITION(!mHaveAllHeaders, "already have all headers");

    if (!mLineBuf.IsEmpty() && mLineBuf.Last() == '\n') {
        // trim off the new line char, and if this segment is
        // not a continuation of the previous or if we haven't
        // parsed the status line yet, then parse the contents
        // of mLineBuf.
        mLineBuf.Truncate(mLineBuf.Length() - 1);
        if (!mHaveStatusLine || (*segment != ' ' && *segment != '\t')) {
            ParseLine(mLineBuf.BeginWriting());
            mLineBuf.Truncate();
        }
    }

    // append segment to mLineBuf...
    if (mLineBuf.Length() + len > MAX_LINEBUF_LENGTH) {
        LOG(("excessively long header received, canceling transaction [trans=%x]", this));
        return NS_ERROR_ABORT;
    }
    mLineBuf.Append(segment, len);
    
    // a line buf with only a new line char signifies the end of headers.
    if (mLineBuf.First() == '\n') {
        mLineBuf.Truncate();
        // discard this response if it is a 100 continue or other 1xx status.
        if (mResponseHead->Status() / 100 == 1) {
            LOG(("ignoring 1xx response\n"));
            mHaveStatusLine = PR_FALSE;
            mResponseHead->Reset();
            return NS_OK;
        }
        mHaveAllHeaders = PR_TRUE;
    }
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 138 of file nsHttpTransaction.h.

{ return mPriority; }

Here is the caller graph for this function:

nsresult nsHttpTransaction::ProcessData ( char *  buf,
PRUint32  count,
PRUint32 countRead 
) [private]

Definition at line 963 of file nsHttpTransaction.cpp.

{
    nsresult rv;

    LOG(("nsHttpTransaction::ProcessData [this=%x count=%u]\n", this, count));

    *countRead = 0;

    // we may not have read all of the headers yet...
    if (!mHaveAllHeaders) {
        PRUint32 bytesConsumed = 0;

        rv = ParseHead(buf, count, &bytesConsumed);
        if (NS_FAILED(rv)) return rv;

        count -= bytesConsumed;

        // if buf has some content in it, shift bytes to top of buf.
        if (count && bytesConsumed)
            memmove(buf, buf + bytesConsumed, count);

        // report the completed response header
        if (mActivityDistributor && mResponseHead && mHaveAllHeaders) {
            nsCAutoString completeResponseHeaders;
            mResponseHead->Flatten(completeResponseHeaders, PR_FALSE);
            completeResponseHeaders.AppendLiteral("\r\n");
            mActivityDistributor->ObserveActivity(
                mChannel,
                NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                NS_HTTP_ACTIVITY_SUBTYPE_RESPONSE_HEADER,
                LL_ZERO, LL_ZERO,
                completeResponseHeaders);
        }
    }

    // even though count may be 0, we still want to call HandleContent
    // so it can complete the transaction if this is a "no-content" response.
    if (mHaveAllHeaders) {
        PRUint32 countRemaining = 0;
        //
        // buf layout:
        // 
        // +--------------------------------------+----------------+-----+
        // |              countRead               | countRemaining |     |
        // +--------------------------------------+----------------+-----+
        //
        // count          : bytes read from the socket
        // countRead      : bytes corresponding to this transaction
        // countRemaining : bytes corresponding to next pipelined transaction
        //
        // NOTE:
        // count > countRead + countRemaining <==> chunked transfer encoding
        //
        rv = HandleContent(buf, count, countRead, &countRemaining);
        if (NS_FAILED(rv)) return rv;
        // we may have read more than our share, in which case we must give
        // the excess bytes back to the connection
        if (mResponseIsComplete && countRemaining) {
            NS_ASSERTION(mConnection, "no connection");
            mConnection->PushBack(buf + *countRead, countRemaining);
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_METHOD nsHttpTransaction::ReadRequestSegment ( nsIInputStream stream,
void closure,
const char *  buf,
PRUint32  offset,
PRUint32  count,
PRUint32 countRead 
) [static, private]

Definition at line 397 of file nsHttpTransaction.cpp.

{
    nsHttpTransaction *trans = (nsHttpTransaction *) closure;
    nsresult rv = trans->mReader->OnReadSegment(buf, count, countRead);
    if (NS_FAILED(rv)) return rv;

    trans->mSentData = PR_TRUE;
    return NS_OK;
}

Here is the call graph for this function:

virtual nsresult nsAHttpTransaction::ReadSegments ( nsAHttpSegmentReader reader,
PRUint32  count,
PRUint32 countRead 
) [pure virtual, inherited]

Here is the caller graph for this function:

Definition at line 118 of file nsHttpTransaction.h.

{ return mRequestHead; }

Here is the caller graph for this function:

Definition at line 119 of file nsHttpTransaction.h.

Definition at line 131 of file nsHttpTransaction.h.

{ return mResponseIsComplete; }

Definition at line 624 of file nsHttpTransaction.cpp.

{
    NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");

    // limit the number of restart attempts - bug 92224
    if (++mRestartCount >= gHttpHandler->MaxRequestAttempts()) {
        LOG(("reached max request attempts, failing transaction @%x\n", this));
        return NS_ERROR_NET_RESET;
    }

    LOG(("restarting transaction @%x\n", this));

    // rewind streams in case we already wrote out the request
    nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mRequestStream);
    if (seekable)
        seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);

    // clear old connection state...
    mSecurityInfo = 0;
    NS_IF_RELEASE(mConnection);

    // disable pipelining for the next attempt in case pipelining caused the
    // reset.  this is being overly cautious since we don't know if pipelining
    // was the problem here.
    mCaps &= ~NS_HTTP_ALLOW_PIPELINING;

    return gHttpHandler->InitiateTransaction(this, mPriority);
}

Here is the call graph for this function:

nsISupports* nsHttpTransaction::SecurityInfo ( ) [inline]

Definition at line 120 of file nsHttpTransaction.h.

{ return mSecurityInfo; }
virtual void nsAHttpTransaction::SetConnection ( nsAHttpConnection ) [pure virtual, inherited]

Here is the caller graph for this function:

Definition at line 137 of file nsHttpTransaction.h.

Here is the caller graph for this function:

Definition at line 133 of file nsHttpTransaction.h.

Here is the caller graph for this function:

Definition at line 134 of file nsHttpTransaction.h.

{ return mSSLConnectFailed; }

Here is the caller graph for this function:

virtual nsresult nsAHttpTransaction::Status ( ) [pure virtual, inherited]

Here is the caller graph for this function:

Definition at line 292 of file nsHttpTransaction.cpp.

{
    if (!mHaveAllHeaders) {
        NS_WARNING("response headers not available or incomplete");
        return nsnull;
    }

    nsHttpResponseHead *head = mResponseHead;
    mResponseHead = nsnull;
    return head;
}
NS_METHOD nsHttpTransaction::WritePipeSegment ( nsIOutputStream stream,
void closure,
char *  buf,
PRUint32  offset,
PRUint32  count,
PRUint32 countWritten 
) [static, private]

Definition at line 455 of file nsHttpTransaction.cpp.

{
    nsHttpTransaction *trans = (nsHttpTransaction *) closure;

    if (trans->mTransactionDone)
        return NS_BASE_STREAM_CLOSED; // stop iterating

    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");
    trans->mReceivedData = PR_TRUE;

    // now let the transaction "play" with the buffer.  it is free to modify
    // the contents of the buffer and/or modify countWritten.
    rv = trans->ProcessData(buf, *countWritten, countWritten);
    if (NS_FAILED(rv))
        trans->Close(rv);

    return rv; // failure code only stops WriteSegments; it is not propogated.
}

Here is the call graph for this function:

virtual nsresult nsAHttpTransaction::WriteSegments ( nsAHttpSegmentWriter writer,
PRUint32  count,
PRUint32 countWritten 
) [pure virtual, inherited]

Here is the caller graph for this function:


Member Data Documentation

Definition at line 169 of file nsHttpTransaction.h.

Definition at line 161 of file nsHttpTransaction.h.

Definition at line 195 of file nsHttpTransaction.h.

nsCOMPtr<nsISupports> nsHttpTransaction::mChannel [private]

Definition at line 168 of file nsHttpTransaction.h.

Definition at line 188 of file nsHttpTransaction.h.

Definition at line 198 of file nsHttpTransaction.h.

Definition at line 200 of file nsHttpTransaction.h.

Definition at line 175 of file nsHttpTransaction.h.

Definition at line 176 of file nsHttpTransaction.h.

Definition at line 163 of file nsHttpTransaction.h.

Definition at line 185 of file nsHttpTransaction.h.

Definition at line 186 of file nsHttpTransaction.h.

Definition at line 199 of file nsHttpTransaction.h.

Definition at line 205 of file nsHttpTransaction.h.

Definition at line 210 of file nsHttpTransaction.h.

Definition at line 202 of file nsHttpTransaction.h.

Definition at line 201 of file nsHttpTransaction.h.

Definition at line 183 of file nsHttpTransaction.h.

Definition at line 206 of file nsHttpTransaction.h.

Definition at line 165 of file nsHttpTransaction.h.

Definition at line 166 of file nsHttpTransaction.h.

Definition at line 192 of file nsHttpTransaction.h.

Definition at line 180 of file nsHttpTransaction.h.

Definition at line 208 of file nsHttpTransaction.h.

Definition at line 171 of file nsHttpTransaction.h.

Definition at line 177 of file nsHttpTransaction.h.

Definition at line 173 of file nsHttpTransaction.h.

Definition at line 172 of file nsHttpTransaction.h.

Definition at line 178 of file nsHttpTransaction.h.

Definition at line 204 of file nsHttpTransaction.h.

Definition at line 194 of file nsHttpTransaction.h.

Definition at line 164 of file nsHttpTransaction.h.

Definition at line 207 of file nsHttpTransaction.h.

Definition at line 211 of file nsHttpTransaction.h.

Definition at line 190 of file nsHttpTransaction.h.

Definition at line 209 of file nsHttpTransaction.h.

Definition at line 203 of file nsHttpTransaction.h.

Definition at line 162 of file nsHttpTransaction.h.

Definition at line 181 of file nsHttpTransaction.h.


The documentation for this class was generated from the following files: