NullHttpTransaction.cpp (7076B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et tw=80 : */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // HttpLog.h should generally be included first 8 #include "HttpLog.h" 9 10 #include "mozilla/net/NeckoChannelParams.h" // For HttpActivityArgs. 11 #include "mozilla/Components.h" 12 #include "nsHttp.h" 13 #include "NullHttpTransaction.h" 14 #include "nsHttpHandler.h" 15 #include "nsHttpRequestHead.h" 16 #include "nsIHttpActivityObserver.h" 17 #include "nsQueryObject.h" 18 #include "nsNetUtil.h" 19 20 namespace mozilla { 21 namespace net { 22 23 NS_IMPL_ISUPPORTS(NullHttpTransaction, NullHttpTransaction, 24 nsISupportsWeakReference) 25 26 NullHttpTransaction::NullHttpTransaction(nsHttpConnectionInfo* ci, 27 nsIInterfaceRequestor* callbacks, 28 uint32_t caps) 29 : mStatus(NS_OK), 30 mCaps(caps | NS_HTTP_ALLOW_KEEPALIVE), 31 mRequestHead(nullptr), 32 mIsDone(false), 33 mClaimed(false), 34 mCallbacks(callbacks), 35 mConnectionInfo(ci) { 36 nsresult rv; 37 mActivityDistributor = 38 mozilla::components::HttpActivityDistributor::Service(&rv); 39 if (NS_FAILED(rv)) { 40 return; 41 } 42 43 bool activityDistributorActive; 44 rv = mActivityDistributor->GetIsActive(&activityDistributorActive); 45 if (NS_SUCCEEDED(rv) && activityDistributorActive) { 46 // There are some observers registered at activity distributor. 47 LOG( 48 ("NulHttpTransaction::NullHttpTransaction() " 49 "mActivityDistributor is active " 50 "[this=%p, %s]", 51 this, ci->GetOrigin().get())); 52 } else { 53 // There is no observer, so don't use it. 54 mActivityDistributor = nullptr; 55 } 56 } 57 58 NullHttpTransaction::~NullHttpTransaction() { 59 mCallbacks = nullptr; 60 delete mRequestHead; 61 } 62 63 bool NullHttpTransaction::Claim() { 64 if (mClaimed) { 65 return false; 66 } 67 mClaimed = true; 68 return true; 69 } 70 71 void NullHttpTransaction::Unclaim() { mClaimed = false; } 72 73 void NullHttpTransaction::SetConnection(nsAHttpConnection* conn) { 74 mConnection = conn; 75 } 76 77 nsAHttpConnection* NullHttpTransaction::Connection() { 78 return mConnection.get(); 79 } 80 81 void NullHttpTransaction::GetSecurityCallbacks(nsIInterfaceRequestor** outCB) { 82 nsCOMPtr<nsIInterfaceRequestor> copyCB(mCallbacks); 83 *outCB = copyCB.forget().take(); 84 } 85 86 void NullHttpTransaction::OnTransportStatus(nsITransport* transport, 87 nsresult status, int64_t progress) { 88 if (status == NS_NET_STATUS_RESOLVING_HOST) { 89 if (mTimings.domainLookupStart.IsNull()) { 90 mTimings.domainLookupStart = TimeStamp::Now(); 91 } 92 } else if (status == NS_NET_STATUS_RESOLVED_HOST) { 93 if (mTimings.domainLookupEnd.IsNull()) { 94 mTimings.domainLookupEnd = TimeStamp::Now(); 95 } 96 } else if (status == NS_NET_STATUS_CONNECTING_TO) { 97 if (mTimings.connectStart.IsNull()) { 98 mTimings.connectStart = TimeStamp::Now(); 99 } 100 } else if (status == NS_NET_STATUS_CONNECTED_TO) { 101 TimeStamp tnow = TimeStamp::Now(); 102 if (mTimings.connectEnd.IsNull()) { 103 mTimings.connectEnd = tnow; 104 } 105 if (mTimings.tcpConnectEnd.IsNull()) { 106 mTimings.tcpConnectEnd = tnow; 107 } 108 } else if (status == NS_NET_STATUS_TLS_HANDSHAKE_STARTING) { 109 if (mTimings.secureConnectionStart.IsNull()) { 110 mTimings.secureConnectionStart = TimeStamp::Now(); 111 } 112 } else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) { 113 mTimings.connectEnd = TimeStamp::Now(); 114 ; 115 } 116 117 if (mActivityDistributor) { 118 (void)mActivityDistributor->ObserveActivityWithArgs( 119 HttpActivity(mConnectionInfo->GetOrigin(), 120 mConnectionInfo->OriginPort(), 121 mConnectionInfo->EndToEndSSL()), 122 NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT, static_cast<uint32_t>(status), 123 PR_Now(), progress, ""_ns); 124 } 125 } 126 127 bool NullHttpTransaction::IsDone() { return mIsDone; } 128 129 nsresult NullHttpTransaction::Status() { return mStatus; } 130 131 uint32_t NullHttpTransaction::Caps() { return mCaps; } 132 133 nsresult NullHttpTransaction::ReadSegments(nsAHttpSegmentReader* reader, 134 uint32_t count, 135 uint32_t* countRead) { 136 *countRead = 0; 137 mIsDone = true; 138 return NS_BASE_STREAM_CLOSED; 139 } 140 141 nsresult NullHttpTransaction::WriteSegments(nsAHttpSegmentWriter* writer, 142 uint32_t count, 143 uint32_t* countWritten) { 144 *countWritten = 0; 145 return NS_BASE_STREAM_CLOSED; 146 } 147 148 uint32_t NullHttpTransaction::Http1xTransactionCount() { return 0; } 149 150 nsHttpRequestHead* NullHttpTransaction::RequestHead() { 151 // We suport a requesthead at all so that a CONNECT tunnel transaction 152 // can obtain a Host header from it, but we lazy-popualate that header. 153 154 if (!mRequestHead) { 155 mRequestHead = new nsHttpRequestHead(); 156 157 nsAutoCString hostHeader; 158 nsCString host(mConnectionInfo->GetOrigin()); 159 nsresult rv = nsHttpHandler::GenerateHostPort( 160 host, mConnectionInfo->OriginPort(), hostHeader); 161 if (NS_SUCCEEDED(rv)) { 162 rv = mRequestHead->SetHeader(nsHttp::Host, hostHeader); 163 MOZ_ASSERT(NS_SUCCEEDED(rv)); 164 if (mActivityDistributor) { 165 // Report request headers. 166 nsCString reqHeaderBuf; 167 mRequestHead->Flatten(reqHeaderBuf, false); 168 (void)mActivityDistributor->ObserveActivityWithArgs( 169 HttpActivity(mConnectionInfo->GetOrigin(), 170 mConnectionInfo->OriginPort(), 171 mConnectionInfo->EndToEndSSL()), 172 NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, 173 NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_HEADER, PR_Now(), 0, reqHeaderBuf); 174 } 175 } 176 177 // CONNECT tunnels may also want Proxy-Authorization but that is a lot 178 // harder to determine, so for now we will let those connections fail in 179 // the NullHttpTransaction and let them be retried from the pending queue 180 // with a bound transaction 181 } 182 183 return mRequestHead; 184 } 185 186 nsresult NullHttpTransaction::TakeSubTransactions( 187 nsTArray<RefPtr<nsAHttpTransaction> >& outTransactions) { 188 return NS_ERROR_NOT_IMPLEMENTED; 189 } 190 191 void NullHttpTransaction::SetProxyConnectFailed() {} 192 193 void NullHttpTransaction::Close(nsresult reason) { 194 mStatus = reason; 195 mConnection = nullptr; 196 mIsDone = true; 197 if (mActivityDistributor) { 198 // Report that this transaction is closing. 199 (void)mActivityDistributor->ObserveActivityWithArgs( 200 HttpActivity(mConnectionInfo->GetOrigin(), 201 mConnectionInfo->OriginPort(), 202 mConnectionInfo->EndToEndSSL()), 203 NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION, 204 NS_HTTP_ACTIVITY_SUBTYPE_TRANSACTION_CLOSE, PR_Now(), 0, ""_ns); 205 } 206 } 207 208 nsHttpConnectionInfo* NullHttpTransaction::ConnectionInfo() { 209 return mConnectionInfo; 210 } 211 212 } // namespace net 213 } // namespace mozilla