bug 378637 part 13 - https proxying changes to casting and trans lifecycle r=hurley

--HG--
extra : rebase_source : 9ba1d5a5c97e6fb42956433dd6738cbec0e8e90c
This commit is contained in:
Patrick McManus 2014-05-16 11:46:12 -04:00
parent 173d1dc1d2
commit 0a3b1e638a
10 changed files with 104 additions and 61 deletions

View File

@ -15,7 +15,7 @@
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS(NullHttpTransaction, nsISupportsWeakReference)
NS_IMPL_ISUPPORTS(NullHttpTransaction, NullHttpTransaction, nsISupportsWeakReference)
NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo *ci,
nsIInterfaceRequestor *callbacks,

View File

@ -21,9 +21,14 @@ class nsAHttpConnection;
class nsHttpConnectionInfo;
class nsHttpRequestHead;
// 6c445340-3b82-4345-8efa-4902c3b8805a
#define NS_NULLHTTPTRANSACTION_IID \
{ 0x6c445340, 0x3b82, 0x4345, {0x8e, 0xfa, 0x49, 0x02, 0xc3, 0xb8, 0x80, 0x5a }}
class NullHttpTransaction : public nsAHttpTransaction
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_NULLHTTPTRANSACTION_IID)
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSAHTTPTRANSACTION
@ -57,6 +62,8 @@ private:
bool mIsDone;
};
NS_DEFINE_STATIC_IID_ACCESSOR(NullHttpTransaction, NS_NULLHTTPTRANSACTION_IID)
}} // namespace mozilla::net
#endif // mozilla_net_NullHttpTransaction_h

View File

@ -2538,6 +2538,7 @@ SpdySession3::DispatchOnTunnel(nsAHttpTransaction *aHttpTransaction,
// requeue it. The connection manager is responsible for actually putting
// this on the tunnel connection with the specific ci now that it
// has DontRouteViaWildCard set.
trans->EnableKeepAlive();
gHttpHandler->InitiateTransaction(trans, trans->Priority());
}

View File

@ -483,10 +483,7 @@ SpdyStream3::ParseHttpRequestHeaders(const char *buf,
if (!mTransaction->RequestHead()->IsConnect()) {
CompressToFrame(mTransaction->RequestHead()->RequestURI());
} else {
#ifdef DEBUG
nsRefPtr<SpdyConnectTransaction> qiTrans(do_QueryObject(mTransaction));
MOZ_ASSERT(qiTrans);
#endif
MOZ_ASSERT(mTransaction->QuerySpdyConnectTransaction());
mIsTunnel = true;
// Connect places host:port in :path. Don't use default port.
nsHttpConnectionInfo *ci = mTransaction->ConnectionInfo();
@ -1562,7 +1559,7 @@ SpdyStream3::ClearTransactionsBlockedOnTunnel()
void
SpdyStream3::MapStreamToHttpConnection()
{
nsRefPtr<SpdyConnectTransaction> qiTrans(do_QueryObject(mTransaction));
nsRefPtr<SpdyConnectTransaction> qiTrans(mTransaction->QuerySpdyConnectTransaction());
MOZ_ASSERT(qiTrans);
qiTrans->MapStreamToHttpConnection(mSocketTransport,
mTransaction->ConnectionInfo());

View File

@ -34,16 +34,19 @@ static PRIOMethods *sLayerMethodsPtr = nullptr;
TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped,
const char *aTLSHost,
int32_t aTLSPort)
int32_t aTLSPort,
nsAHttpSegmentReader *aReader,
nsAHttpSegmentWriter *aWriter)
: mTransaction(aWrapped)
, mEncryptedTextUsed(0)
, mEncryptedTextSize(0)
, mSegmentReader(nullptr)
, mSegmentWriter(nullptr)
, mSegmentReader(aReader)
, mSegmentWriter(aWriter)
, mForce(false)
, mNudgeCounter(0)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG(("TLSFilterTransaction ctor %p\n", this));
nsCOMPtr<nsISocketProvider> provider;
nsCOMPtr<nsISocketProviderService> spserv =
@ -91,6 +94,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped,
TLSFilterTransaction::~TLSFilterTransaction()
{
LOG(("TLSFilterTransaction dtor %p\n", this));
Cleanup();
}
@ -334,7 +338,6 @@ TLSFilterTransaction::WriteSegments(nsAHttpSegmentWriter *aWriter,
mSegmentWriter = aWriter;
nsresult rv = mTransaction->WriteSegments(this, aCount, outCountWritten);
mSegmentWriter = nullptr;
LOG(("TLSFilterTransaction %p called trans->WriteSegments rv=%x %d\n",
this, rv, *outCountWritten));
return rv;
@ -352,9 +355,7 @@ TLSFilterTransaction::GetTransactionSecurityInfo(nsISupports **outSecInfo)
}
nsresult
TLSFilterTransaction::NudgeTunnel(NudgeTunnelCallback *aCallback,
nsAHttpSegmentReader *aReader,
nsAHttpSegmentWriter *aWriter)
TLSFilterTransaction::NudgeTunnel(NudgeTunnelCallback *aCallback)
{
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG(("TLSFilterTransaction %p NudgeTunnel\n", this));
@ -364,13 +365,6 @@ TLSFilterTransaction::NudgeTunnel(NudgeTunnelCallback *aCallback,
return NS_ERROR_FAILURE;
}
if (aReader) {
mSegmentReader = aReader;
}
if (aWriter) {
mSegmentWriter = aWriter;
}
uint32_t notUsed;
PR_Write(mFD, "", 0);
OnReadSegment("", 0, &notUsed);
@ -765,7 +759,7 @@ SpdyConnectTransaction::SpdyConnectTransaction(nsHttpConnectionInfo *ci,
nsIInterfaceRequestor *callbacks,
uint32_t caps,
nsAHttpTransaction *trans,
ASpdySession *session)
nsAHttpConnection *session)
: NullHttpTransaction(ci, callbacks, caps | NS_HTTP_ALLOW_KEEPALIVE)
, mConnectStringOffset(0)
, mSession(session)
@ -1006,16 +1000,18 @@ OutputStreamShim::AsyncWait(nsIOutputStreamCallback *callback,
LOG(("OutputStreamShim::AsyncWait %p callback %p\n", this, callback));
mCallback = callback;
nsRefPtr<SpdyConnectTransaction> trans = do_QueryReferent(mWeakTrans);
if (!trans) {
nsRefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
if (!baseTrans) {
return NS_ERROR_FAILURE;
}
nsRefPtr<nsAHttpConnection> spdySession(do_QueryObject(trans->mSession));
if (!spdySession) {
SpdyConnectTransaction *trans = baseTrans->QuerySpdyConnectTransaction();
MOZ_ASSERT(trans);
if (!trans) {
return NS_ERROR_UNEXPECTED;
}
spdySession->TransactionHasDataToWrite(trans);
trans->mSession->TransactionHasDataToWrite(trans);
return NS_OK;
}
@ -1023,17 +1019,17 @@ OutputStreamShim::AsyncWait(nsIOutputStreamCallback *callback,
NS_IMETHODIMP
OutputStreamShim::CloseWithStatus(nsresult reason)
{
nsRefPtr<SpdyConnectTransaction> trans = do_QueryReferent(mWeakTrans);
if (!trans) {
nsRefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
if (!baseTrans) {
return NS_ERROR_FAILURE;
}
nsRefPtr<nsAHttpConnection> spdySession(do_QueryObject(trans->mSession));
if (!spdySession) {
SpdyConnectTransaction *trans = baseTrans->QuerySpdyConnectTransaction();
MOZ_ASSERT(trans);
if (!trans) {
return NS_ERROR_UNEXPECTED;
}
spdySession->CloseTransaction(trans, reason);
trans->mSession->CloseTransaction(trans, reason);
return NS_OK;
}
@ -1046,10 +1042,15 @@ OutputStreamShim::Close()
NS_IMETHODIMP
OutputStreamShim::Flush()
{
nsRefPtr<SpdyConnectTransaction> trans = do_QueryReferent(mWeakTrans);
if (!trans) {
nsRefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
if (!baseTrans) {
return NS_ERROR_FAILURE;
}
SpdyConnectTransaction *trans = baseTrans->QuerySpdyConnectTransaction();
MOZ_ASSERT(trans);
if (!trans) {
return NS_ERROR_UNEXPECTED;
}
uint32_t count = trans->mOutputDataUsed - trans->mOutputDataOffset;
if (!count) {
@ -1072,10 +1073,15 @@ OutputStreamShim::Write(const char * aBuf, uint32_t aCount, uint32_t *_retval)
return mStatus;
}
nsRefPtr<SpdyConnectTransaction> trans = do_QueryReferent(mWeakTrans);
if (!trans) {
nsRefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
if (!baseTrans) {
return NS_ERROR_FAILURE;
}
SpdyConnectTransaction *trans = baseTrans->QuerySpdyConnectTransaction();
MOZ_ASSERT(trans);
if (!trans) {
return NS_ERROR_UNEXPECTED;
}
if ((trans->mOutputDataUsed + aCount) >= 512000) {
*_retval = 0;
@ -1091,11 +1097,7 @@ OutputStreamShim::Write(const char * aBuf, uint32_t aCount, uint32_t *_retval)
*_retval = aCount;
LOG(("OutputStreamShim::Write %p new %d total %d\n", this, aCount, trans->mOutputDataUsed));
nsRefPtr<nsAHttpConnection> spdySession(do_QueryObject(trans->mSession));
if (!spdySession) {
return NS_ERROR_UNEXPECTED;
}
spdySession->TransactionHasDataToWrite(trans);
trans->mSession->TransactionHasDataToWrite(trans);
return NS_OK;
}
@ -1139,17 +1141,17 @@ InputStreamShim::AsyncWait(nsIInputStreamCallback *callback,
NS_IMETHODIMP
InputStreamShim::CloseWithStatus(nsresult reason)
{
nsRefPtr<SpdyConnectTransaction> trans = do_QueryReferent(mWeakTrans);
if (!trans) {
nsRefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
if (!baseTrans) {
return NS_ERROR_FAILURE;
}
nsRefPtr<nsAHttpConnection> spdySession(do_QueryObject(trans->mSession));
if (!spdySession) {
SpdyConnectTransaction *trans = baseTrans->QuerySpdyConnectTransaction();
MOZ_ASSERT(trans);
if (!trans) {
return NS_ERROR_UNEXPECTED;
}
spdySession->CloseTransaction(trans, reason);
trans->mSession->CloseTransaction(trans, reason);
return NS_OK;
}
@ -1162,10 +1164,15 @@ InputStreamShim::Close()
NS_IMETHODIMP
InputStreamShim::Available(uint64_t *_retval)
{
nsRefPtr<SpdyConnectTransaction> trans = do_QueryReferent(mWeakTrans);
if (!trans) {
nsRefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
if (!baseTrans) {
return NS_ERROR_FAILURE;
}
SpdyConnectTransaction *trans = baseTrans->QuerySpdyConnectTransaction();
MOZ_ASSERT(trans);
if (!trans) {
return NS_ERROR_UNEXPECTED;
}
*_retval = trans->mInputDataUsed - trans->mInputDataOffset;
return NS_OK;
@ -1180,10 +1187,15 @@ InputStreamShim::Read(char *aBuf, uint32_t aCount, uint32_t *_retval)
return mStatus;
}
nsRefPtr<SpdyConnectTransaction> trans = do_QueryReferent(mWeakTrans);
if (!trans) {
nsRefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
if (!baseTrans) {
return NS_ERROR_FAILURE;
}
SpdyConnectTransaction *trans = baseTrans->QuerySpdyConnectTransaction();
MOZ_ASSERT(trans);
if (!trans) {
return NS_ERROR_UNEXPECTED;
}
uint32_t avail = trans->mInputDataUsed - trans->mInputDataOffset;
uint32_t tocopy = std::min(aCount, avail);

View File

@ -108,15 +108,15 @@ public:
NS_DECL_NSITIMERCALLBACK
TLSFilterTransaction(nsAHttpTransaction *aWrappedTransaction,
const char *tlsHost, int32_t tlsPort);
const char *tlsHost, int32_t tlsPort,
nsAHttpSegmentReader *reader,
nsAHttpSegmentWriter *writer);
~TLSFilterTransaction();
const nsAHttpTransaction *Transaction() const { return mTransaction.get(); }
nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment);
nsresult GetTransactionSecurityInfo(nsISupports **);
nsresult NudgeTunnel(NudgeTunnelCallback *callback,
nsAHttpSegmentReader *reader,
nsAHttpSegmentWriter *writer);
nsresult NudgeTunnel(NudgeTunnelCallback *callback);
private:
nsresult StartTimerCallback();
@ -169,9 +169,11 @@ public:
nsIInterfaceRequestor *callbacks,
uint32_t caps,
nsAHttpTransaction *trans,
ASpdySession *session);
nsAHttpConnection *session);
~SpdyConnectTransaction();
SpdyConnectTransaction *QuerySpdyConnectTransaction() { return this; }
void MapStreamToHttpConnection(nsISocketTransport *aTransport,
nsHttpConnectionInfo *aConnInfo);
@ -193,7 +195,7 @@ private:
uint32_t mConnectStringOffset;
nsHttpRequestHead *mRequestHead;
ASpdySession *mSession;
nsAHttpConnection *mSession;
nsAHttpSegmentReader *mSegmentReader;
nsAutoArrayPtr<char> mInputData;

View File

@ -21,9 +21,15 @@ class nsHttpConnection;
// Abstract base class for a HTTP connection
//-----------------------------------------------------------------------------
// 5a66aed7-eede-468b-ac2b-e5fb431fcc5c
#define NS_AHTTPCONNECTION_IID \
{ 0x5a66aed7, 0xeede, 0x468b, {0xac, 0x2b, 0xe5, 0xfb, 0x43, 0x1f, 0xcc, 0x5c }}
class nsAHttpConnection : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_AHTTPCONNECTION_IID)
//-------------------------------------------------------------------------
// NOTE: these methods may only be called on the socket thread.
//-------------------------------------------------------------------------
@ -136,6 +142,8 @@ public:
virtual void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpConnection, NS_AHTTPCONNECTION_IID)
#define NS_DECL_NSAHTTPCONNECTION(fwdObject) \
nsresult OnHeadersAvailable(nsAHttpTransaction *, nsHttpRequestHead *, nsHttpResponseHead *, bool *reset); \
void CloseTransaction(nsAHttpTransaction *, nsresult); \

View File

@ -23,6 +23,7 @@ class nsHttpTransaction;
class nsHttpPipeline;
class nsHttpRequestHead;
class nsHttpConnectionInfo;
class SpdyConnectTransaction;
//----------------------------------------------------------------------------
// Abstract base class for a HTTP transaction:
@ -33,9 +34,15 @@ class nsHttpConnectionInfo;
// write function returns NS_BASE_STREAM_WOULD_BLOCK in this case).
//----------------------------------------------------------------------------
// 2af6d634-13e3-494c-8903-c9dce5c22fc0
#define NS_AHTTPTRANSACTION_IID \
{ 0x2af6d634, 0x13e3, 0x494c, {0x89, 0x03, 0xc9, 0xdc, 0xe5, 0xc2, 0x2f, 0xc0 }}
class nsAHttpTransaction : public nsSupportsWeakReference
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_AHTTPTRANSACTION_IID)
// called by the connection when it takes ownership of the transaction.
virtual void SetConnection(nsAHttpConnection *) = 0;
@ -131,6 +138,11 @@ public:
// non nsHttpTransaction implementations of nsAHttpTransaction
virtual nsHttpTransaction *QueryHttpTransaction() { return nullptr; }
// If we used rtti this would be the result of doing
// dynamic_cast<SpdyConnectTransaction *>(this).. i.e. it can be nullptr for
// other types
virtual SpdyConnectTransaction *QuerySpdyConnectTransaction() { return nullptr; }
// return the load group connection information associated with the transaction
virtual nsILoadGroupConnectionInfo *LoadGroupConnectionInfo() { return nullptr; }
@ -176,6 +188,8 @@ public:
}
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTransaction, NS_AHTTPTRANSACTION_IID)
#define NS_DECL_NSAHTTPTRANSACTION \
void SetConnection(nsAHttpConnection *); \
nsAHttpConnection *Connection(); \

View File

@ -1347,7 +1347,7 @@ nsHttpConnection::ForceSend()
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
if (mTLSFilter) {
return mTLSFilter->NudgeTunnel(this, this, this);
return mTLSFilter->NudgeTunnel(this);
}
return NS_DispatchToCurrentThread(new nsHttpConnectionForceIO(this, false));
@ -1537,7 +1537,7 @@ nsHttpConnection::OnSocketWritable()
if (mSocketOutCondition == NS_BASE_STREAM_WOULD_BLOCK) {
if (mTLSFilter) {
LOG((" blocked tunnel (handshake?)\n"));
mTLSFilter->NudgeTunnel(this, this, this);
mTLSFilter->NudgeTunnel(this);
} else {
rv = mSocketOut->AsyncWait(this, 0, 0, nullptr); // continue writing
}
@ -1716,7 +1716,8 @@ nsHttpConnection::SetupSecondaryTLS()
this, mConnInfo->Host(), mConnInfo->Port()));
mTLSFilter = new TLSFilterTransaction(mTransaction,
mConnInfo->Host(),
mConnInfo->Port());
mConnInfo->Port(),
this, this);
if (mTransaction) {
mTransaction = mTLSFilter;
}

View File

@ -109,6 +109,7 @@ public:
// existing tunnel instead of triggering creation of a new one.
void SetDontRouteViaWildCard(bool var) { mDontRouteViaWildCard = var; }
bool DontRouteViaWildCard() { return mDontRouteViaWildCard; }
void EnableKeepAlive() { mCaps |= NS_HTTP_ALLOW_KEEPALIVE; }
// SetPriority() may only be used by the connection manager.
void SetPriority(int32_t priority) { mPriority = priority; }