michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim: set sw=4 ts=8 et tw=80 : */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // HttpLog.h should generally be included first michael@0: #include "HttpLog.h" michael@0: michael@0: // Log on level :5, instead of default :4. michael@0: #undef LOG michael@0: #define LOG(args) LOG5(args) michael@0: #undef LOG_ENABLED michael@0: #define LOG_ENABLED() LOG5_ENABLED() michael@0: michael@0: #include "nsHttpConnectionInfo.h" michael@0: #include "mozilla/net/DNS.h" michael@0: #include "prnetdb.h" michael@0: michael@0: namespace mozilla { michael@0: namespace net { michael@0: michael@0: nsHttpConnectionInfo::nsHttpConnectionInfo(const nsACString &host, int32_t port, michael@0: const nsACString &username, michael@0: nsProxyInfo* proxyInfo, michael@0: bool usingSSL) michael@0: : mUsername(username) michael@0: , mProxyInfo(proxyInfo) michael@0: , mUsingSSL(usingSSL) michael@0: , mUsingConnect(false) michael@0: { michael@0: LOG(("Creating nsHttpConnectionInfo @%x\n", this)); michael@0: michael@0: mUsingHttpProxy = (proxyInfo && proxyInfo->IsHTTP()); michael@0: michael@0: if (mUsingHttpProxy) { michael@0: mUsingConnect = mUsingSSL; // SSL always uses CONNECT michael@0: uint32_t resolveFlags = 0; michael@0: if (NS_SUCCEEDED(mProxyInfo->GetResolveFlags(&resolveFlags)) && michael@0: resolveFlags & nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL) { michael@0: mUsingConnect = true; michael@0: } michael@0: } michael@0: michael@0: SetOriginServer(host, port); michael@0: } michael@0: michael@0: void michael@0: nsHttpConnectionInfo::SetOriginServer(const nsACString &host, int32_t port) michael@0: { michael@0: mHost = host; michael@0: mPort = port == -1 ? DefaultPort() : port; michael@0: michael@0: // michael@0: // build hash key: michael@0: // michael@0: // the hash key uniquely identifies the connection type. two connections michael@0: // are "equal" if they end up talking the same protocol to the same server michael@0: // and are both used for anonymous or non-anonymous connection only; michael@0: // anonymity of the connection is setup later from nsHttpChannel::AsyncOpen michael@0: // where we know we use anonymous connection (LOAD_ANONYMOUS load flag) michael@0: // michael@0: michael@0: const char *keyHost; michael@0: int32_t keyPort; michael@0: michael@0: if (mUsingHttpProxy && !mUsingConnect) { michael@0: keyHost = ProxyHost(); michael@0: keyPort = ProxyPort(); michael@0: } michael@0: else { michael@0: keyHost = Host(); michael@0: keyPort = Port(); michael@0: } michael@0: michael@0: mHashKey.AssignLiteral("...."); michael@0: mHashKey.Append(keyHost); michael@0: mHashKey.Append(':'); michael@0: mHashKey.AppendInt(keyPort); michael@0: if (!mUsername.IsEmpty()) { michael@0: mHashKey.Append('['); michael@0: mHashKey.Append(mUsername); michael@0: mHashKey.Append(']'); michael@0: } michael@0: michael@0: if (mUsingHttpProxy) michael@0: mHashKey.SetCharAt('P', 0); michael@0: if (mUsingSSL) michael@0: mHashKey.SetCharAt('S', 1); michael@0: michael@0: // NOTE: for transparent proxies (e.g., SOCKS) we need to encode the proxy michael@0: // info in the hash key (this ensures that we will continue to speak the michael@0: // right protocol even if our proxy preferences change). michael@0: // michael@0: // NOTE: for SSL tunnels add the proxy information to the cache key. michael@0: // We cannot use the proxy as the host parameter (as we do for non SSL) michael@0: // because this is a single host tunnel, but we need to include the proxy michael@0: // information so that a change in proxy config will mean this connection michael@0: // is not reused michael@0: michael@0: if ((!mUsingHttpProxy && ProxyHost()) || michael@0: (mUsingHttpProxy && mUsingConnect)) { michael@0: mHashKey.AppendLiteral(" ("); michael@0: mHashKey.Append(ProxyType()); michael@0: mHashKey.Append(':'); michael@0: mHashKey.Append(ProxyHost()); michael@0: mHashKey.Append(':'); michael@0: mHashKey.AppendInt(ProxyPort()); michael@0: mHashKey.Append(')'); michael@0: } michael@0: } michael@0: michael@0: nsHttpConnectionInfo* michael@0: nsHttpConnectionInfo::Clone() const michael@0: { michael@0: nsHttpConnectionInfo* clone = new nsHttpConnectionInfo(mHost, mPort, mUsername, mProxyInfo, mUsingSSL); michael@0: michael@0: // Make sure the anonymous and private flags are transferred! michael@0: clone->SetAnonymous(GetAnonymous()); michael@0: clone->SetPrivate(GetPrivate()); michael@0: michael@0: return clone; michael@0: } michael@0: michael@0: bool michael@0: nsHttpConnectionInfo::UsingProxy() michael@0: { michael@0: if (!mProxyInfo) michael@0: return false; michael@0: return !mProxyInfo->IsDirect(); michael@0: } michael@0: michael@0: bool michael@0: nsHttpConnectionInfo::HostIsLocalIPLiteral() const michael@0: { michael@0: PRNetAddr prAddr; michael@0: // If the host/proxy host is not an IP address literal, return false. michael@0: if (ProxyHost()) { michael@0: if (PR_StringToNetAddr(ProxyHost(), &prAddr) != PR_SUCCESS) { michael@0: return false; michael@0: } michael@0: } else if (PR_StringToNetAddr(Host(), &prAddr) != PR_SUCCESS) { michael@0: return false; michael@0: } michael@0: NetAddr netAddr; michael@0: PRNetAddrToNetAddr(&prAddr, &netAddr); michael@0: return IsIPAddrLocal(&netAddr); michael@0: } michael@0: michael@0: } // namespace mozilla::net michael@0: } // namespace mozilla