Bug 613977 - Intermittent invalid certificate error prompt in security tests causing timeouts r=honzab a=beta-N

This commit is contained in:
Patrick McManus 2011-01-05 08:37:45 -05:00
Родитель 04c72a8fde
Коммит 0ce3b79531
6 изменённых файлов: 109 добавлений и 50 удалений

Просмотреть файл

@ -1778,9 +1778,20 @@ nsSocketTransport::GetSecurityCallbacks(nsIInterfaceRequestor **callbacks)
NS_IMETHODIMP
nsSocketTransport::SetSecurityCallbacks(nsIInterfaceRequestor *callbacks)
{
nsAutoLock lock(mLock);
mCallbacks = callbacks;
// XXX should we tell PSM about this?
nsCOMPtr<nsISupports> secinfo;
{
nsAutoLock lock(mLock);
mCallbacks = callbacks;
SOCKET_LOG(("Reset callbacks for secinfo=%p callbacks=%p\n", mSecInfo.get(), mCallbacks.get()));
secinfo = mSecInfo;
}
// don't call into PSM while holding mLock!!
nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(secinfo));
if (secCtrl)
secCtrl->SetNotificationCallbacks(callbacks);
return NS_OK;
}

Просмотреть файл

@ -44,6 +44,7 @@ class nsAHttpConnection;
class nsAHttpSegmentReader;
class nsAHttpSegmentWriter;
class nsIInterfaceRequestor;
class nsIEventTarget;
//----------------------------------------------------------------------------
// Abstract base class for a HTTP transaction:
@ -62,7 +63,8 @@ public:
// called by the connection to get security callbacks to set on the
// socket transport.
virtual void GetSecurityCallbacks(nsIInterfaceRequestor **) = 0;
virtual void GetSecurityCallbacks(nsIInterfaceRequestor **,
nsIEventTarget **) = 0;
// called to report socket status (see nsITransportEventSink)
virtual void OnTransportStatus(nsresult status, PRUint64 progress) = 0;
@ -88,7 +90,8 @@ public:
#define NS_DECL_NSAHTTPTRANSACTION \
void SetConnection(nsAHttpConnection *); \
void GetSecurityCallbacks(nsIInterfaceRequestor **); \
void GetSecurityCallbacks(nsIInterfaceRequestor **, \
nsIEventTarget **); \
void OnTransportStatus(nsresult status, PRUint64 progress); \
PRBool IsDone(); \
nsresult Status(); \

Просмотреть файл

@ -51,6 +51,7 @@
#include "netCore.h"
#include "nsNetCID.h"
#include "nsAutoLock.h"
#include "nsProxyRelease.h"
#include "prmem.h"
#ifdef DEBUG
@ -98,19 +99,15 @@ nsHttpConnection::nsHttpConnection()
nsHttpConnection::~nsHttpConnection()
{
LOG(("Destroying nsHttpConnection @%x\n", this));
if (mIdleSynTimer) {
mIdleSynTimer->Cancel();
mIdleSynTimer = nsnull;
}
CancelSynTimer();
if (mBackupConnection) {
gHttpHandler->ReclaimConnection(mBackupConnection);
mBackupConnection = nsnull;
}
ReleaseCallbacks();
NS_IF_RELEASE(mConnInfo);
NS_IF_RELEASE(mTransaction);
if (mLock) {
PR_DestroyLock(mLock);
@ -122,6 +119,25 @@ nsHttpConnection::~nsHttpConnection()
NS_RELEASE(handler);
}
void
nsHttpConnection::ReleaseCallbacks()
{
if (mCallbacks) {
nsIInterfaceRequestor *cbs = nsnull;
mCallbacks.swap(cbs);
NS_ProxyRelease(mCallbackTarget, cbs);
}
}
void
nsHttpConnection::CancelSynTimer()
{
if (mIdleSynTimer) {
mIdleSynTimer->Cancel();
mIdleSynTimer = nsnull;
}
}
nsresult
nsHttpConnection::Init(nsHttpConnectionInfo *info, PRUint16 maxHangTime)
{
@ -159,6 +175,11 @@ nsHttpConnection::IdleSynTimeout(nsITimer *timer, void *closure)
LOG(("SocketTransport hit idle timer - starting backup socket"));
// if we have already cleared ::CloseTransaction, then we do not
// need to create the backup connection
if (!self->mTransaction)
return;
gHttpHandler->ConnMgr()->GetConnection(self->mConnInfo,
self->mSocketCaps,
getter_AddRefs(
@ -172,6 +193,10 @@ nsHttpConnection::IdleSynTimeout(nsITimer *timer, void *closure)
getter_AddRefs(self->mSocketOut2));
if (NS_SUCCEEDED(rv)) {
sCreateTransport2++;
self->mTransaction->
GetSecurityCallbacks(
getter_AddRefs(self->mCallbacks),
getter_AddRefs(self->mCallbackTarget));
self->mSocketOut2->AsyncWait(self, 0, 0, nsnull);
}
}
@ -194,8 +219,8 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, PRUint8 caps)
// take ownership of the transaction
mTransaction = trans;
NS_ADDREF(mTransaction);
mActivationCount++;
ReleaseCallbacks();
// set mKeepAlive according to what will be requested
mKeepAliveMask = mKeepAlive = (caps & NS_HTTP_ALLOW_KEEPALIVE);
@ -219,15 +244,22 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, PRUint8 caps)
// we already have a socket that means the socket was created
// speculatively in the past, not used at that time, and
// given to the connection manager.
if (mActivationCount == 1)
if (mActivationCount == 1) {
sWastedReuseCount++;
rv = mSocketTransport->SetEventSink(this, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
rv = mSocketTransport->SetSecurityCallbacks(this);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mSocketOut->AsyncWait(this, 0, 0, nsnull);
}
failed_activation:
if (NS_FAILED(rv))
NS_RELEASE(mTransaction);
if (NS_FAILED(rv)) {
mTransaction = nsnull;
CancelSynTimer();
}
return rv;
}
@ -486,7 +518,7 @@ nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
// processing a transaction pipeline until after the first HTTP/1.1
// response.
nsHttpTransaction *trans =
static_cast<nsHttpTransaction *>(mTransaction);
static_cast<nsHttpTransaction *>(mTransaction.get());
trans->SetSSLConnectFailed();
}
}
@ -648,10 +680,6 @@ nsHttpConnection::AssignTransport(nsISocketTransport *sock,
nsIAsyncOutputStream *outs,
nsIAsyncInputStream *ins)
{
nsresult rv = sock->SetEventSink(this, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
rv =sock->SetSecurityCallbacks(this);
NS_ENSURE_SUCCESS(rv, rv);
mSocketTransport = sock;
mSocketOut = outs;
mSocketIn = ins;
@ -672,9 +700,7 @@ nsHttpConnection::CloseTransaction(nsAHttpTransaction *trans, nsresult reason)
reason = NS_OK;
mTransaction->Close(reason);
NS_RELEASE(mTransaction);
mTransaction = 0;
mTransaction = nsnull;
if (NS_FAILED(reason))
Close(reason);
@ -885,7 +911,8 @@ nsHttpConnection::SetupSSLProxyConnect()
// NOTE: this cast is valid since this connection cannot be processing a
// transaction pipeline until after the first HTTP/1.1 response.
nsHttpTransaction *trans = static_cast<nsHttpTransaction *>(mTransaction);
nsHttpTransaction *trans =
static_cast<nsHttpTransaction *>(mTransaction.get());
val = trans->RequestHead()->PeekHeader(nsHttp::Host);
if (val) {
@ -930,14 +957,14 @@ nsHttpConnection::ReleaseBackupTransport(nsISocketTransport *sock,
void
nsHttpConnection::SelectPrimaryTransport(nsIAsyncOutputStream *out)
{
LOG(("nsHttpConnection::SelectPrimaryTransport(out=%p), mSocketOut1=%p, mSocketOut2=%p, mSocketOut=%p",
out, mSocketOut1.get(), mSocketOut2.get(), mSocketOut.get()));
if (!mSocketOut) {
// Setup the Main Socket
if (mIdleSynTimer) {
mIdleSynTimer->Cancel();
mIdleSynTimer = nsnull;
}
CancelSynTimer();
if (out == mSocketOut1) {
sSuccessTransport1++;
mSocketTransport.swap(mSocketTransport1);
@ -1030,18 +1057,18 @@ nsHttpConnection::OnOutputStreamReady(nsIAsyncOutputStream *out)
{
NS_ABORT_IF_FALSE(PR_GetCurrentThread() == gSocketThread, "wrong thread");
// if the transaction was dropped...
if (!mTransaction) {
LOG((" no transaction; ignoring event\n"));
return NS_OK;
}
NS_ABORT_IF_FALSE(out == mSocketOut ||
out == mSocketOut1 ||
out == mSocketOut2 , "unexpected socket");
if (out != mSocketOut)
SelectPrimaryTransport(out);
// if the transaction was dropped...
if (!mTransaction) {
LOG((" no transaction; ignoring event\n"));
return NS_OK;
}
if (mSocketOut == out) {
NS_ABORT_IF_FALSE(!mIdleSynTimer,"IdleSynTimer should not be set");
nsresult rv = OnSocketWritable();
@ -1080,13 +1107,12 @@ nsHttpConnection::GetInterface(const nsIID &iid, void **result)
// have to worry about the possibility of mTransaction going away
// part-way through this function call. See CloseTransaction.
NS_ASSERTION(PR_GetCurrentThread() != gSocketThread, "wrong thread");
if (mTransaction) {
nsCOMPtr<nsIInterfaceRequestor> callbacks;
mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks));
if (callbacks)
return callbacks->GetInterface(iid, result);
}
nsCOMPtr<nsIInterfaceRequestor> callbacks = mCallbacks;
if (!callbacks && mTransaction)
mTransaction->GetSecurityCallbacks(getter_AddRefs(callbacks), nsnull);
if (callbacks)
return callbacks->GetInterface(iid, result);
return NS_ERROR_NO_INTERFACE;
}

Просмотреть файл

@ -53,6 +53,7 @@
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
#include "nsIInterfaceRequestor.h"
#include "nsIEventTarget.h"
#include "nsITimer.h"
//-----------------------------------------------------------------------------
@ -154,6 +155,8 @@ private:
void ReleaseBackupTransport(nsISocketTransport *sock,
nsIAsyncOutputStream *outs,
nsIAsyncInputStream *ins);
void CancelSynTimer();
void ReleaseCallbacks();
private:
nsCOMPtr<nsISocketTransport> mSocketTransport;
nsCOMPtr<nsIAsyncInputStream> mSocketIn;
@ -165,7 +168,16 @@ private:
nsCOMPtr<nsIInputStream> mSSLProxyConnectStream;
nsCOMPtr<nsIInputStream> mRequestStream;
nsAHttpTransaction *mTransaction; // hard ref
// mTransaction only points to the HTTP Transaction callbacks if the
// transaction is open, otherwise it is null.
nsRefPtr<nsAHttpTransaction> mTransaction;
// The security callbacks are only stored if we initiate a
// backup connection because they need to be proxy released
// on the main thread.
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIEventTarget> mCallbackTarget;
nsHttpConnectionInfo *mConnInfo; // hard ref
PRLock *mLock;

Просмотреть файл

@ -310,16 +310,20 @@ nsHttpPipeline::SetConnection(nsAHttpConnection *conn)
}
void
nsHttpPipeline::GetSecurityCallbacks(nsIInterfaceRequestor **result)
nsHttpPipeline::GetSecurityCallbacks(nsIInterfaceRequestor **result,
nsIEventTarget **target)
{
NS_ASSERTION(PR_GetCurrentThread() == gSocketThread, "wrong thread");
// return security callbacks from first request
nsAHttpTransaction *trans = Request(0);
if (trans)
trans->GetSecurityCallbacks(result);
else
trans->GetSecurityCallbacks(result, target);
else {
*result = nsnull;
if (target)
*target = nsnull;
}
}
void

Просмотреть файл

@ -328,9 +328,12 @@ nsHttpTransaction::SetConnection(nsAHttpConnection *conn)
}
void
nsHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **cb)
nsHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor **cb,
nsIEventTarget **target)
{
NS_IF_ADDREF(*cb = mCallbacks);
if (target)
NS_IF_ADDREF(*target = mConsumerTarget);
}
void