Merge inbound to mozilla-central a=merge

This commit is contained in:
arthur.iakab 2018-05-01 00:57:17 +03:00
Родитель 52b7451194 6a2d43d5e7
Коммит a4b709fedc
37 изменённых файлов: 234 добавлений и 1519 удалений

Просмотреть файл

@ -352,7 +352,7 @@ AudioStream::Init(uint32_t aNumChannels,
params.channels = mOutChannels; params.channels = mOutChannels;
params.layout = static_cast<uint32_t>(aChannelMap); params.layout = static_cast<uint32_t>(aChannelMap);
params.format = ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value; params.format = ToCubebFormat<AUDIO_OUTPUT_FORMAT>::value;
params.prefs = CUBEB_STREAM_PREF_NONE; params.prefs = CubebUtils::GetDefaultStreamPrefs();
mAudioClock.Init(aRate); mAudioClock.Init(aRate);

Просмотреть файл

@ -42,6 +42,8 @@
#define PREF_CUBEB_LOGGING_LEVEL "media.cubeb.logging_level" #define PREF_CUBEB_LOGGING_LEVEL "media.cubeb.logging_level"
// Hidden pref used by tests to force failure to obtain cubeb context // Hidden pref used by tests to force failure to obtain cubeb context
#define PREF_CUBEB_FORCE_NULL_CONTEXT "media.cubeb.force_null_context" #define PREF_CUBEB_FORCE_NULL_CONTEXT "media.cubeb.force_null_context"
// Hidden pref to disable BMO 1427011 experiment; can be removed once proven.
#define PREF_CUBEB_DISABLE_DEVICE_SWITCHING "media.cubeb.disable_device_switching"
#define PREF_CUBEB_SANDBOX "media.cubeb.sandbox" #define PREF_CUBEB_SANDBOX "media.cubeb.sandbox"
#define PREF_AUDIOIPC_POOL_SIZE "media.audioipc.pool_size" #define PREF_AUDIOIPC_POOL_SIZE "media.audioipc.pool_size"
#define PREF_AUDIOIPC_STACK_SIZE "media.audioipc.stack_size" #define PREF_AUDIOIPC_STACK_SIZE "media.audioipc.stack_size"
@ -130,6 +132,7 @@ bool sCubebPlaybackLatencyPrefSet = false;
bool sCubebMSGLatencyPrefSet = false; bool sCubebMSGLatencyPrefSet = false;
bool sAudioStreamInitEverSucceeded = false; bool sAudioStreamInitEverSucceeded = false;
bool sCubebForceNullContext = false; bool sCubebForceNullContext = false;
bool sCubebDisableDeviceSwitching = true;
#ifdef MOZ_CUBEB_REMOTING #ifdef MOZ_CUBEB_REMOTING
bool sCubebSandbox = false; bool sCubebSandbox = false;
size_t sAudioIPCPoolSize; size_t sAudioIPCPoolSize;
@ -243,7 +246,12 @@ void PrefChanged(const char* aPref, void* aClosure)
sCubebForceNullContext = Preferences::GetBool(aPref, false); sCubebForceNullContext = Preferences::GetBool(aPref, false);
MOZ_LOG(gCubebLog, LogLevel::Verbose, MOZ_LOG(gCubebLog, LogLevel::Verbose,
("%s: %s", PREF_CUBEB_FORCE_NULL_CONTEXT, sCubebForceNullContext ? "true" : "false")); ("%s: %s", PREF_CUBEB_FORCE_NULL_CONTEXT, sCubebForceNullContext ? "true" : "false"));
} } else if (strcmp(aPref, PREF_CUBEB_DISABLE_DEVICE_SWITCHING) == 0) {
StaticMutexAutoLock lock(sMutex);
sCubebDisableDeviceSwitching = Preferences::GetBool(aPref, true);
MOZ_LOG(gCubebLog, LogLevel::Verbose,
("%s: %s", PREF_CUBEB_DISABLE_DEVICE_SWITCHING, sCubebDisableDeviceSwitching ? "true" : "false"));
}
#ifdef MOZ_CUBEB_REMOTING #ifdef MOZ_CUBEB_REMOTING
else if (strcmp(aPref, PREF_CUBEB_SANDBOX) == 0) { else if (strcmp(aPref, PREF_CUBEB_SANDBOX) == 0) {
StaticMutexAutoLock lock(sMutex); StaticMutexAutoLock lock(sMutex);
@ -694,6 +702,19 @@ void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
} }
} }
cubeb_stream_prefs GetDefaultStreamPrefs()
{
#ifdef XP_WIN
// Investigation for bug 1427011 - if we're in E10S mode, rely on the
// AudioNotification IPC to detect device changes.
if (sCubebDisableDeviceSwitching &&
(XRE_IsE10sParentProcess() || XRE_IsContentProcess())) {
return CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING;
}
#endif
return CUBEB_STREAM_PREF_NONE;
}
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
uint32_t AndroidGetAudioOutputSampleRate() uint32_t AndroidGetAudioOutputSampleRate()
{ {

Просмотреть файл

@ -46,6 +46,7 @@ bool CubebLatencyPrefSet();
void GetCurrentBackend(nsAString& aBackend); void GetCurrentBackend(nsAString& aBackend);
void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos, void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
Side aSide); Side aSide);
cubeb_stream_prefs GetDefaultStreamPrefs();
#ifdef MOZ_WIDGET_ANDROID #ifdef MOZ_WIDGET_ANDROID
uint32_t AndroidGetAudioOutputSampleRate(); uint32_t AndroidGetAudioOutputSampleRate();

Просмотреть файл

@ -627,7 +627,7 @@ AudioCallbackDriver::Init()
output.channels = mOutputChannels; output.channels = mOutputChannels;
output.layout = CUBEB_LAYOUT_UNDEFINED; output.layout = CUBEB_LAYOUT_UNDEFINED;
output.prefs = CUBEB_STREAM_PREF_NONE; output.prefs = CubebUtils::GetDefaultStreamPrefs();
uint32_t latency_frames = CubebUtils::GetCubebMSGLatencyInFrames(&output); uint32_t latency_frames = CubebUtils::GetCubebMSGLatencyInFrames(&output);

Просмотреть файл

@ -15,8 +15,6 @@
inline void inline void
js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind, const AutoLockGC& lock) js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind, const AutoLockGC& lock)
{ {
MOZ_MAKE_MEM_UNDEFINED(this, ArenaSize);
MOZ_ASSERT(firstFreeSpan.isEmpty()); MOZ_ASSERT(firstFreeSpan.isEmpty());
MOZ_ASSERT(!zone); MOZ_ASSERT(!zone);
MOZ_ASSERT(!allocated()); MOZ_ASSERT(!allocated());
@ -24,13 +22,19 @@ js::gc::Arena::init(JS::Zone* zoneArg, AllocKind kind, const AutoLockGC& lock)
MOZ_ASSERT(!markOverflow); MOZ_ASSERT(!markOverflow);
MOZ_ASSERT(!auxNextLink); MOZ_ASSERT(!auxNextLink);
MOZ_MAKE_MEM_UNDEFINED(this, ArenaSize);
zone = zoneArg; zone = zoneArg;
allocKind = size_t(kind); allocKind = size_t(kind);
setAsFullyUnused(); hasDelayedMarking = 0;
markOverflow = 0;
auxNextLink = 0;
if (zone->isAtomsZone()) if (zone->isAtomsZone())
zone->runtimeFromAnyThread()->gc.atomMarking.registerArena(this, lock); zone->runtimeFromAnyThread()->gc.atomMarking.registerArena(this, lock);
else else
bufferedCells() = &ArenaCellSet::Empty; bufferedCells() = &ArenaCellSet::Empty;
setAsFullyUnused();
} }
inline void inline void

Просмотреть файл

@ -539,12 +539,12 @@ GCRuntime::markBufferedGrayRoots(JS::Zone* zone)
if (roots.empty()) if (roots.empty())
return; return;
// Check for and remove canary value. // Check for canary value but don't remove it.
MOZ_RELEASE_ASSERT(roots.length() > 1); MOZ_RELEASE_ASSERT(roots.length() > 1);
MOZ_RELEASE_ASSERT(roots.back() == GrayBufferCanary); MOZ_RELEASE_ASSERT(roots.back() == GrayBufferCanary);
roots.popBack();
for (auto cell : zone->gcGrayRoots()) { for (size_t i = 0; i < roots.length() - 1; i++) {
Cell* cell = roots[i];
MOZ_ASSERT(IsCellPointerValid(cell)); MOZ_ASSERT(IsCellPointerValid(cell));
TraceManuallyBarrieredGenericPointerEdge(&marker, &cell, "buffered gray root"); TraceManuallyBarrieredGenericPointerEdge(&marker, &cell, "buffered gray root");
} }

Просмотреть файл

@ -0,0 +1,4 @@
// |jit-test| error: ReferenceError
gczeal(11, 5);
gczeal(22, 9);
grayRoot().map = wm;

Просмотреть файл

@ -1669,7 +1669,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
if (!script) { if (!script) {
// No error was reported, but no script produced. Assume we hit out of // No error was reported, but no script produced. Assume we hit out of
// memory. // memory.
MOZ_DIAGNOSTIC_ASSERT(false); MOZ_ASSERT(false, "Expected script");
ReportOutOfMemory(cx); ReportOutOfMemory(cx);
return nullptr; return nullptr;
} }
@ -1706,7 +1706,7 @@ GlobalHelperThreadState::finishParseTask(JSContext* cx, ParseTaskKind kind, void
if (scripts.length() != expectedLength) { if (scripts.length() != expectedLength) {
// No error was reported, but fewer scripts produced than expected. // No error was reported, but fewer scripts produced than expected.
// Assume we hit out of memory. // Assume we hit out of memory.
MOZ_DIAGNOSTIC_ASSERT(false); MOZ_ASSERT(false, "Expected more scripts");
ReportOutOfMemory(cx); ReportOutOfMemory(cx);
return false; return false;
} }

Просмотреть файл

@ -0,0 +1,87 @@
diff --git a/media/libcubeb/include/cubeb.h b/media/libcubeb/include/cubeb.h
--- a/media/libcubeb/include/cubeb.h
+++ b/media/libcubeb/include/cubeb.h
@@ -216,20 +216,23 @@ enum {
CHANNEL_FRONT_CENTER | CHANNEL_LOW_FREQUENCY |
CHANNEL_BACK_LEFT | CHANNEL_BACK_RIGHT |
CHANNEL_SIDE_LEFT | CHANNEL_SIDE_RIGHT,
};
/** Miscellaneous stream preferences. */
typedef enum {
CUBEB_STREAM_PREF_NONE = 0x00, /**< No stream preferences are requested. */
- CUBEB_STREAM_PREF_LOOPBACK = 0x01 /**< Request a loopback stream. Should be
- specified on the input params and an
- output device to loopback from should
- be passed in place of an input device. */
+ CUBEB_STREAM_PREF_LOOPBACK = 0x01, /**< Request a loopback stream. Should be
+ specified on the input params and an
+ output device to loopback from should
+ be passed in place of an input device. */
+ CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING = 0x02, /**< Disable switching
+ default device on OS
+ changes. */
} cubeb_stream_prefs;
/** Stream format initialization parameters. */
typedef struct {
cubeb_sample_format format; /**< Requested sample format. One of
#cubeb_sample_format. */
uint32_t rate; /**< Requested sample rate. Valid range is [1000, 192000]. */
uint32_t channels; /**< Requested channel count. Valid range is [1, 8]. */
diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp
--- a/media/libcubeb/src/cubeb_wasapi.cpp
+++ b/media/libcubeb/src/cubeb_wasapi.cpp
@@ -1829,21 +1829,26 @@ wasapi_stream_init(cubeb * context, cube
assert that the lock is held in the function. */
auto_lock lock(stm->stream_reset_lock);
rv = setup_wasapi_stream(stm.get());
}
if (rv != CUBEB_OK) {
return rv;
}
- HRESULT hr = register_notification_client(stm.get());
- if (FAILED(hr)) {
- /* this is not fatal, we can still play audio, but we won't be able
- to keep using the default audio endpoint if it changes. */
- LOG("failed to register notification client, %lx", hr);
+ if (!((input_stream_params ?
+ (input_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0) ||
+ (output_stream_params ?
+ (output_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0))) {
+ HRESULT hr = register_notification_client(stm.get());
+ if (FAILED(hr)) {
+ /* this is not fatal, we can still play audio, but we won't be able
+ to keep using the default audio endpoint if it changes. */
+ LOG("failed to register notification client, %lx", hr);
+ }
}
*stream = stm.release();
LOG("Stream init succesfull (%p)", *stream);
return CUBEB_OK;
}
@@ -1879,17 +1884,19 @@ void wasapi_stream_destroy(cubeb_stream
// Only free stm->emergency_bailout if we could join the thread.
// If we could not join the thread, stm->emergency_bailout is true
// and is still alive until the thread wakes up and exits cleanly.
if (stop_and_join_render_thread(stm)) {
delete stm->emergency_bailout.load();
stm->emergency_bailout = nullptr;
}
- unregister_notification_client(stm);
+ if (stm->notification_client) {
+ unregister_notification_client(stm);
+ }
CloseHandle(stm->reconfigure_event);
CloseHandle(stm->refill_event);
CloseHandle(stm->input_available_event);
// The variables intialized in wasapi_stream_init,
// must be destroyed in wasapi_stream_destroy.
stm->linear_input_buffer.reset();

Просмотреть файл

@ -221,10 +221,13 @@ enum {
/** Miscellaneous stream preferences. */ /** Miscellaneous stream preferences. */
typedef enum { typedef enum {
CUBEB_STREAM_PREF_NONE = 0x00, /**< No stream preferences are requested. */ CUBEB_STREAM_PREF_NONE = 0x00, /**< No stream preferences are requested. */
CUBEB_STREAM_PREF_LOOPBACK = 0x01 /**< Request a loopback stream. Should be CUBEB_STREAM_PREF_LOOPBACK = 0x01, /**< Request a loopback stream. Should be
specified on the input params and an specified on the input params and an
output device to loopback from should output device to loopback from should
be passed in place of an input device. */ be passed in place of an input device. */
CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING = 0x02, /**< Disable switching
default device on OS
changes. */
} cubeb_stream_prefs; } cubeb_stream_prefs;
/** Stream format initialization parameters. */ /** Stream format initialization parameters. */

Просмотреть файл

@ -1834,11 +1834,16 @@ wasapi_stream_init(cubeb * context, cubeb_stream ** stream,
return rv; return rv;
} }
HRESULT hr = register_notification_client(stm.get()); if (!((input_stream_params ?
if (FAILED(hr)) { (input_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0) ||
/* this is not fatal, we can still play audio, but we won't be able (output_stream_params ?
to keep using the default audio endpoint if it changes. */ (output_stream_params->prefs & CUBEB_STREAM_PREF_DISABLE_DEVICE_SWITCHING) : 0))) {
LOG("failed to register notification client, %lx", hr); HRESULT hr = register_notification_client(stm.get());
if (FAILED(hr)) {
/* this is not fatal, we can still play audio, but we won't be able
to keep using the default audio endpoint if it changes. */
LOG("failed to register notification client, %lx", hr);
}
} }
*stream = stm.release(); *stream = stm.release();
@ -1884,7 +1889,9 @@ void wasapi_stream_destroy(cubeb_stream * stm)
stm->emergency_bailout = nullptr; stm->emergency_bailout = nullptr;
} }
unregister_notification_client(stm); if (stm->notification_client) {
unregister_notification_client(stm);
}
CloseHandle(stm->reconfigure_event); CloseHandle(stm->reconfigure_event);
CloseHandle(stm->refill_event); CloseHandle(stm->refill_event);

Просмотреть файл

@ -79,3 +79,7 @@ patch -p3 < disable-assert.patch
echo "Applying prefer-pulse-rust.patch on top of $rev" echo "Applying prefer-pulse-rust.patch on top of $rev"
patch -p3 < prefer-pulse-rust.patch patch -p3 < prefer-pulse-rust.patch
echo "Applying disable-device-switching.patch on top of $rev"
patch -p3 < disable-device-switching.patch

Просмотреть файл

@ -415,13 +415,14 @@ private:
LinkedListElement<T> sentinel; LinkedListElement<T> sentinel;
public: public:
template <typename Type>
class Iterator { class Iterator {
RawType mCurrent; Type mCurrent;
public: public:
explicit Iterator(RawType aCurrent) : mCurrent(aCurrent) {} explicit Iterator(Type aCurrent) : mCurrent(aCurrent) {}
RawType operator *() const { Type operator *() const {
return mCurrent; return mCurrent;
} }
@ -430,7 +431,7 @@ public:
return *this; return *this;
} }
bool operator!=(Iterator& aOther) const { bool operator!=(const Iterator<Type>& aOther) const {
return mCurrent != aOther.mCurrent; return mCurrent != aOther.mCurrent;
} }
}; };
@ -535,11 +536,17 @@ public:
* *
* for (MyElementType* elt : myList) { ... } * for (MyElementType* elt : myList) { ... }
*/ */
Iterator begin() { Iterator<RawType> begin() {
return Iterator(getFirst()); return Iterator<RawType>(getFirst());
} }
Iterator end() { Iterator<ConstRawType> begin() const {
return Iterator(nullptr); return Iterator<ConstRawType>(getFirst());
}
Iterator<RawType> end() {
return Iterator<RawType>(nullptr);
}
Iterator<ConstRawType> end() const {
return Iterator<ConstRawType>(nullptr);
} }
/* /*

Просмотреть файл

@ -115,6 +115,11 @@ TestList()
MOZ_RELEASE_ASSERT(list.getLast() == &three); MOZ_RELEASE_ASSERT(list.getLast() == &three);
MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 3); MOZ_RELEASE_ASSERT(list.getFirst()->mValue == 3);
MOZ_RELEASE_ASSERT(list.getLast()->mValue == 4); MOZ_RELEASE_ASSERT(list.getLast()->mValue == 4);
const LinkedList<SomeClass>& constList = list;
for (const SomeClass* x : constList) {
MOZ_RELEASE_ASSERT(x);
}
} }
static void static void

Просмотреть файл

@ -2171,7 +2171,6 @@ pref("network.cookie.lifetimePolicy", 0); // 0-accept, 1-dontUse 2-acceptF
pref("network.cookie.prefsMigrated", false); pref("network.cookie.prefsMigrated", false);
pref("network.cookie.lifetime.days", 90); // Ignored unless network.cookie.lifetimePolicy is 3. pref("network.cookie.lifetime.days", 90); // Ignored unless network.cookie.lifetimePolicy is 3.
pref("network.proxy.enable_wpad_over_dhcp", true);
// The PAC file to load. Ignored unless network.proxy.type is 2. // The PAC file to load. Ignored unless network.proxy.type is 2.
pref("network.proxy.autoconfig_url", ""); pref("network.proxy.autoconfig_url", "");
// Strip off paths when sending URLs to PAC scripts // Strip off paths when sending URLs to PAC scripts

Просмотреть файл

@ -38,7 +38,6 @@ XPIDL_SOURCES += [
'nsIDashboard.idl', 'nsIDashboard.idl',
'nsIDashboardEventNotifier.idl', 'nsIDashboardEventNotifier.idl',
'nsIDeprecationWarner.idl', 'nsIDeprecationWarner.idl',
'nsIDHCPClient.idl',
'nsIDivertableChannel.idl', 'nsIDivertableChannel.idl',
'nsIDownloader.idl', 'nsIDownloader.idl',
'nsIEncodedChannel.idl', 'nsIEncodedChannel.idl',

Просмотреть файл

@ -1,19 +0,0 @@
/* -*- Mode: IDL; 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 "nsISupports.idl"
/**
* This interface allows the proxy code to access the DHCP Options in a platform-specific way
*/
[scriptable, uuid(aee75dc0-be1a-46b9-9e0c-31a6899c175c)]
interface nsIDHCPClient : nsISupports
{
/**
* returns the DHCP Option designated by the option parameter
*/
ACString getOption(in uint8_t option);
};

Просмотреть файл

@ -5,20 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsPACMan.h" #include "nsPACMan.h"
#include "nsThreadUtils.h"
#include "mozilla/Preferences.h"
#include "nsContentUtils.h"
#include "nsIAsyncVerifyRedirectCallback.h"
#include "nsIAuthPrompt.h" #include "nsIAuthPrompt.h"
#include "nsIDHCPClient.h" #include "nsIPromptFactory.h"
#include "nsIHttpChannel.h" #include "nsIHttpChannel.h"
#include "nsIPrefService.h" #include "nsIPrefService.h"
#include "nsIPrefBranch.h" #include "nsIPrefBranch.h"
#include "nsIPromptFactory.h"
#include "nsIProtocolProxyService.h"
#include "nsISystemProxySettings.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsThreadUtils.h" #include "nsIAsyncVerifyRedirectCallback.h"
#include "nsISystemProxySettings.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -29,8 +26,6 @@ LazyLogModule gProxyLog("proxy");
#undef LOG #undef LOG
#define LOG(args) MOZ_LOG(gProxyLog, LogLevel::Debug, args) #define LOG(args) MOZ_LOG(gProxyLog, LogLevel::Debug, args)
#define MOZ_WPAD_URL "http://wpad/wpad.dat"
#define MOZ_DHCP_WPAD_OPTION 252
// The PAC thread does evaluations of both PAC files and // The PAC thread does evaluations of both PAC files and
// nsISystemProxySettings because they can both block the calling thread and we // nsISystemProxySettings because they can both block the calling thread and we
@ -80,26 +75,6 @@ GetExtraJSContextHeapSize()
return extraSize < 0 ? 0 : extraSize; return extraSize < 0 ? 0 : extraSize;
} }
// Read network proxy type from preference
// Used to verify that the preference is WPAD in nsPACMan::ConfigureWPAD
nsresult
GetNetworkProxyTypeFromPref(int32_t* type)
{
*type = 0;
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs) {
LOG(("Failed to get a preference service object"));
return NS_ERROR_FACTORY_NOT_REGISTERED;
}
nsresult rv = prefs->GetIntPref("network.proxy.type", type);
if (!NS_SUCCEEDED(rv)) {
LOG(("Failed to retrieve network.proxy.type from prefs"));
return rv;
}
LOG(("network.proxy.type pref retrieved: %d\n", *type));
return NS_OK;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -117,12 +92,12 @@ public:
{ {
} }
void SetPACString(const nsACString &pacString) void SetPACString(const nsCString &pacString)
{ {
mPACString = pacString; mPACString = pacString;
} }
void SetPACURL(const nsACString &pacURL) void SetPACURL(const nsCString &pacURL)
{ {
mPACURL = pacURL; mPACURL = pacURL;
} }
@ -216,43 +191,14 @@ public:
} }
private: private:
RefPtr<nsPACMan> mPACMan; RefPtr<nsPACMan> mPACMan;
};
//-----------------------------------------------------------------------------
// ConfigureWPADComplete allows the PAC thread to tell the main thread that
// the URL for the PAC file has been found
class ConfigureWPADComplete final : public Runnable
{
public:
ConfigureWPADComplete(nsPACMan *aPACMan, const nsACString &aPACURISpec)
: Runnable("net::ConfigureWPADComplete"),
mPACMan(aPACMan),
mPACURISpec(aPACURISpec)
{
}
NS_IMETHOD Run() override
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
mPACMan->AssignPACURISpec(mPACURISpec);
mPACMan->ContinueLoadingAfterPACUriKnown();
return NS_OK;
}
private:
RefPtr<nsPACMan> mPACMan;
nsCString mPACURISpec;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// ExecutePACThreadAction is used to proxy actions from the main // ExecutePACThreadAction is used to proxy actions from the main
// thread onto the PAC thread. There are 4 options: process the queue, // thread onto the PAC thread. There are 3 options: process the queue,
// cancel the queue, query DHCP for the PAC option // cancel the queue, and setup the javascript context with a new PAC file
// and setup the javascript context with a new PAC file
class ExecutePACThreadAction final : public Runnable class ExecutePACThreadAction final : public Runnable
{ {
@ -265,7 +211,6 @@ public:
, mCancelStatus(NS_OK) , mCancelStatus(NS_OK)
, mSetupPAC(false) , mSetupPAC(false)
, mExtraHeapSize(0) , mExtraHeapSize(0)
, mConfigureWPAD(false)
{ } { }
void CancelQueue (nsresult status) void CancelQueue (nsresult status)
@ -276,7 +221,7 @@ public:
void SetupPAC (const char *text, void SetupPAC (const char *text,
uint32_t datalen, uint32_t datalen,
const nsACString &pacURI, nsCString &pacURI,
uint32_t extraHeapSize) uint32_t extraHeapSize)
{ {
mSetupPAC = true; mSetupPAC = true;
@ -285,11 +230,6 @@ public:
mExtraHeapSize = extraHeapSize; mExtraHeapSize = extraHeapSize;
} }
void ConfigureWPAD()
{
mConfigureWPAD = true;
}
NS_IMETHOD Run() override NS_IMETHOD Run() override
{ {
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread"); MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
@ -314,15 +254,6 @@ public:
return NS_OK; return NS_OK;
} }
if (mConfigureWPAD) {
nsAutoCString spec;
mConfigureWPAD = false;
mPACMan->ConfigureWPAD(spec);
RefPtr<ConfigureWPADComplete> runnable = new ConfigureWPADComplete(mPACMan, spec);
NS_DispatchToMainThread(runnable);
return NS_OK;
}
mPACMan->ProcessPendingQ(); mPACMan->ProcessPendingQ();
return NS_OK; return NS_OK;
} }
@ -335,9 +266,8 @@ private:
bool mSetupPAC; bool mSetupPAC;
uint32_t mExtraHeapSize; uint32_t mExtraHeapSize;
nsCString mSetupPACData; nsCString mSetupPACData;
nsCString mSetupPACURI; nsCString mSetupPACURI;
bool mConfigureWPAD;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -358,7 +288,7 @@ PendingPACQuery::PendingPACQuery(nsPACMan* pacMan,
} }
void void
PendingPACQuery::Complete(nsresult status, const nsACString &pacString) PendingPACQuery::Complete(nsresult status, const nsCString &pacString)
{ {
if (!mCallback) if (!mCallback)
return; return;
@ -371,7 +301,7 @@ PendingPACQuery::Complete(nsresult status, const nsACString &pacString)
} }
void void
PendingPACQuery::UseAlternatePACFile(const nsACString &pacURL) PendingPACQuery::UseAlternatePACFile(const nsCString &pacURL)
{ {
if (!mCallback) if (!mCallback)
return; return;
@ -406,9 +336,6 @@ nsPACMan::nsPACMan(nsIEventTarget *mainThreadEventTarget)
, mShutdown(false) , mShutdown(false)
, mLoadFailureCount(0) , mLoadFailureCount(0)
, mInProgress(false) , mInProgress(false)
, mAutoDetect(false)
, mWPADOverDHCPEnabled(false)
, mProxyConfigType(0)
{ {
MOZ_ASSERT(NS_IsMainThread(), "pacman must be created on main thread"); MOZ_ASSERT(NS_IsMainThread(), "pacman must be created on main thread");
if (!sThreadLocalSetup){ if (!sThreadLocalSetup){
@ -468,7 +395,7 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri,
TimeStamp::Now() > mScheduledReload) { TimeStamp::Now() > mScheduledReload) {
LOG(("nsPACMan::AsyncGetProxyForURI reload as scheduled\n")); LOG(("nsPACMan::AsyncGetProxyForURI reload as scheduled\n"));
LoadPACFromURI(EmptyCString(), true); LoadPACFromURI(EmptyCString());
} }
RefPtr<PendingPACQuery> query = RefPtr<PendingPACQuery> query =
@ -501,15 +428,16 @@ nsPACMan::PostQuery(PendingPACQuery *query)
} }
nsresult nsresult
nsPACMan::LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload) nsPACMan::LoadPACFromURI(const nsCString &spec)
{ {
NS_ENSURE_STATE(!mShutdown); NS_ENSURE_STATE(!mShutdown);
NS_ENSURE_ARG(!spec.IsEmpty() || !mPACURISpec.IsEmpty());
nsCOMPtr<nsIStreamLoader> loader = nsCOMPtr<nsIStreamLoader> loader =
do_CreateInstance(NS_STREAMLOADER_CONTRACTID); do_CreateInstance(NS_STREAMLOADER_CONTRACTID);
NS_ENSURE_STATE(loader); NS_ENSURE_STATE(loader);
LOG(("nsPACMan::LoadPACFromURI aSpec: %s, aIsScheduledReload:%s\n", aSpec.BeginReading(), aIsScheduledReload? "true" : "false")); LOG(("nsPACMan::LoadPACFromURI %s\n", spec.get()));
// Since we might get called from nsProtocolProxyService::Init, we need to // Since we might get called from nsProtocolProxyService::Init, we need to
// post an event back to the main thread before we try to use the IO service. // post an event back to the main thread before we try to use the IO service.
// //
@ -530,12 +458,11 @@ nsPACMan::LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload)
CancelExistingLoad(); CancelExistingLoad();
mLoader = loader; mLoader = loader;
if (!aIsScheduledReload) { if (!spec.IsEmpty()) {
mPACURISpec = spec;
mPACURIRedirectSpec.Truncate(); mPACURIRedirectSpec.Truncate();
mNormalPACURISpec.Truncate(); // set at load time mNormalPACURISpec.Truncate(); // set at load time
mLoadFailureCount = 0; // reset mLoadFailureCount = 0; // reset
mAutoDetect = aSpec.IsEmpty();
mPACURISpec.Assign(aSpec);
} }
// reset to Null // reset to Null
@ -543,56 +470,6 @@ nsPACMan::LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload)
return NS_OK; return NS_OK;
} }
nsresult
nsPACMan::GetPACFromDHCP(nsACString &aSpec)
{
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
if (!mDHCPClient) {
LOG(("nsPACMan::GetPACFromDHCP DHCP option %d query failed because there is no DHCP client available\n", MOZ_DHCP_WPAD_OPTION));
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult rv;
rv = mDHCPClient->GetOption(MOZ_DHCP_WPAD_OPTION, aSpec);
if (NS_FAILED(rv)) {
LOG(("nsPACMan::GetPACFromDHCP DHCP option %d query failed with result %d\n", MOZ_DHCP_WPAD_OPTION, (uint32_t)rv));
} else {
LOG(("nsPACMan::GetPACFromDHCP DHCP option %d query succeeded, finding PAC URL %s\n", MOZ_DHCP_WPAD_OPTION, aSpec.BeginReading()));
}
return rv;
}
nsresult
nsPACMan::ConfigureWPAD(nsACString &aSpec)
{
MOZ_ASSERT(!NS_IsMainThread(), "wrong thread");
MOZ_RELEASE_ASSERT(mProxyConfigType == nsIProtocolProxyService::PROXYCONFIG_WPAD,
"WPAD is being executed when not selected by user");
aSpec.Truncate();
if (mWPADOverDHCPEnabled) {
GetPACFromDHCP(aSpec);
}
if (aSpec.IsEmpty()) {
// We diverge from the WPAD spec here in that we don't walk the
// hosts's FQDN, stripping components until we hit a TLD. Doing so
// is dangerous in the face of an incomplete list of TLDs, and TLDs
// get added over time. We could consider doing only a single
// substitution of the first component, if that proves to help
// compatibility.
aSpec.AssignLiteral(MOZ_WPAD_URL);
}
return NS_OK;
}
void
nsPACMan::AssignPACURISpec(const nsACString &aSpec)
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
mPACURISpec.Assign(aSpec);
}
void void
nsPACMan::StartLoading() nsPACMan::StartLoading()
{ {
@ -605,29 +482,6 @@ nsPACMan::StartLoading()
return; return;
} }
if (mAutoDetect) {
GetNetworkProxyTypeFromPref(&mProxyConfigType);
RefPtr<ExecutePACThreadAction> wpadConfigurer =
new ExecutePACThreadAction(this);
wpadConfigurer->ConfigureWPAD();
if (mPACThread) {
mPACThread->Dispatch(wpadConfigurer, nsIEventTarget::DISPATCH_NORMAL);
}
} else {
ContinueLoadingAfterPACUriKnown();
}
}
void
nsPACMan::ContinueLoadingAfterPACUriKnown()
{
MOZ_ASSERT(NS_IsMainThread(), "wrong thread");
// CancelExistingLoad was called...
if (!mLoader) {
PostCancelPendingQ(NS_ERROR_ABORT);
return;
}
if (NS_SUCCEEDED(mLoader->Init(this, nullptr))) { if (NS_SUCCEEDED(mLoader->Init(this, nullptr))) {
// Always hit the origin server when loading PAC. // Always hit the origin server when loading PAC.
nsCOMPtr<nsIIOService> ios = do_GetIOService(); nsCOMPtr<nsIIOService> ios = do_GetIOService();
@ -945,8 +799,6 @@ nsresult
nsPACMan::Init(nsISystemProxySettings *systemProxySettings) nsPACMan::Init(nsISystemProxySettings *systemProxySettings)
{ {
mSystemProxySettings = systemProxySettings; mSystemProxySettings = systemProxySettings;
mDHCPClient = do_GetService(NS_DHCPCLIENT_CONTRACTID);
nsresult rv = nsresult rv =
NS_NewNamedThread("ProxyResolution", getter_AddRefs(mPACThread)); NS_NewNamedThread("ProxyResolution", getter_AddRefs(mPACThread));

Просмотреть файл

@ -7,24 +7,23 @@
#ifndef nsPACMan_h__ #ifndef nsPACMan_h__
#define nsPACMan_h__ #define nsPACMan_h__
#include "mozilla/Atomics.h"
#include "mozilla/Attributes.h"
#include "mozilla/LinkedList.h"
#include "mozilla/Logging.h"
#include "mozilla/net/NeckoTargetHolder.h"
#include "mozilla/TimeStamp.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsIChannelEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIStreamLoader.h" #include "nsIStreamLoader.h"
#include "nsIInterfaceRequestor.h"
#include "nsIChannelEventSink.h"
#include "ProxyAutoConfig.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsCOMPtr.h"
#include "nsString.h" #include "nsString.h"
#include "ProxyAutoConfig.h" #include "mozilla/Attributes.h"
#include "mozilla/LinkedList.h"
#include "nsAutoPtr.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Logging.h"
#include "mozilla/Atomics.h"
#include "mozilla/net/NeckoTargetHolder.h"
class nsISystemProxySettings; class nsISystemProxySettings;
class nsIDHCPClient;
class nsIThread; class nsIThread;
namespace mozilla { namespace mozilla {
@ -53,8 +52,8 @@ public:
* newPACURL should be 0 length. * newPACURL should be 0 length.
*/ */
virtual void OnQueryComplete(nsresult status, virtual void OnQueryComplete(nsresult status,
const nsACString &pacString, const nsCString &pacString,
const nsACString &newPACURL) = 0; const nsCString &newPACURL) = 0;
}; };
class PendingPACQuery final : public Runnable, class PendingPACQuery final : public Runnable,
@ -66,8 +65,8 @@ public:
bool mainThreadResponse); bool mainThreadResponse);
// can be called from either thread // can be called from either thread
void Complete(nsresult status, const nsACString &pacString); void Complete(nsresult status, const nsCString &pacString);
void UseAlternatePACFile(const nsACString &pacURL); void UseAlternatePACFile(const nsCString &pacURL);
nsCString mSpec; nsCString mSpec;
nsCString mScheme; nsCString mScheme;
@ -132,7 +131,7 @@ public:
* The non normalized uri spec of this URI used for comparison with * The non normalized uri spec of this URI used for comparison with
* system proxy settings to determine if the PAC uri has changed. * system proxy settings to determine if the PAC uri has changed.
*/ */
nsresult LoadPACFromURI(const nsACString &aSpec, bool aIsScheduledReload = false); nsresult LoadPACFromURI(const nsCString &pacSpec);
/** /**
* Returns true if we are currently loading the PAC file. * Returns true if we are currently loading the PAC file.
@ -167,10 +166,6 @@ public:
return IsPACURI(tmp); return IsPACURI(tmp);
} }
bool IsUsingWPAD() {
return mAutoDetect;
}
nsresult Init(nsISystemProxySettings *); nsresult Init(nsISystemProxySettings *);
static nsPACMan *sInstance; static nsPACMan *sInstance;
@ -178,8 +173,6 @@ public:
void ProcessPendingQ(); void ProcessPendingQ();
void CancelPendingQ(nsresult); void CancelPendingQ(nsresult);
void SetWPADOverDHCPEnabled(bool aValue) { mWPADOverDHCPEnabled = aValue; }
private: private:
NS_DECL_NSISTREAMLOADEROBSERVER NS_DECL_NSISTREAMLOADEROBSERVER
NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSIINTERFACEREQUESTOR
@ -187,10 +180,8 @@ private:
friend class PendingPACQuery; friend class PendingPACQuery;
friend class PACLoadComplete; friend class PACLoadComplete;
friend class ConfigureWPADComplete;
friend class ExecutePACThreadAction; friend class ExecutePACThreadAction;
friend class WaitForThreadShutdown; friend class WaitForThreadShutdown;
friend class TestPACMan;
~nsPACMan(); ~nsPACMan();
@ -204,11 +195,6 @@ private:
*/ */
void StartLoading(); void StartLoading();
/**
* Continue loading the PAC file.
*/
void ContinueLoadingAfterPACUriKnown();
/** /**
* Reload the PAC file if there is reason to. * Reload the PAC file if there is reason to.
*/ */
@ -226,22 +212,15 @@ private:
*/ */
nsresult PostQuery(PendingPACQuery *query); nsresult PostQuery(PendingPACQuery *query);
// Having found the PAC URI on the PAC thread, copy it to a string which
// can be altered on the main thread.
void AssignPACURISpec(const nsACString &aSpec);
// PAC thread operations only // PAC thread operations only
void PostProcessPendingQ(); void PostProcessPendingQ();
void PostCancelPendingQ(nsresult); void PostCancelPendingQ(nsresult);
bool ProcessPending(); bool ProcessPending();
nsresult GetPACFromDHCP(nsACString &aSpec);
nsresult ConfigureWPAD(nsACString &aSpec);
private: private:
ProxyAutoConfig mPAC; ProxyAutoConfig mPAC;
nsCOMPtr<nsIThread> mPACThread; nsCOMPtr<nsIThread> mPACThread;
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings; nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
nsCOMPtr<nsIDHCPClient> mDHCPClient;
LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */ LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
@ -260,9 +239,6 @@ private:
bool mInProgress; bool mInProgress;
bool mIncludePath; bool mIncludePath;
bool mAutoDetect;
bool mWPADOverDHCPEnabled;
int32_t mProxyConfigType;
}; };
extern LazyLogModule gProxyLog; extern LazyLogModule gProxyLog;

Просмотреть файл

@ -62,6 +62,7 @@ namespace net {
#define PROXY_PREF_BRANCH "network.proxy" #define PROXY_PREF_BRANCH "network.proxy"
#define PROXY_PREF(x) PROXY_PREF_BRANCH "." x #define PROXY_PREF(x) PROXY_PREF_BRANCH "." x
#define WPAD_URL "http://wpad/wpad.dat"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -310,8 +311,8 @@ private:
// Called asynchronously, so we do not need to post another PLEvent // Called asynchronously, so we do not need to post another PLEvent
// before calling DoCallback. // before calling DoCallback.
void OnQueryComplete(nsresult status, void OnQueryComplete(nsresult status,
const nsACString &pacString, const nsCString &pacString,
const nsACString &newPACURL) override const nsCString &newPACURL) override
{ {
// If we've already called DoCallback then, nothing more to do. // If we've already called DoCallback then, nothing more to do.
if (!mCallback) if (!mCallback)
@ -820,7 +821,6 @@ nsProtocolProxyService::nsProtocolProxyService()
, mSOCKSProxyVersion(4) , mSOCKSProxyVersion(4)
, mSOCKSProxyRemoteDNS(false) , mSOCKSProxyRemoteDNS(false)
, mProxyOverTLS(true) , mProxyOverTLS(true)
, mWPADOverDHCPEnabled(false)
, mPACMan(nullptr) , mPACMan(nullptr)
, mSessionStart(PR_Now()) , mSessionStart(PR_Now())
, mFailedProxyTimeout(30 * 60) // 30 minute default , mFailedProxyTimeout(30 * 60) // 30 minute default
@ -1087,12 +1087,6 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
mProxyOverTLS); mProxyOverTLS);
} }
if (!pref || !strcmp(pref, PROXY_PREF("enable_wpad_over_dhcp"))) {
proxy_GetBoolPref(prefBranch, PROXY_PREF("enable_wpad_over_dhcp"),
mWPADOverDHCPEnabled);
reloadPAC = true;
}
if (!pref || !strcmp(pref, PROXY_PREF("failover_timeout"))) if (!pref || !strcmp(pref, PROXY_PREF("failover_timeout")))
proxy_GetIntPref(prefBranch, PROXY_PREF("failover_timeout"), proxy_GetIntPref(prefBranch, PROXY_PREF("failover_timeout"),
mFailedProxyTimeout); mFailedProxyTimeout);
@ -1125,15 +1119,19 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
ResetPACThread(); ResetPACThread();
} }
} else if (mProxyConfig == PROXYCONFIG_WPAD) { } else if (mProxyConfig == PROXYCONFIG_WPAD) {
LOG(("Auto-detecting proxy - Reset Pac Thread")); // We diverge from the WPAD spec here in that we don't walk the
ResetPACThread(); // hosts's FQDN, stripping components until we hit a TLD. Doing so
// is dangerous in the face of an incomplete list of TLDs, and TLDs
// get added over time. We could consider doing only a single
// substitution of the first component, if that proves to help
// compatibility.
tempString.AssignLiteral(WPAD_URL);
} else if (mSystemProxySettings) { } else if (mSystemProxySettings) {
// Get System Proxy settings if available // Get System Proxy settings if available
AsyncConfigureFromPAC(false, false); AsyncConfigureFromPAC(false, false);
} }
if (!tempString.IsEmpty() || mProxyConfig == PROXYCONFIG_WPAD) { if (!tempString.IsEmpty())
ConfigureFromPAC(tempString, true); ConfigureFromPAC(tempString, false);
}
} }
} }
@ -1484,7 +1482,9 @@ nsProtocolProxyService::SetupPACThread(nsIEventTarget *mainThreadEventTarget)
else { else {
rv = mPACMan->Init(nullptr); rv = mPACMan->Init(nullptr);
} }
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
mPACMan->Shutdown();
mPACMan = nullptr; mPACMan = nullptr;
} }
return rv; return rv;
@ -1508,15 +1508,11 @@ nsProtocolProxyService::ConfigureFromPAC(const nsCString &spec,
nsresult rv = SetupPACThread(); nsresult rv = SetupPACThread();
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
bool autodetect = spec.IsEmpty(); if (mPACMan->IsPACURI(spec) && !forceReload)
if (!forceReload && ((!autodetect && mPACMan->IsPACURI(spec)) ||
(autodetect && mPACMan->IsUsingWPAD()))) {
return NS_OK; return NS_OK;
}
mFailedProxies.Clear(); mFailedProxies.Clear();
mPACMan->SetWPADOverDHCPEnabled(mWPADOverDHCPEnabled);
return mPACMan->LoadPACFromURI(spec); return mPACMan->LoadPACFromURI(spec);
} }
@ -1569,6 +1565,8 @@ nsProtocolProxyService::ReloadPAC()
nsAutoCString pacSpec; nsAutoCString pacSpec;
if (type == PROXYCONFIG_PAC) if (type == PROXYCONFIG_PAC)
prefs->GetCharPref(PROXY_PREF("autoconfig_url"), pacSpec); prefs->GetCharPref(PROXY_PREF("autoconfig_url"), pacSpec);
else if (type == PROXYCONFIG_WPAD)
pacSpec.AssignLiteral(WPAD_URL);
else if (type == PROXYCONFIG_SYSTEM) { else if (type == PROXYCONFIG_SYSTEM) {
if (mSystemProxySettings) { if (mSystemProxySettings) {
AsyncConfigureFromPAC(true, true); AsyncConfigureFromPAC(true, true);
@ -1577,7 +1575,7 @@ nsProtocolProxyService::ReloadPAC()
} }
} }
if (!pacSpec.IsEmpty() || type == PROXYCONFIG_WPAD) if (!pacSpec.IsEmpty())
ConfigureFromPAC(pacSpec, true); ConfigureFromPAC(pacSpec, true);
return NS_OK; return NS_OK;
} }
@ -1601,8 +1599,8 @@ class nsAsyncBridgeRequest final : public nsPACManCallback
} }
void OnQueryComplete(nsresult status, void OnQueryComplete(nsresult status,
const nsACString &pacString, const nsCString &pacString,
const nsACString &newPACURL) override const nsCString &newPACURL) override
{ {
MutexAutoLock lock(mMutex); MutexAutoLock lock(mMutex);
mCompleted = true; mCompleted = true;

Просмотреть файл

@ -400,7 +400,6 @@ protected:
int32_t mSOCKSProxyVersion; int32_t mSOCKSProxyVersion;
bool mSOCKSProxyRemoteDNS; bool mSOCKSProxyRemoteDNS;
bool mProxyOverTLS; bool mProxyOverTLS;
bool mWPADOverDHCPEnabled;
RefPtr<nsPACMan> mPACMan; // non-null if we are using PAC RefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings; nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;

Просмотреть файл

@ -335,10 +335,6 @@
#define NS_SYSTEMPROXYSETTINGS_CONTRACTID \ #define NS_SYSTEMPROXYSETTINGS_CONTRACTID \
"@mozilla.org/system-proxy-settings;1" "@mozilla.org/system-proxy-settings;1"
// component implementing nsIDHCPClient.
#define NS_DHCPCLIENT_CONTRACTID \
"@mozilla.org/dhcp-client;1"
// service implementing nsIStreamTransportService // service implementing nsIStreamTransportService
#define NS_STREAMTRANSPORTSERVICE_CONTRACTID \ #define NS_STREAMTRANSPORTSERVICE_CONTRACTID \
"@mozilla.org/network/stream-transport-service;1" "@mozilla.org/network/stream-transport-service;1"

Просмотреть файл

@ -1,322 +0,0 @@
#include "gtest/gtest.h"
#include "nsServiceManagerUtils.h"
#include "../../../xpcom/threads/nsThreadManager.h"
#include "nsIDHCPClient.h"
#include "nsIPrefBranch.h"
#include "nsComponentManager.h"
#include "mozilla/ModuleUtils.h"
#include "../../base/nsPACMan.h"
#define TEST_WPAD_DHCP_OPTION "http://pac/pac.dat"
#define TEST_ASSIGNED_PAC_URL "http://assignedpac/pac.dat"
#define WPAD_PREF 4
#define NETWORK_PROXY_TYPE_PREF_NAME "network.proxy.type"
#define GETTING_NETWORK_PROXY_TYPE_FAILED -1
nsCString WPADOptionResult;
namespace mozilla {
namespace net {
nsresult
SetNetworkProxyType(int32_t pref)
{
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs) {
return NS_ERROR_FACTORY_NOT_REGISTERED;
}
return prefs->SetIntPref(NETWORK_PROXY_TYPE_PREF_NAME, pref);
}
nsresult
GetNetworkProxyType(int32_t* pref)
{
nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs) {
return NS_ERROR_FACTORY_NOT_REGISTERED;
}
return prefs->GetIntPref(NETWORK_PROXY_TYPE_PREF_NAME, pref);
}
class nsTestDHCPClient final : public nsIDHCPClient
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIDHCPCLIENT
nsTestDHCPClient() {};
nsresult Init(){
return NS_OK;
};
private:
~nsTestDHCPClient() {};
};
NS_IMETHODIMP
nsTestDHCPClient::GetOption(uint8_t option, nsACString & _retval)
{
_retval.Assign(WPADOptionResult);
return NS_OK;
}
NS_IMPL_ISUPPORTS(nsTestDHCPClient, nsIDHCPClient)
#define NS_TESTDHCPCLIENTSERVICE_CID /* {FEBF1D69-4D7D-4891-9524-045AD18B5592} */\
{ 0xFEBF1D69, 0x4D7D, 0x4891, \
{0x95, 0x24, 0x04, 0x5a, 0xd1, 0x8b, 0x55, 0x92 } }
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsTestDHCPClient, Init)
NS_DEFINE_NAMED_CID(NS_TESTDHCPCLIENTSERVICE_CID);
static const mozilla::Module::CIDEntry kSysDHCPClientCIDs[] = {
{ &kNS_TESTDHCPCLIENTSERVICE_CID, false, nullptr, nsTestDHCPClientConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kSysDHCPClientContracts[] = {
{ NS_DHCPCLIENT_CONTRACTID, &kNS_TESTDHCPCLIENTSERVICE_CID },
{ nullptr }
};
static const mozilla::Module kSysDHCPClientModule = {
mozilla::Module::kVersion,
kSysDHCPClientCIDs,
kSysDHCPClientContracts
};
NSMODULE_DEFN(nsDHCPClientModule) = &kSysDHCPClientModule;
void
SetOptionResult(const char* result)
{
WPADOptionResult.Assign(result);
}
class ProcessPendingEventsAction final : public Runnable
{
public:
// by default we just process the queue
ProcessPendingEventsAction()
: Runnable("net::ProcessPendingEventsAction")
{ }
NS_IMETHOD
Run() override
{
if (NS_HasPendingEvents(nullptr)) {
NS_WARNING("Found pending requests on PAC thread");
nsresult rv;
rv = NS_ProcessPendingEvents(nullptr);
EXPECT_EQ(NS_OK, rv);
}
NS_WARNING("No pending requests on PAC thread");
return NS_OK;
}
};
class TestPACMan : public ::testing::Test {
protected:
RefPtr<nsPACMan> mPACMan;
void
ProcessAllEvents()
{
ProcessPendingEventsOnPACThread();
nsresult rv;
while (NS_HasPendingEvents(nullptr)) {
NS_WARNING("Pending events on main thread");
rv = NS_ProcessPendingEvents(nullptr);
ASSERT_EQ(NS_OK, rv);
ProcessPendingEventsOnPACThread();
}
NS_WARNING("End of pending events on main thread");
}
// This method is used to ensure that all pending events on the main thread
// and the Proxy thread are processsed.
// It iterates over ProcessAllEvents because simply calling ProcessAllEvents once
// did not reliably process the events on both threads on all platforms.
void
ProcessAllEventsTenTimes(){
for (int i = 0; i < 10; i++) {
ProcessAllEvents();
}
}
virtual void
SetUp()
{
ASSERT_EQ(NS_OK, GetNetworkProxyType(&originalNetworkProxyTypePref));
nsFactoryEntry* factoryEntry = nsComponentManagerImpl::gComponentManager
->GetFactoryEntry(kNS_TESTDHCPCLIENTSERVICE_CID);
if (factoryEntry) {
nsresult rv = nsComponentManagerImpl::gComponentManager->UnregisterFactory(kNS_TESTDHCPCLIENTSERVICE_CID, factoryEntry->mFactory);
ASSERT_EQ(NS_OK, rv);
}
nsComponentManagerImpl::gComponentManager->RegisterModule(&kSysDHCPClientModule, nullptr);
mPACMan = new nsPACMan(nullptr);
mPACMan->SetWPADOverDHCPEnabled(true);
mPACMan->Init(nullptr);
ASSERT_EQ(NS_OK, SetNetworkProxyType(WPAD_PREF));
}
virtual void
TearDown()
{
mPACMan->Shutdown();
if (originalNetworkProxyTypePref != GETTING_NETWORK_PROXY_TYPE_FAILED) {
ASSERT_EQ(NS_OK, SetNetworkProxyType(originalNetworkProxyTypePref));
}
}
nsCOMPtr<nsIDHCPClient>
GetPACManDHCPCient()
{
return mPACMan->mDHCPClient;
}
void
SetPACManDHCPCient(nsCOMPtr<nsIDHCPClient> aValue)
{
mPACMan->mDHCPClient = aValue;
}
void
AssertPACSpecEqualTo(const char* aExpected)
{
ASSERT_STREQ(aExpected, mPACMan->mPACURISpec.Data());
}
private:
int32_t originalNetworkProxyTypePref = GETTING_NETWORK_PROXY_TYPE_FAILED;
void ProcessPendingEventsOnPACThread(){
RefPtr<ProcessPendingEventsAction> action =
new ProcessPendingEventsAction();
mPACMan->mPACThread->Dispatch(action, nsIEventTarget::DISPATCH_SYNC);
}
};
TEST_F(TestPACMan, TestCreateDHCPClientAndGetOption) {
SetOptionResult(TEST_WPAD_DHCP_OPTION);
nsCString spec;
GetPACManDHCPCient()->GetOption(252, spec);
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, spec.Data());
}
TEST_F(TestPACMan, TestCreateDHCPClientAndGetEmptyOption) {
SetOptionResult("");
nsCString spec;
spec.AssignLiteral(TEST_ASSIGNED_PAC_URL);
GetPACManDHCPCient()->GetOption(252, spec);
ASSERT_TRUE(spec.IsEmpty());
}
TEST_F(TestPACMan, WhenTheDHCPClientExistsAndDHCPIsNonEmptyDHCPOptionIsUsedAsPACUri) {
SetOptionResult(TEST_WPAD_DHCP_OPTION);
mPACMan->LoadPACFromURI(EmptyCString());
ProcessAllEventsTenTimes();
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data());
AssertPACSpecEqualTo(TEST_WPAD_DHCP_OPTION);
}
TEST_F(TestPACMan, WhenTheDHCPResponseIsEmptyWPADDefaultsToStandardURL) {
SetOptionResult(EmptyCString().Data());
mPACMan->LoadPACFromURI(EmptyCString());
ASSERT_TRUE(NS_HasPendingEvents(nullptr));
ProcessAllEventsTenTimes();
ASSERT_STREQ("", WPADOptionResult.Data());
AssertPACSpecEqualTo("http://wpad/wpad.dat");
}
TEST_F(TestPACMan, WhenThereIsNoDHCPClientWPADDefaultsToStandardURL) {
SetOptionResult(TEST_WPAD_DHCP_OPTION);
SetPACManDHCPCient(nullptr);
mPACMan->LoadPACFromURI(EmptyCString());
ProcessAllEventsTenTimes();
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data());
AssertPACSpecEqualTo("http://wpad/wpad.dat");
}
TEST_F(TestPACMan, WhenWPADOverDHCPIsPreffedOffWPADDefaultsToStandardURL) {
SetOptionResult(TEST_WPAD_DHCP_OPTION);
mPACMan->SetWPADOverDHCPEnabled(false);
mPACMan->LoadPACFromURI(EmptyCString());
ProcessAllEventsTenTimes();
ASSERT_STREQ(TEST_WPAD_DHCP_OPTION, WPADOptionResult.Data());
AssertPACSpecEqualTo("http://wpad/wpad.dat");
}
TEST_F(TestPACMan, WhenPACUriIsSetDirectlyItIsUsedRatherThanWPAD) {
SetOptionResult(TEST_WPAD_DHCP_OPTION);
nsCString spec;
spec.AssignLiteral(TEST_ASSIGNED_PAC_URL);
mPACMan->LoadPACFromURI(spec);
ProcessAllEventsTenTimes();
AssertPACSpecEqualTo(TEST_ASSIGNED_PAC_URL);
}
TEST_F(TestPACMan, WhenAScheduledReloadOfAssignedPACHappensTheAssignedPACSpecStaysRatherThanReadingFromDHCP) {
SetOptionResult(TEST_WPAD_DHCP_OPTION);
nsCString spec;
spec.AssignLiteral(TEST_ASSIGNED_PAC_URL);
mPACMan->LoadPACFromURI(spec);
ProcessAllEventsTenTimes();
mPACMan->LoadPACFromURI(EmptyCString(), true);
ProcessAllEventsTenTimes();
AssertPACSpecEqualTo(TEST_ASSIGNED_PAC_URL);
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -9,7 +9,6 @@ UNIFIED_SOURCES += [
'TestHeaders.cpp', 'TestHeaders.cpp',
'TestHttpAuthUtils.cpp', 'TestHttpAuthUtils.cpp',
'TestMozURL.cpp', 'TestMozURL.cpp',
'TestPACMan.cpp',
'TestPartiallySeekableInputStream.cpp', 'TestPartiallySeekableInputStream.cpp',
'TestProtocolProxyService.cpp', 'TestProtocolProxyService.cpp',
'TestReadStreamToString.cpp', 'TestReadStreamToString.cpp',
@ -30,8 +29,3 @@ LOCAL_INCLUDES += [
include('/ipc/chromium/chromium-config.mozbuild') include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul-gtest' FINAL_LIBRARY = 'xul-gtest'
LOCAL_INCLUDES += [
'!/xpcom',
'/xpcom/components'
]

Просмотреть файл

@ -1163,4 +1163,4 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
static const int32_t kUnknownId = -1; static const int32_t kUnknownId = -1;
static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1533204274991000); static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1533550046602000);

Просмотреть файл

@ -8,7 +8,7 @@
/*****************************************************************************/ /*****************************************************************************/
#include <stdint.h> #include <stdint.h>
const PRTime gPreloadListExpirationTime = INT64_C(1535623417693000); const PRTime gPreloadListExpirationTime = INT64_C(1535969034685000);
%% %%
0-1.party, 1 0-1.party, 1
0.me.uk, 1 0.me.uk, 1

Просмотреть файл

@ -8,7 +8,7 @@ import sys
from setuptools import setup, find_packages from setuptools import setup, find_packages
PACKAGE_NAME = 'mozrunner' PACKAGE_NAME = 'mozrunner'
PACKAGE_VERSION = '7.0.0' PACKAGE_VERSION = '7.0.1'
desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)""" desc = """Reliable start/stop/configuration of Mozilla Applications (Firefox, Thunderbird, etc.)"""

Просмотреть файл

@ -40,8 +40,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
DIRS += ['system/osxproxy'] DIRS += ['system/osxproxy']
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DIRS += ['system/windowsproxy', DIRS += ['system/windowsproxy']
'system/windowsDHCPClient']
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
DIRS += ['system/androidproxy'] DIRS += ['system/androidproxy']

Просмотреть файл

@ -1,256 +0,0 @@
/* -*- 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 "DHCPUtils.h"
#include <vector>
#include "mozilla\Logging.h"
#include "nsString.h"
#define MOZ_WORKING_BUFFER_SIZE_NETWORK_ADAPTERS 15000
#define MOZ_WORKING_BUFFER_SIZE_DHCP_PARAMS 1000
#define MOZ_MAX_TRIES 3
namespace mozilla {
namespace toolkit {
namespace system {
namespace windowsDHCPClient {
//
// The comments on this page reference the following Microsoft documentation pages (both retrieved 2017-06-27)
// [1] https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx
// [2] https://msdn.microsoft.com/en-us/library/windows/desktop/aa363298(v=vs.85).aspx
mozilla::LazyLogModule gDhcpUtilsLog("dhcpUtils");
#undef LOG
#define LOG(args) MOZ_LOG(gDhcpUtilsLog, LogLevel::Debug, args)
bool
IsCurrentAndHasDHCP(PIP_ADAPTER_ADDRESSES aAddresses)
{
return aAddresses->OperStatus == 1 &&
(aAddresses->Dhcpv4Server.iSockaddrLength ||
aAddresses->Dhcpv6Server.iSockaddrLength);
}
nsresult
GetActiveDHCPNetworkAdapterName(nsACString& aNetworkAdapterName,
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper)
{
/* Declare and initialize variables */
uint32_t dwSize = 0;
uint32_t dwRetVal = 0;
nsresult rv = NS_ERROR_FAILURE;
// Set the flags to pass to GetAdaptersAddresses
uint32_t flags = GAA_FLAG_INCLUDE_PREFIX;
// default to unspecified address family (both)
uint32_t family = AF_UNSPEC;
// Allocate a 15 KB buffer to start with.
uint32_t outBufLen = MOZ_WORKING_BUFFER_SIZE_NETWORK_ADAPTERS;
uint32_t iterations = 0;
aNetworkAdapterName.Truncate();
// Now we try calling the GetAdaptersAddresses method until the return value
// is not ERROR_BUFFER_OVERFLOW. According to [1]
//
//
// > When the return value is ERROR_BUFFER_OVERFLOW, the SizePointer parameter returned
// > points to the required size of the buffer to hold the adapter information.
// > Note that it is possible for the buffer size required for the IP_ADAPTER_ADDRESSES
// > structures pointed to by the AdapterAddresses parameter to change between
// > subsequent calls to the GetAdaptersAddresses function if an adapter address
// > is added or removed. However, this method of using the GetAdaptersAddresses
// > function is strongly discouraged. This method requires calling the
// > GetAdaptersAddresses function multiple times.
// >
// > The recommended method of calling the GetAdaptersAddresses function is
// > to pre-allocate a 15KB working buffer pointed to by the AdapterAddresses parameter.
// > On typical computers, this dramatically reduces the chances that the
// > GetAdaptersAddresses function returns ERROR_BUFFER_OVERFLOW, which would require
// > calling GetAdaptersAddresses function multiple times.
//
//
// The possibility of the buffer size changing between calls to
// GetAdaptersAddresses is why we allow the following code to be called several times,
// rather than just the two that would be neccessary if we could rely on the
// value returned in outBufLen being the true size needed.
std::vector<IP_ADAPTER_ADDRESSES> pAddresses;
do {
pAddresses.resize(outBufLen/sizeof(IP_ADAPTER_ADDRESSES));
dwRetVal =
aWindowsNetworkFunctionsWrapper->GetAdaptersAddressesWrapped(
family, flags, nullptr, pAddresses.data(), (PULONG)&outBufLen);
if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
iterations++;
}
} while (dwRetVal == ERROR_BUFFER_OVERFLOW && iterations < MOZ_MAX_TRIES);
switch(dwRetVal) {
case NO_ERROR:
{
// set default return value if we don't find a suitable network adapter
rv = NS_ERROR_NOT_AVAILABLE;
PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses.data();
while (pCurrAddresses) {
if (IsCurrentAndHasDHCP(pCurrAddresses)) {
rv = NS_OK;
aNetworkAdapterName.Assign(pCurrAddresses->AdapterName);
break;
}
pCurrAddresses = pCurrAddresses->Next;
}
}
break;
case ERROR_NO_DATA:
rv = NS_ERROR_NOT_AVAILABLE;
break;
default:
MOZ_LOG(gDhcpUtilsLog, mozilla::LogLevel::Warning,
("GetAdaptersAddresses returned %d", dwRetVal));
rv = NS_ERROR_FAILURE;
break;
}
return rv;
}
DWORD
IterateDHCPInformRequestsUntilBufferLargeEnough(
DHCPCAPI_PARAMS& aDhcpRequestedOptionParams,
wchar_t* aWideNetworkAdapterName,
std::vector<char>& aBuffer,
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper)
{
uint32_t iterations = 0;
uint32_t outBufLen = MOZ_WORKING_BUFFER_SIZE_DHCP_PARAMS;
DHCPCAPI_PARAMS_ARRAY RequestParams = {
1, // only one option to request
&aDhcpRequestedOptionParams
};
// According to [2],
// the following is for 'Optional data to be requested,
// in addition to the data requested in the RecdParams array.'
// We are not requesting anything in addition, so this is empty.
DHCPCAPI_PARAMS_ARRAY SendParams = {
0,
nullptr
};
DWORD winAPIResponse;
// Now we try calling the DHCPRequestParams method until the return value
// is not ERROR_MORE_DATA. According to [2]:
//
//
// > Note that the required size of Buffer may increase during the time that elapses
// > between the initial function call's return and a subsequent call;
// > therefore, the required size of Buffer (indicated in pSize)
// > provides an indication of the approximate size required of Buffer,
// > rather than guaranteeing that subsequent calls will return successfully
// > if Buffer is set to the size indicated in pSize.
//
//
// This is why we allow this DHCPRequestParams to be called several times,
// rather than just the two that would be neccessary if we could rely on the
// value returned in outBufLen being the true size needed.
do {
aBuffer.resize(outBufLen);
winAPIResponse = aWindowsNetworkFunctionsWrapper->DhcpRequestParamsWrapped(
DHCPCAPI_REQUEST_SYNCHRONOUS, // Flags
nullptr, // Reserved
aWideNetworkAdapterName, // Adapter Name
nullptr, // not using class id
SendParams, // sent parameters
RequestParams, // requesting params
(PBYTE)aBuffer.data(), // buffer for the output of RequestParams
(PULONG)&outBufLen, // buffer size
nullptr // Request ID for persistent requests - not needed here
);
if (winAPIResponse == ERROR_MORE_DATA) {
iterations++;
}
} while (winAPIResponse == ERROR_MORE_DATA && iterations < MOZ_MAX_TRIES);
return winAPIResponse;
}
nsresult
RetrieveOption(
const nsACString& aAdapterName,
uint8_t aOption,
std::vector<char>& aOptionValueBuf,
uint32_t* aOptionSize,
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper)
{
nsresult rv;
nsAutoString wideNetworkAdapterName = NS_ConvertUTF8toUTF16(aAdapterName);
DHCPCAPI_PARAMS DhcpRequestedOptionParams = {
0, // Flags - Reserved, must be set to zero [2]
aOption, // OptionId
false, // whether this is vendor specific - let's assume not
nullptr, // data filled in on return
0 // nBytes used by return data
};
std::vector<char> tmpBuffer(MOZ_WORKING_BUFFER_SIZE_DHCP_PARAMS); // a buffer for the DHCP response object
DWORD winAPIResponse = IterateDHCPInformRequestsUntilBufferLargeEnough(DhcpRequestedOptionParams,
wideNetworkAdapterName.get(),
tmpBuffer,
aWindowsNetworkFunctionsWrapper);
switch (winAPIResponse){
case NO_ERROR:
{
if (DhcpRequestedOptionParams.nBytesData == 0) {
*aOptionSize = 0;
rv = NS_ERROR_NOT_AVAILABLE;
break;
}
if (*aOptionSize >= DhcpRequestedOptionParams.nBytesData) {
rv = NS_OK;
} else {
rv = NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
}
uint32_t actualSizeReturned =
*aOptionSize > DhcpRequestedOptionParams.nBytesData?
DhcpRequestedOptionParams.nBytesData: *aOptionSize;
memcpy(aOptionValueBuf.data(),
DhcpRequestedOptionParams.Data, actualSizeReturned);
*aOptionSize = DhcpRequestedOptionParams.nBytesData;
break;
}
case ERROR_INVALID_PARAMETER:
MOZ_LOG(gDhcpUtilsLog, mozilla::LogLevel::Warning,
("RetrieveOption returned %d (ERROR_INVALID_PARAMETER) when option %d requested",
winAPIResponse, aOption));
rv = NS_ERROR_INVALID_ARG;
break;
default:
MOZ_LOG(gDhcpUtilsLog, mozilla::LogLevel::Warning,
("RetrieveOption returned %d when option %d requested", winAPIResponse, aOption));
rv = NS_ERROR_FAILURE;
}
return rv;
}
} // namespace windowsDHCPClient
} // namespace system
} // namespace toolkit
} // namespace mozilla

Просмотреть файл

@ -1,34 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_toolkit_system_windowsDHCPClient_DHCPUtils_h
#define mozilla_toolkit_system_windowsDHCPClient_DHCPUtils_h
#include "WindowsNetworkFunctionsWrapper.h"
#include <vector>
namespace mozilla {
namespace toolkit {
namespace system {
namespace windowsDHCPClient {
nsresult GetActiveDHCPNetworkAdapterName(
nsACString& aNetworkAdapterName,
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper);
nsresult RetrieveOption(
const nsACString& aAdapterName,
uint8_t aOption,
std::vector<char>& aOptionValueBuf,
uint32_t* aOptionSize,
WindowsNetworkFunctionsWrapper* aWindowsNetworkFunctionsWrapper
);
} // namespace windowsDHCPClient
} // namespace system
} // namespace toolkit
} // namespace mozilla
#endif // mozilla_toolkit_system_windowsDHCPClient_DHCPUtils_h

Просмотреть файл

@ -1,46 +0,0 @@
/* -*- 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 "WindowsNetworkFunctionsWrapper.h"
#pragma comment(lib, "IPHLPAPI.lib")
#pragma comment(lib, "dhcpcsvc.lib" )
namespace mozilla {
namespace toolkit {
namespace system {
namespace windowsDHCPClient {
NS_IMPL_ISUPPORTS(WindowsNetworkFunctionsWrapper, nsISupports)
ULONG WindowsNetworkFunctionsWrapper::GetAdaptersAddressesWrapped(
_In_ ULONG aFamily,
_In_ ULONG aFlags,
_In_ PVOID aReserved,
_Inout_ PIP_ADAPTER_ADDRESSES aAdapterAddresses,
_Inout_ PULONG aSizePointer)
{
return GetAdaptersAddresses(aFamily, aFlags, aReserved, aAdapterAddresses, aSizePointer);
}
DWORD WindowsNetworkFunctionsWrapper::DhcpRequestParamsWrapped(
_In_ DWORD aFlags,
_In_ LPVOID aReserved,
_In_ LPWSTR aAdapterName,
_In_ LPDHCPCAPI_CLASSID aClassId,
_In_ DHCPCAPI_PARAMS_ARRAY aSendParams,
_Inout_ DHCPCAPI_PARAMS_ARRAY aRecdParams,
_In_ LPBYTE aBuffer,
_Inout_ LPDWORD apSize,
_In_ LPWSTR aRequestIdStr)
{
return DhcpRequestParams(aFlags, aReserved, aAdapterName, aClassId, aSendParams, aRecdParams, aBuffer, apSize, aRequestIdStr);
}
} // namespace windowsDHCPClient
} // namespace system
} // namespace toolkit
} // namespace mozilla

Просмотреть файл

@ -1,60 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_toolkit_system_windowsDHCPClient_windowsNetworkFunctionsWrapper_h
#define mozilla_toolkit_system_windowsDHCPClient_windowsNetworkFunctionsWrapper_h
#include <Winsock2.h> // there is a compilation error if Winsock.h is not
// declared before dhcpcsdk.h
#include <dhcpcsdk.h>
#include <iphlpapi.h>
#include "nsISupports.h"
// Thin wrapper around low-level network functions needed for DHCP querying for web proxy
namespace mozilla {
namespace toolkit {
namespace system {
namespace windowsDHCPClient {
class WindowsNetworkFunctionsWrapper : nsISupports
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
WindowsNetworkFunctionsWrapper(){};
virtual ULONG GetAdaptersAddressesWrapped(
_In_ ULONG aFamily,
_In_ ULONG aFlags,
_In_ PVOID aReserved,
_Inout_ PIP_ADAPTER_ADDRESSES aAdapterAddresses,
_Inout_ PULONG aSizePointer
);
virtual DWORD DhcpRequestParamsWrapped(
_In_ DWORD aFlags,
_In_ LPVOID aReserved,
_In_ LPWSTR aAdapterName,
_In_ LPDHCPCAPI_CLASSID aClassId,
_In_ DHCPCAPI_PARAMS_ARRAY aSendParams,
_Inout_ DHCPCAPI_PARAMS_ARRAY aRecdParams,
_In_ LPBYTE aBuffer,
_Inout_ LPDWORD apSize,
_In_ LPWSTR aRequestIdStr
);
protected:
~WindowsNetworkFunctionsWrapper(){};
};
} // namespace windowsDHCPClient
} // namespace system
} // namespace toolkit
} // namespace mozilla
#endif //mozilla_toolkit_system_windowsDHCPClient_windowsNetworkFunctionsWrapper_h

Просмотреть файл

@ -1,18 +0,0 @@
# -*- 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/.
with Files('**'):
BUG_COMPONENT = ('Core', 'Networking: HTTP')
TEST_DIRS += ['tests/gtest']
SOURCES += [
'DHCPUtils.cpp',
'nsWindowsDHCPClient.cpp',
'WindowsNetworkFunctionsWrapper.cpp'
]
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -1,103 +0,0 @@
/* -*- 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 "nsWindowsDHCPClient.h"
#include <vector>
#include "DHCPUtils.h"
#include "nsNetCID.h"
#include "nsString.h"
#include "mozilla/Logging.h"
#include "mozilla/ModuleUtils.h"
namespace mozilla {
namespace toolkit {
namespace system {
namespace windowsDHCPClient {
LazyLogModule gDhcpLog("windowsDHCPClient");
#undef LOG
#define LOG(args) MOZ_LOG(gDhcpLog, LogLevel::Debug, args)
#define MOZ_MAX_DHCP_OPTION_LENGTH 255 // this is the maximum option length in DHCP V4 and 6
NS_IMPL_ISUPPORTS(nsWindowsDHCPClient, nsIDHCPClient)
nsresult
nsWindowsDHCPClient::Init()
{
return NS_OK;
}
NS_IMETHODIMP
nsWindowsDHCPClient::GetOption(uint8_t aOption, nsACString& aRetVal)
{
nsCString networkAdapterName;
nsresult rv;
rv = GetActiveDHCPNetworkAdapterName(networkAdapterName, mNetworkFunctions);
if (rv != NS_OK) {
LOG(("Failed to get network adapter name in nsWindowsDHCPClient::GetOption due to error %d", rv));
return rv;
}
uint32_t sizeOptionValue = MOZ_MAX_DHCP_OPTION_LENGTH;
std::vector<char> optionValue;
bool retryingAfterLossOfSignificantData = false;
do {
optionValue.resize(sizeOptionValue);
rv = RetrieveOption(networkAdapterName,
aOption,
optionValue,
&sizeOptionValue,
mNetworkFunctions);
if (rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) {
LOG(("In nsWindowsDHCPClient::GetOption, DHCP Option %d required %d bytes", aOption, sizeOptionValue));
if (retryingAfterLossOfSignificantData) {
break;
}
retryingAfterLossOfSignificantData = true;
}
} while (rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA);
if (rv != NS_OK) {
LOG(("Failed to get DHCP Option %d nsWindowsDHCPClient::GetOption due to error %d", aOption, rv));
return rv;
}
aRetVal.Assign(optionValue.data(), sizeOptionValue);
return NS_OK;
}
#define NS_WINDOWSDHCPCLIENTSERVICE_CID /* {FEBF1D69-4D7D-4891-9524-045AD18B5592} */\
{ 0xFEBF1D69, 0x4D7D, 0x4891, \
{0x95, 0x24, 0x04, 0x5a, 0xd1, 0x8b, 0x55, 0x92 } }
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowsDHCPClient, Init)
NS_DEFINE_NAMED_CID(NS_WINDOWSDHCPCLIENTSERVICE_CID);
static const mozilla::Module::CIDEntry kSysDHCPClientCIDs[] = {
{ &kNS_WINDOWSDHCPCLIENTSERVICE_CID, false, nullptr, nsWindowsDHCPClientConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kSysDHCPClientContracts[] = {
{ NS_DHCPCLIENT_CONTRACTID, &kNS_WINDOWSDHCPCLIENTSERVICE_CID },
{ nullptr }
};
static const mozilla::Module kSysDHCPClientModule = {
mozilla::Module::kVersion,
kSysDHCPClientCIDs,
kSysDHCPClientContracts
};
NSMODULE_DEFN(nsDHCPClientModule) = &kSysDHCPClientModule;
} // namespace windowsDHCPClient
} // namespace system
} // namespace toolkit
} // namespace mozilla

Просмотреть файл

@ -1,38 +0,0 @@
/* -*- 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 "nsIDHCPClient.h"
#include "nsIServiceManager.h"
#include "nsNetCID.h"
#include "WindowsNetworkFunctionsWrapper.h"
namespace mozilla {
namespace toolkit {
namespace system {
namespace windowsDHCPClient {
class nsWindowsDHCPClient final : public nsIDHCPClient
{
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIDHCPCLIENT
explicit nsWindowsDHCPClient(WindowsNetworkFunctionsWrapper *aNetworkFunctions = new WindowsNetworkFunctionsWrapper())
: mNetworkFunctions(aNetworkFunctions) {};
nsresult Init();
private:
~nsWindowsDHCPClient() {};
WindowsNetworkFunctionsWrapper* mNetworkFunctions;
};
} // namespace windowsDHCPClient
} // namespace system
} // namespace toolkit
} // namespace mozilla

Просмотреть файл

@ -1,323 +0,0 @@
/* -*- 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 "DHCPUtils.h"
#include "gtest/gtest.h"
#include "nsString.h"
#include "nsWindowsDHCPClient.h"
using namespace mozilla::toolkit::system::windowsDHCPClient;
class WindowsNetworkFunctionsMock : public WindowsNetworkFunctionsWrapper {
public:
WindowsNetworkFunctionsMock():mAddressesToReturn(nullptr) {
memset(mOptions, 0, sizeof(char*) * 256);
}
ULONG GetAdaptersAddressesWrapped(
_In_ ULONG Family,
_In_ ULONG Flags,
_In_ PVOID Reserved,
_Inout_ PIP_ADAPTER_ADDRESSES AdapterAddresses,
_Inout_ PULONG SizePointer
){
if (*SizePointer < sizeof(*mAddressesToReturn)){
*SizePointer = sizeof(*mAddressesToReturn);
return ERROR_BUFFER_OVERFLOW;
}
*SizePointer = sizeof(*mAddressesToReturn);
memcpy(AdapterAddresses, mAddressesToReturn,
*SizePointer);
return 0;
}
DWORD DhcpRequestParamsWrapped(
_In_ DWORD Flags,
_In_ LPVOID Reserved,
_In_ LPWSTR AdapterName,
_In_ LPDHCPCAPI_CLASSID ClassId,
_In_ DHCPCAPI_PARAMS_ARRAY SendParams,
_Inout_ DHCPCAPI_PARAMS_ARRAY RecdParams,
_In_ LPBYTE Buffer,
_Inout_ LPDWORD pSize,
_In_ LPWSTR RequestIdStr
)
{
mLastRequestedNetworkAdapterName.Assign(AdapterName);
if (mOptions[RecdParams.Params[0].OptionId] == nullptr) {
RecdParams.Params[0].nBytesData = 0;
}
else {
RecdParams.Params[0].Data = Buffer;
size_t lengthOfValue = strlen(mOptions[RecdParams.Params[0].OptionId]);
if (*pSize > lengthOfValue) {
memcpy(Buffer, mOptions[RecdParams.Params[0].OptionId], lengthOfValue);
RecdParams.Params[0].nBytesData = lengthOfValue;
} else {
*pSize = lengthOfValue;
return ERROR_MORE_DATA;
}
}
return 0;
}
void
AddAdapterAddresses(IP_ADAPTER_ADDRESSES& aAddressesToAdd)
{
if (mAddressesToReturn == nullptr) {
mAddressesToReturn = &aAddressesToAdd;
return;
}
IP_ADAPTER_ADDRESSES* tail = mAddressesToReturn;
while (tail->Next != nullptr) {
tail = tail->Next;
}
tail->Next = &aAddressesToAdd;
}
void
SetDHCPOption(uint8_t option, char* value)
{
mOptions[option] = value;
}
nsString
GetLastRequestedNetworkAdapterName()
{
return mLastRequestedNetworkAdapterName;
}
private:
IP_ADAPTER_ADDRESSES* mAddressesToReturn = nullptr;
char* mOptions[256];
nsString mLastRequestedNetworkAdapterName;
};
class TestDHCPUtils : public ::testing::Test {
protected:
RefPtr<WindowsNetworkFunctionsMock> mMockWindowsFunctions;
nsCString mDefaultAdapterName;
virtual void
SetUp()
{
mMockWindowsFunctions = new WindowsNetworkFunctionsMock();
mDefaultAdapterName.AssignLiteral("my favourite network adapter");
}
void
Given_DHCP_Option_Is(uint8_t option, char* value)
{
mMockWindowsFunctions.get()->SetDHCPOption(option, value);
}
void
Given_Network_Adapter_Called(
IP_ADAPTER_ADDRESSES& adapterAddresses,
char* adapterName)
{
adapterAddresses.AdapterName = adapterName;
adapterAddresses.Next = nullptr;
adapterAddresses.Dhcpv4Server.iSockaddrLength = 0;
adapterAddresses.Dhcpv6Server.iSockaddrLength = 0;
AddAdapterAddresses(adapterAddresses);
}
void
Given_Network_Adapter_Supports_DHCP_V4(IP_ADAPTER_ADDRESSES& adapterAddresses)
{
adapterAddresses.Dhcpv4Server.iSockaddrLength = 4;
}
void
Given_Network_Adapter_Supports_DHCP_V6(IP_ADAPTER_ADDRESSES& adapterAddresses)
{
adapterAddresses.Dhcpv6Server.iSockaddrLength = 12;
}
void
Given_Network_Adapter_Has_Operational_Status(
IP_ADAPTER_ADDRESSES& adapterAddresses,
IF_OPER_STATUS operStatus)
{
adapterAddresses.OperStatus = operStatus;
}
private:
void
AddAdapterAddresses(IP_ADAPTER_ADDRESSES& aAddressToAdd)
{
mMockWindowsFunctions.get()->AddAdapterAddresses(aAddressToAdd);
}
};
// following class currently just distinguishes tests of nsWindowsDHCPClient from
// tests of DHCPUtils.
class TestNsWindowsDHCPClient : public TestDHCPUtils { };
TEST_F(TestDHCPUtils, TestGetAdaptersAddresses)
{
IP_ADAPTER_ADDRESSES adapterAddresses = {};
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
nsCString networkAdapterName;
ASSERT_EQ(NS_OK, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
ASSERT_STREQ(networkAdapterName.Data(), "my favourite network adapter");
}
TEST_F(TestDHCPUtils, TestGetAdaptersAddressesNoAvailableNetworks)
{
IP_ADAPTER_ADDRESSES adapterAddresses = {};
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusDown);
nsCString networkAdapterName;
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
ASSERT_STREQ(networkAdapterName.Data(), "");
}
TEST_F(TestDHCPUtils, TestGetAdaptersAddressesNoNetworksWithDHCP)
{
IP_ADAPTER_ADDRESSES adapterAddresses = {};
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
nsCString networkAdapterName;
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
ASSERT_STREQ(networkAdapterName.Data(), "");
}
TEST_F(TestDHCPUtils, TestGetAdaptersAddressesSecondNetworkIsAvailable)
{
IP_ADAPTER_ADDRESSES adapterAddresses = {};
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusDown);
IP_ADAPTER_ADDRESSES secondAdapterAddresses = {};
Given_Network_Adapter_Called(secondAdapterAddresses, "my second favourite network adapter");
Given_Network_Adapter_Supports_DHCP_V6(secondAdapterAddresses);
Given_Network_Adapter_Has_Operational_Status(secondAdapterAddresses, IfOperStatusUp);
nsCString networkAdapterName;
ASSERT_EQ(NS_OK, GetActiveDHCPNetworkAdapterName(networkAdapterName, mMockWindowsFunctions));
ASSERT_STREQ(networkAdapterName.Data(), "my second favourite network adapter");
}
TEST_F(TestDHCPUtils, TestGetOption)
{
char* pacURL = "http://pac.com";
Given_DHCP_Option_Is(1, "My network option");
Given_DHCP_Option_Is(252, pacURL);
std::vector<char> optionValue(255, *"originalValue originalValue");
memcpy(optionValue.data(), "originalValue originalValue", strlen("originalValue originalValue") + 1);
uint32_t size = 255;
nsresult retVal = RetrieveOption(mDefaultAdapterName, 252, optionValue, &size, mMockWindowsFunctions);
ASSERT_EQ(strlen(pacURL), size);
ASSERT_STREQ("http://pac.comoriginalValue", optionValue.data());
ASSERT_EQ(NS_OK, retVal);
}
TEST_F(TestDHCPUtils, TestGetAbsentOption)
{
std::vector<char> optionValue(255);
uint32_t size = 256;
memcpy(optionValue.data(), "originalValue", strlen("originalValue") + 1);
nsresult retVal = RetrieveOption(mDefaultAdapterName, 252, optionValue, &size, mMockWindowsFunctions);
ASSERT_EQ(0, size);
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, retVal);
}
TEST_F(TestDHCPUtils, TestGetTooLongOption)
{
Given_DHCP_Option_Is(252, "http://pac.com");
std::vector<char> optionValue(255);
memcpy(optionValue.data(), "originalValue", strlen("originalValue") + 1);
uint32_t size = 4;
nsresult retVal = RetrieveOption(mDefaultAdapterName, 252, optionValue, &size, mMockWindowsFunctions);
ASSERT_STREQ("httpinalValue", optionValue.data());
ASSERT_EQ(NS_ERROR_LOSS_OF_SIGNIFICANT_DATA, retVal);
ASSERT_EQ(strlen("http://pac.com"), size);
}
TEST_F(TestNsWindowsDHCPClient, TestGettingOptionThroughNSWindowsDHCPClient)
{
IP_ADAPTER_ADDRESSES adapterAddresses = {};
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
Given_Network_Adapter_Supports_DHCP_V4(adapterAddresses);
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
Given_DHCP_Option_Is(252, "http://pac.com");
nsCString optionValue;
nsCOMPtr<nsIDHCPClient> dhcpClient = new nsWindowsDHCPClient(mMockWindowsFunctions);
nsresult retVal = dhcpClient->GetOption(252, optionValue);
ASSERT_STREQ("http://pac.com", optionValue.Data());
ASSERT_STREQ(L"my favourite network adapter", mMockWindowsFunctions->GetLastRequestedNetworkAdapterName().Data());
ASSERT_EQ(NS_OK, retVal);
}
TEST_F(TestNsWindowsDHCPClient, TestGettingOptionThroughNSWindowsDHCPClientWhenNoAvailableNetworkAdapter)
{
IP_ADAPTER_ADDRESSES adapterAddresses = {};
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusDown);
Given_DHCP_Option_Is(252, "http://pac.com");
nsCString optionValue;
nsCOMPtr<nsIDHCPClient> dhcpClient = new nsWindowsDHCPClient(mMockWindowsFunctions);
nsresult retVal = dhcpClient->GetOption(252, optionValue);
ASSERT_STREQ("", optionValue.Data());
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, retVal);
}
TEST_F(TestNsWindowsDHCPClient, TestGettingAbsentOptionThroughNSWindowsDHCPClient)
{
IP_ADAPTER_ADDRESSES adapterAddresses = {};
Given_Network_Adapter_Called(adapterAddresses, "my favourite network adapter");
Given_Network_Adapter_Supports_DHCP_V6(adapterAddresses);
Given_Network_Adapter_Has_Operational_Status(adapterAddresses, IfOperStatusUp);
nsCString optionValue;
nsCOMPtr<nsIDHCPClient> dhcpClient = new nsWindowsDHCPClient(mMockWindowsFunctions);
nsresult retVal = dhcpClient->GetOption(252, optionValue);
ASSERT_STREQ("", optionValue.Data());
ASSERT_EQ(NS_ERROR_NOT_AVAILABLE, retVal);
}

Просмотреть файл

@ -1,21 +0,0 @@
# -*- 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/.
with Files('**'):
BUG_COMPONENT = ('Core', 'Networking: HTTP')
UNIFIED_SOURCES += [
'TestDHCPUtils.cpp',
]
LOCAL_INCLUDES += [
'/toolkit/system/windowsDHCPClient',
]
FINAL_LIBRARY = 'xul-gtest'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wshadow']