diff options
Diffstat (limited to 'toolkit/system/windowsproxy')
-rw-r--r-- | toolkit/system/windowsproxy/ProxyUtils.cpp | 182 | ||||
-rw-r--r-- | toolkit/system/windowsproxy/ProxyUtils.h | 21 | ||||
-rw-r--r-- | toolkit/system/windowsproxy/moz.build | 14 | ||||
-rw-r--r-- | toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp | 304 | ||||
-rw-r--r-- | toolkit/system/windowsproxy/tests/gtest/TestProxyBypassRules.cpp | 42 | ||||
-rw-r--r-- | toolkit/system/windowsproxy/tests/gtest/moz.build | 18 |
6 files changed, 581 insertions, 0 deletions
diff --git a/toolkit/system/windowsproxy/ProxyUtils.cpp b/toolkit/system/windowsproxy/ProxyUtils.cpp new file mode 100644 index 000000000..4e59f226a --- /dev/null +++ b/toolkit/system/windowsproxy/ProxyUtils.cpp @@ -0,0 +1,182 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "ProxyUtils.h" +#include "nsTArray.h" +#include "prnetdb.h" +#include "prtypes.h" + +namespace mozilla { +namespace toolkit { +namespace system { + +/** + * Normalize the short IP form into the complete form. + * For example, it converts "192.168" into "192.168.0.0" + */ +static bool +NormalizeAddr(const nsACString& aAddr, nsCString& aNormalized) +{ + nsTArray<nsCString> addr; + if (!ParseString(aAddr, '.', addr)) { + return false; + } + aNormalized = ""; + for (uint32_t i = 0; i < 4; ++i) { + if (i != 0) { + aNormalized.Append("."); + } + if (i < addr.Length()) { + aNormalized.Append(addr[i]); + } else { + aNormalized.Append("0"); + } + } + return true; +} + +static PRUint32 +MaskIPv4Addr(PRUint32 aAddr, uint16_t aMaskLen) +{ + if (aMaskLen == 32) { + return aAddr; + } + return PR_htonl(PR_ntohl(aAddr) & (~0L << (32 - aMaskLen))); +} + +static void +MaskIPv6Addr(PRIPv6Addr& aAddr, uint16_t aMaskLen) +{ + if (aMaskLen == 128) { + return; + } + + if (aMaskLen > 96) { + aAddr.pr_s6_addr32[3] = PR_htonl( + PR_ntohl(aAddr.pr_s6_addr32[3]) & (~0L << (128 - aMaskLen))); + } else if (aMaskLen > 64) { + aAddr.pr_s6_addr32[3] = 0; + aAddr.pr_s6_addr32[2] = PR_htonl( + PR_ntohl(aAddr.pr_s6_addr32[2]) & (~0L << (96 - aMaskLen))); + } else if (aMaskLen > 32) { + aAddr.pr_s6_addr32[3] = 0; + aAddr.pr_s6_addr32[2] = 0; + aAddr.pr_s6_addr32[1] = PR_htonl( + PR_ntohl(aAddr.pr_s6_addr32[1]) & (~0L << (64 - aMaskLen))); + } else { + aAddr.pr_s6_addr32[3] = 0; + aAddr.pr_s6_addr32[2] = 0; + aAddr.pr_s6_addr32[1] = 0; + aAddr.pr_s6_addr32[0] = PR_htonl( + PR_ntohl(aAddr.pr_s6_addr32[0]) & (~0L << (32 - aMaskLen))); + } + + return; +} + +static bool +IsMatchMask(const nsACString& aHost, const nsACString& aOverride) +{ + nsresult rv; + + auto tokenEnd = aOverride.FindChar('/'); + if (tokenEnd == -1) { + return false; + } + + nsAutoCString prefixStr(Substring(aOverride, + tokenEnd + 1, + aOverride.Length() - tokenEnd - 1)); + auto maskLen = prefixStr.ToInteger(&rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return false; + } + + nsAutoCString override(aOverride); + if (!NormalizeAddr(Substring(aOverride, 0, tokenEnd), override)) { + return false; + } + + PRNetAddr prAddrHost; + PRNetAddr prAddrOverride; + if (PR_SUCCESS != PR_StringToNetAddr(PromiseFlatCString(aHost).get(), + &prAddrHost) || + PR_SUCCESS != PR_StringToNetAddr(override.get(), + &prAddrOverride)) { + return false; + } + + if (prAddrHost.raw.family == PR_AF_INET && + prAddrOverride.raw.family == PR_AF_INET) { + return MaskIPv4Addr(prAddrHost.inet.ip, maskLen) == + MaskIPv4Addr(prAddrOverride.inet.ip, maskLen); + } + else if (prAddrHost.raw.family == PR_AF_INET6 && + prAddrOverride.raw.family == PR_AF_INET6) { + MaskIPv6Addr(prAddrHost.ipv6.ip, maskLen); + MaskIPv6Addr(prAddrOverride.ipv6.ip, maskLen); + + return memcmp(&prAddrHost.ipv6.ip, + &prAddrOverride.ipv6.ip, + sizeof(PRIPv6Addr)) == 0; + } + + return false; +} + +static bool +IsMatchWildcard(const nsACString& aHost, const nsACString& aOverride) +{ + nsAutoCString host(aHost); + nsAutoCString override(aOverride); + + int32_t overrideLength = override.Length(); + int32_t tokenStart = 0; + int32_t offset = 0; + bool star = false; + + while (tokenStart < overrideLength) { + int32_t tokenEnd = override.FindChar('*', tokenStart); + if (tokenEnd == tokenStart) { + // Star is the first character in the token. + star = true; + tokenStart++; + // If the character following the '*' is a '.' character then skip + // it so that "*.foo.com" allows "foo.com". + if (override.FindChar('.', tokenStart) == tokenStart) { + nsAutoCString token(Substring(override, + tokenStart + 1, + overrideLength - tokenStart - 1)); + if (host.Equals(token)) { + return true; + } + } + } else { + if (tokenEnd == -1) { + tokenEnd = overrideLength; // no '*' char, match rest of string + } + nsAutoCString token(Substring(override, tokenStart, tokenEnd - tokenStart)); + offset = host.Find(token, offset); + if (offset == -1 || (!star && offset)) { + return false; + } + star = false; + tokenStart = tokenEnd; + offset += token.Length(); + } + } + + return (star || (offset == static_cast<int32_t>(host.Length()))); +} + +bool +IsHostProxyEntry(const nsACString& aHost, const nsACString& aOverride) +{ + return IsMatchMask(aHost, aOverride) || IsMatchWildcard(aHost, aOverride); +} + +} // namespace system +} // namespace toolkit +} // namespace mozilla diff --git a/toolkit/system/windowsproxy/ProxyUtils.h b/toolkit/system/windowsproxy/ProxyUtils.h new file mode 100644 index 000000000..7d6ae220f --- /dev/null +++ b/toolkit/system/windowsproxy/ProxyUtils.h @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef mozilla_toolkit_system_windowsproxy_ProxyUtils_h +#define mozilla_toolkit_system_windowsproxy_ProxyUtils_h + +#include "nsStringGlue.h" + +namespace mozilla { +namespace toolkit { +namespace system { + +bool IsHostProxyEntry(const nsACString& aHost, const nsACString& aOverride); + +} // namespace system +} // namespace toolkit +} // namespace mozilla + +#endif // mozilla_toolkit_system_windowsproxy_ProxyUtils_h diff --git a/toolkit/system/windowsproxy/moz.build b/toolkit/system/windowsproxy/moz.build new file mode 100644 index 000000000..6a1dcc73c --- /dev/null +++ b/toolkit/system/windowsproxy/moz.build @@ -0,0 +1,14 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +TEST_DIRS += ['tests/gtest'] + +SOURCES += [ + 'nsWindowsSystemProxySettings.cpp', + 'ProxyUtils.cpp' +] + +FINAL_LIBRARY = 'xul' diff --git a/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp new file mode 100644 index 000000000..bb5f72b69 --- /dev/null +++ b/toolkit/system/windowsproxy/nsWindowsSystemProxySettings.cpp @@ -0,0 +1,304 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* 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/. */ + +#include <windows.h> +#include <ras.h> +#include <wininet.h> + +#include "mozilla/ArrayUtils.h" +#include "mozilla/Attributes.h" +#include "nsISystemProxySettings.h" +#include "nsIServiceManager.h" +#include "mozilla/ModuleUtils.h" +#include "nsPrintfCString.h" +#include "nsNetCID.h" +#include "nsISupportsPrimitives.h" +#include "nsIURI.h" +#include "GeckoProfiler.h" +#include "prnetdb.h" +#include "ProxyUtils.h" + +class nsWindowsSystemProxySettings final : public nsISystemProxySettings +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSISYSTEMPROXYSETTINGS + + nsWindowsSystemProxySettings() {}; + nsresult Init(); + +private: + ~nsWindowsSystemProxySettings() {}; + + bool MatchOverride(const nsACString& aHost); + bool PatternMatch(const nsACString& aHost, const nsACString& aOverride); +}; + +NS_IMPL_ISUPPORTS(nsWindowsSystemProxySettings, nsISystemProxySettings) + +NS_IMETHODIMP +nsWindowsSystemProxySettings::GetMainThreadOnly(bool *aMainThreadOnly) +{ + *aMainThreadOnly = false; + return NS_OK; +} + + +nsresult +nsWindowsSystemProxySettings::Init() +{ + return NS_OK; +} + +static void SetProxyResult(const char* aType, const nsACString& aHostPort, + nsACString& aResult) +{ + aResult.AssignASCII(aType); + aResult.Append(' '); + aResult.Append(aHostPort); +} + +static void SetProxyResultDirect(nsACString& aResult) +{ + // For whatever reason, a proxy is not to be used. + aResult.AssignASCII("DIRECT"); +} + +static nsresult ReadInternetOption(uint32_t aOption, uint32_t& aFlags, + nsAString& aValue) +{ + DWORD connFlags = 0; + WCHAR connName[RAS_MaxEntryName + 1]; + MOZ_SEH_TRY { + InternetGetConnectedStateExW(&connFlags, connName, + mozilla::ArrayLength(connName), 0); + } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + return NS_ERROR_FAILURE; + } + + INTERNET_PER_CONN_OPTIONW options[2]; + options[0].dwOption = INTERNET_PER_CONN_FLAGS_UI; + options[1].dwOption = aOption; + + INTERNET_PER_CONN_OPTION_LISTW list; + list.dwSize = sizeof(INTERNET_PER_CONN_OPTION_LISTW); + list.pszConnection = connFlags & INTERNET_CONNECTION_MODEM ? + connName : nullptr; + list.dwOptionCount = mozilla::ArrayLength(options); + list.dwOptionError = 0; + list.pOptions = options; + + unsigned long size = sizeof(INTERNET_PER_CONN_OPTION_LISTW); + if (!InternetQueryOptionW(nullptr, INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size)) { + if (GetLastError() != ERROR_INVALID_PARAMETER) { + return NS_ERROR_FAILURE; + } + options[0].dwOption = INTERNET_PER_CONN_FLAGS; + size = sizeof(INTERNET_PER_CONN_OPTION_LISTW); + MOZ_SEH_TRY { + if (!InternetQueryOptionW(nullptr, + INTERNET_OPTION_PER_CONNECTION_OPTION, + &list, &size)) { + return NS_ERROR_FAILURE; + } + } MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { + return NS_ERROR_FAILURE; + } + } + + aFlags = options[0].Value.dwValue; + aValue.Assign(options[1].Value.pszValue); + GlobalFree(options[1].Value.pszValue); + + return NS_OK; +} + +bool +nsWindowsSystemProxySettings::MatchOverride(const nsACString& aHost) +{ + nsresult rv; + uint32_t flags = 0; + nsAutoString buf; + + rv = ReadInternetOption(INTERNET_PER_CONN_PROXY_BYPASS, flags, buf); + if (NS_FAILED(rv)) + return false; + + NS_ConvertUTF16toUTF8 cbuf(buf); + + nsAutoCString host(aHost); + int32_t start = 0; + int32_t end = cbuf.Length(); + + // Windows formats its proxy override list in the form: + // server;server;server where 'server' is a server name pattern or IP + // address, or "<local>". "<local>" must be translated to + // "localhost;127.0.0.1". + // In a server name pattern, a '*' character matches any substring and + // all other characters must match themselves; the whole pattern must match + // the whole hostname. + while (true) { + int32_t delimiter = cbuf.FindCharInSet(" ;", start); + if (delimiter == -1) + delimiter = end; + + if (delimiter != start) { + const nsAutoCString override(Substring(cbuf, start, + delimiter - start)); + if (override.EqualsLiteral("<local>")) { + PRNetAddr addr; + bool isIpAddr = (PR_StringToNetAddr(host.get(), &addr) == PR_SUCCESS); + + // Don't use proxy for local hosts (plain hostname, no dots) + if (!isIpAddr && !host.Contains('.')) { + return true; + } + + if (host.EqualsLiteral("127.0.0.1") || + host.EqualsLiteral("::1")) { + return true; + } + } else if (PatternMatch(host, override)) { + return true; + } + } + + if (delimiter == end) + break; + start = ++delimiter; + } + + return false; +} + +bool +nsWindowsSystemProxySettings::PatternMatch(const nsACString& aHost, + const nsACString& aOverride) +{ + return mozilla::toolkit::system::IsHostProxyEntry(aHost, aOverride); +} + +nsresult +nsWindowsSystemProxySettings::GetPACURI(nsACString& aResult) +{ + PROFILER_LABEL_FUNC(js::ProfileEntry::Category::STORAGE); + nsresult rv; + uint32_t flags = 0; + nsAutoString buf; + + rv = ReadInternetOption(INTERNET_PER_CONN_AUTOCONFIG_URL, flags, buf); + if (!(flags & PROXY_TYPE_AUTO_PROXY_URL)) { + aResult.Truncate(); + return rv; + } + + if (NS_SUCCEEDED(rv)) + aResult = NS_ConvertUTF16toUTF8(buf); + return rv; +} + +nsresult +nsWindowsSystemProxySettings::GetProxyForURI(const nsACString & aSpec, + const nsACString & aScheme, + const nsACString & aHost, + const int32_t aPort, + nsACString & aResult) +{ + nsresult rv; + uint32_t flags = 0; + nsAutoString buf; + + rv = ReadInternetOption(INTERNET_PER_CONN_PROXY_SERVER, flags, buf); + if (NS_FAILED(rv) || !(flags & PROXY_TYPE_PROXY)) { + SetProxyResultDirect(aResult); + return NS_OK; + } + + if (MatchOverride(aHost)) { + SetProxyResultDirect(aResult); + return NS_OK; + } + + NS_ConvertUTF16toUTF8 cbuf(buf); + + nsAutoCString prefix; + ToLowerCase(aScheme, prefix); + + prefix.Append('='); + + nsAutoCString specificProxy; + nsAutoCString defaultProxy; + nsAutoCString socksProxy; + int32_t start = 0; + int32_t end = cbuf.Length(); + + while (true) { + int32_t delimiter = cbuf.FindCharInSet(" ;", start); + if (delimiter == -1) + delimiter = end; + + if (delimiter != start) { + const nsAutoCString proxy(Substring(cbuf, start, + delimiter - start)); + if (proxy.FindChar('=') == -1) { + // If a proxy name is listed by itself, it is used as the + // default proxy for any protocols that do not have a specific + // proxy specified. + // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx) + defaultProxy = proxy; + } else if (proxy.Find(prefix) == 0) { + // To list a proxy for a specific protocol, the string must + // follow the format "<protocol>=<protocol>://<proxy_name>". + // (http://msdn.microsoft.com/en-us/library/aa383996%28VS.85%29.aspx) + specificProxy = Substring(proxy, prefix.Length()); + break; + } else if (proxy.Find("socks=") == 0) { + // SOCKS proxy. + socksProxy = Substring(proxy, 5); // "socks=" length. + } + } + + if (delimiter == end) + break; + start = ++delimiter; + } + + if (!specificProxy.IsEmpty()) + SetProxyResult("PROXY", specificProxy, aResult); // Protocol-specific proxy. + else if (!defaultProxy.IsEmpty()) + SetProxyResult("PROXY", defaultProxy, aResult); // Default proxy. + else if (!socksProxy.IsEmpty()) + SetProxyResult("SOCKS", socksProxy, aResult); // SOCKS proxy. + else + SetProxyResultDirect(aResult); // Direct connection. + + return NS_OK; +} + +#define NS_WINDOWSSYSTEMPROXYSERVICE_CID /* 4e22d3ea-aaa2-436e-ada4-9247de57d367 */\ + { 0x4e22d3ea, 0xaaa2, 0x436e, \ + {0xad, 0xa4, 0x92, 0x47, 0xde, 0x57, 0xd3, 0x67 } } + +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowsSystemProxySettings, Init) +NS_DEFINE_NAMED_CID(NS_WINDOWSSYSTEMPROXYSERVICE_CID); + +static const mozilla::Module::CIDEntry kSysProxyCIDs[] = { + { &kNS_WINDOWSSYSTEMPROXYSERVICE_CID, false, nullptr, nsWindowsSystemProxySettingsConstructor }, + { nullptr } +}; + +static const mozilla::Module::ContractIDEntry kSysProxyContracts[] = { + { NS_SYSTEMPROXYSETTINGS_CONTRACTID, &kNS_WINDOWSSYSTEMPROXYSERVICE_CID }, + { nullptr } +}; + +static const mozilla::Module kSysProxyModule = { + mozilla::Module::kVersion, + kSysProxyCIDs, + kSysProxyContracts +}; + +NSMODULE_DEFN(nsWindowsProxyModule) = &kSysProxyModule; diff --git a/toolkit/system/windowsproxy/tests/gtest/TestProxyBypassRules.cpp b/toolkit/system/windowsproxy/tests/gtest/TestProxyBypassRules.cpp new file mode 100644 index 000000000..9cd6bf981 --- /dev/null +++ b/toolkit/system/windowsproxy/tests/gtest/TestProxyBypassRules.cpp @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 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/. */ + +#include "gtest/gtest.h" +#include "ProxyUtils.h" + +using namespace mozilla::toolkit::system; + +TEST(WindowsProxy, TestProxyBypassRules) +{ + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("mozilla.org"), NS_LITERAL_CSTRING("mozilla.org"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("mozilla.org"),NS_LITERAL_CSTRING("*mozilla.org"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("mozilla.org"), NS_LITERAL_CSTRING("*.mozilla.org"))); + EXPECT_FALSE(IsHostProxyEntry(NS_LITERAL_CSTRING("notmozilla.org"), NS_LITERAL_CSTRING("*.mozilla.org"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("www.mozilla.org"), NS_LITERAL_CSTRING("*mozilla.org"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("www.mozilla.org"), NS_LITERAL_CSTRING("*.mozilla.org"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("www.mozilla.com"), NS_LITERAL_CSTRING("*.mozilla.*"))); +} + +TEST(WindowsProxy, TestProxyBypassRulesIPv4) +{ + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("192.168.1.1"), NS_LITERAL_CSTRING("192.168.1.*"))); + EXPECT_FALSE(IsHostProxyEntry(NS_LITERAL_CSTRING("192.168.1.1"), NS_LITERAL_CSTRING("192.168.2.*"))); + + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("10.1.2.3"), NS_LITERAL_CSTRING("10.0.0.0/8"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("192.168.192.1"), NS_LITERAL_CSTRING("192.168/16"))); + EXPECT_FALSE(IsHostProxyEntry(NS_LITERAL_CSTRING("192.168.192.1"), NS_LITERAL_CSTRING("192.168/17"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("192.168.192.1"), NS_LITERAL_CSTRING("192.168.128/17"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("192.168.1.1"), NS_LITERAL_CSTRING("192.168.1.1/32"))); +} + +TEST(WindowsProxy, TestProxyBypassRulesIPv6) +{ + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("2001:0DB8:ABCD:0012:0123:4567:89AB:CDEF"), NS_LITERAL_CSTRING("2001:db8:abcd:0012::0/64"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("2001:0DB8:ABCD:0012:0000:4567:89AB:CDEF"), NS_LITERAL_CSTRING("2001:db8:abcd:0012::0/80"))); + EXPECT_FALSE(IsHostProxyEntry(NS_LITERAL_CSTRING("2001:0DB8:ABCD:0012:0123:4567:89AB:CDEF"), NS_LITERAL_CSTRING("2001:db8:abcd:0012::0/80"))); + EXPECT_TRUE(IsHostProxyEntry(NS_LITERAL_CSTRING("2001:0DB8:ABCD:0012:0000:0000:89AB:CDEF"), NS_LITERAL_CSTRING("2001:db8:abcd:0012::0/96"))); + EXPECT_FALSE(IsHostProxyEntry(NS_LITERAL_CSTRING("2001:0DB8:ABCD:0012:0123:4567:89AB:CDEF"), NS_LITERAL_CSTRING("2001:db8:abcd:0012::0/96"))); +} diff --git a/toolkit/system/windowsproxy/tests/gtest/moz.build b/toolkit/system/windowsproxy/tests/gtest/moz.build new file mode 100644 index 000000000..3ae4e73c2 --- /dev/null +++ b/toolkit/system/windowsproxy/tests/gtest/moz.build @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +UNIFIED_SOURCES += [ + 'TestProxyBypassRules.cpp', +] + +LOCAL_INCLUDES += [ + '/toolkit/system/windowsproxy', +] + +FINAL_LIBRARY = 'xul-gtest' + +if CONFIG['GNU_CXX']: + CXXFLAGS += ['-Wshadow'] |