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