PendingTransactionInfo.cpp (4859B)
1 /* vim:t ts=4 sw=2 sts=2 et cin: */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 // HttpLog.h should generally be included first 7 #include "HttpLog.h" 8 9 #include "PendingTransactionInfo.h" 10 #include "NullHttpTransaction.h" 11 12 // Log on level :5, instead of default :4. 13 #undef LOG 14 #define LOG(args) LOG5(args) 15 #undef LOG_ENABLED 16 #define LOG_ENABLED() LOG5_ENABLED() 17 18 namespace mozilla { 19 namespace net { 20 21 PendingTransactionInfo::~PendingTransactionInfo() { 22 if (mDnsAndSock) { 23 RefPtr<DnsAndConnectSocket> dnsAndSock = do_QueryReferent(mDnsAndSock); 24 LOG( 25 ("PendingTransactionInfo::PendingTransactionInfo " 26 "[trans=%p halfOpen=%p]", 27 mTransaction.get(), dnsAndSock.get())); 28 if (dnsAndSock) { 29 dnsAndSock->Unclaim(); 30 } 31 mDnsAndSock = nullptr; 32 } else if (mActiveConn) { 33 RefPtr<HttpConnectionBase> activeConn = do_QueryReferent(mActiveConn); 34 if (activeConn && activeConn->Transaction() && 35 activeConn->Transaction()->IsNullTransaction()) { 36 NullHttpTransaction* nullTrans = 37 activeConn->Transaction()->QueryNullTransaction(); 38 nullTrans->Unclaim(); 39 LOG(( 40 "PendingTransactionInfo::PendingTransactionInfo - mark %p unclaimed.", 41 activeConn.get())); 42 } 43 } 44 } 45 46 bool PendingTransactionInfo::IsAlreadyClaimedInitializingConn() { 47 LOG( 48 ("PendingTransactionInfo::IsAlreadyClaimedInitializingConn " 49 "[trans=%p, halfOpen=%p, activeConn=%p]\n", 50 mTransaction.get(), mDnsAndSock.get(), mActiveConn.get())); 51 52 // When this transaction has already established a half-open 53 // connection, we want to prevent any duplicate half-open 54 // connections from being established and bound to this 55 // transaction. Allow only use of an idle persistent connection 56 // (if found) for transactions referred by a half-open connection. 57 bool alreadyDnsAndSockOrWaitingForTLS = false; 58 if (mDnsAndSock) { 59 MOZ_ASSERT(!mActiveConn); 60 RefPtr<DnsAndConnectSocket> dnsAndSock = do_QueryReferent(mDnsAndSock); 61 LOG( 62 ("PendingTransactionInfo::IsAlreadyClaimedInitializingConn " 63 "[trans=%p, dnsAndSock=%p]\n", 64 mTransaction.get(), dnsAndSock.get())); 65 if (dnsAndSock) { 66 alreadyDnsAndSockOrWaitingForTLS = true; 67 } else { 68 // If we have not found the halfOpen socket, remove the pointer. 69 mDnsAndSock = nullptr; 70 } 71 } else if (mActiveConn) { 72 MOZ_ASSERT(!mDnsAndSock); 73 RefPtr<HttpConnectionBase> activeConn = do_QueryReferent(mActiveConn); 74 LOG( 75 ("PendingTransactionInfo::IsAlreadyClaimedInitializingConn " 76 "[trans=%p, activeConn=%p]\n", 77 mTransaction.get(), activeConn.get())); 78 // Check if this transaction claimed a connection that is still 79 // performing tls handshake with a NullHttpTransaction or it is between 80 // finishing tls and reclaiming (When nullTrans finishes tls handshake, 81 // httpConnection does not have a transaction any more and a 82 // ReclaimConnection is dispatched). But if an error occurred the 83 // connection will be closed, it will exist but CanReused will be 84 // false. 85 if (activeConn && 86 ((activeConn->Transaction() && 87 activeConn->Transaction()->IsNullTransaction()) || 88 (!activeConn->Transaction() && activeConn->CanReuse()))) { 89 alreadyDnsAndSockOrWaitingForTLS = true; 90 } else { 91 // If we have not found the connection, remove the pointer. 92 mActiveConn = nullptr; 93 } 94 } 95 96 return alreadyDnsAndSockOrWaitingForTLS; 97 } 98 99 nsWeakPtr PendingTransactionInfo::ForgetDnsAndConnectSocketAndActiveConn() { 100 nsWeakPtr dnsAndSock = mDnsAndSock; 101 102 mDnsAndSock = nullptr; 103 mActiveConn = nullptr; 104 return dnsAndSock; 105 } 106 107 void PendingTransactionInfo::RememberDnsAndConnectSocket( 108 DnsAndConnectSocket* sock) { 109 mDnsAndSock = 110 do_GetWeakReference(static_cast<nsISupportsWeakReference*>(sock)); 111 } 112 113 bool PendingTransactionInfo::TryClaimingActiveConn(HttpConnectionBase* conn) { 114 nsAHttpTransaction* activeTrans = conn->Transaction(); 115 NullHttpTransaction* nullTrans = 116 activeTrans ? activeTrans->QueryNullTransaction() : nullptr; 117 if (nullTrans && nullTrans->Claim()) { 118 mActiveConn = 119 do_GetWeakReference(static_cast<nsISupportsWeakReference*>(conn)); 120 nsCOMPtr<nsITLSSocketControl> tlsSocketControl; 121 conn->GetTLSSocketControl(getter_AddRefs(tlsSocketControl)); 122 if (tlsSocketControl) { 123 (void)tlsSocketControl->Claim(); 124 } 125 return true; 126 } 127 return false; 128 } 129 130 void PendingTransactionInfo::AddDnsAndConnectSocket(DnsAndConnectSocket* sock) { 131 mDnsAndSock = 132 do_GetWeakReference(static_cast<nsISupportsWeakReference*>(sock)); 133 } 134 135 } // namespace net 136 } // namespace mozilla