Ejemplo n.º 1
0
void
nsHttpPipeline::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
{
    LOG(("nsHttpPipeline::CloseTransaction [this=%p trans=%x reason=%x]\n",
        this, trans, reason));

    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
    MOZ_ASSERT(NS_FAILED(reason), "expecting failure code");

    // the specified transaction is to be closed with the given "reason"

    int32_t index;
    bool killPipeline = false;

    index = mRequestQ.IndexOf(trans);
    if (index >= 0) {
        if (index == 0 && mRequestIsPartial) {
            // the transaction is in the request queue.  check to see if any of
            // its data has been written out yet.
            killPipeline = true;
        }
        mRequestQ.RemoveElementAt(index);
    }
    else {
        index = mResponseQ.IndexOf(trans);
        if (index >= 0)
            mResponseQ.RemoveElementAt(index);
        // while we could avoid killing the pipeline if this transaction is the
        // last transaction in the pipeline, there doesn't seem to be that much
        // value in doing so.  most likely if this transaction is going away,
        // the others will be shortly as well.
        killPipeline = true;
    }

    // Marking this connection as non-reusable prevents other items from being
    // added to it and causes it to be torn down soon.
    DontReuse();

    trans->Close(reason);
    NS_RELEASE(trans);

    if (killPipeline) {
        // reschedule anything from this pipeline onto a different connection
        CancelPipeline(reason);
    }

    // If all the transactions have been removed then we can close the connection
    // right away.
    if (!mRequestQ.Length() && !mResponseQ.Length() && mConnection)
        mConnection->CloseTransaction(this, reason);
}
Ejemplo n.º 2
0
PRUint32
nsHttpPipeline::CancelPipeline(nsresult originalReason)
{
    PRUint32 i, reqLen, respLen, total;
    nsAHttpTransaction *trans;

    reqLen = mRequestQ.Length();
    respLen = mResponseQ.Length();
    total = reqLen + respLen;

    // don't count the first response, if presnet
    if (respLen)
        total--;

    if (!total)
        return 0;

    // any pending requests can ignore this error and be restarted
    // unless it is during a CONNECT tunnel request
    for (i = 0; i < reqLen; ++i) {
        trans = Request(i);
        if (mConnection && mConnection->IsProxyConnectInProgress())
            trans->Close(originalReason);
        else
            trans->Close(NS_ERROR_NET_RESET);
        NS_RELEASE(trans);
    }
    mRequestQ.Clear();

    // any pending responses can be restarted except for the first one,
    // that we might want to finish on this pipeline or cancel individually.
    // Higher levels of callers ensure that we don't process non-idempotent
    // tranasction with the NS_HTTP_ALLOW_PIPELINING bit set
    for (i = 1; i < respLen; ++i) {
        trans = Response(i);
        trans->Close(NS_ERROR_NET_RESET);
        NS_RELEASE(trans);
    }

    if (respLen > 1)
        mResponseQ.TruncateLength(1);

    DontReuse();
    Classify(nsAHttpTransaction::CLASS_SOLO);

    return total;
}