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