Bug 1476899 - Web Proxy auto-detect doesn't check DHCP option 252 on Mac OS draft
authorPolly Shaw <polly.shaw@gmail.com>
Wed, 02 May 2018 22:37:09 +0100
changeset 821072 65820c6f445d894e251edb7bbaca15e4aca2dfea
parent 816909 7ebb3c95ab11a0ca3f678c565cd3bdb7153deae0
push id117009
push userbmo:polly.shaw@gmail.com
push dateFri, 20 Jul 2018 22:13:15 +0000
bugs1476899, 356831
milestone63.0a1
Bug 1476899 - Web Proxy auto-detect doesn't check DHCP option 252 on Mac OS This patch fixes the bug by implementing nsIDHCPClient (an interface defined in netwerk/base and used in the process of proxy auto-detection) on the Mac OS X platform, by using methods of the Mac OS X platform API documented here: https://developer.apple.com/documentation/systemconfiguration/scdynamicstorecopydhcpinfo?language=objc It makes the following changes: * toolkit/moz.build: changed to compile the contents of toolkit/system/osxDHCPClient when building for OS X. * toolkit/system/osxDHCPClient/moz.build: added to control the compilation of the osxDHCPClient directory * toolkit/system/osxDHCPClient/nsOSXDHCPClient.h: added header file for implementation of the nsIDHCPClient interface * toolkit/system/osxDHCPClient/nsOSXDHCPClient.mm: added to implement the functionality of the interface by calling native OS X methods. This patch does not contain tests because there is very little logic other than calling the API methods, and introducing mocks for the API would risk adding more untested code than they would remove. Existing end-to-end tests will call the auto-detect functionality, although admittedly not in an environment which has the PAC URL broadcast using DHCP. This work builds on the patch for bug 356831, which was also implemented by this author. MozReview-Commit-ID: LBI01MFhCuz
toolkit/moz.build
toolkit/system/osxDHCPClient/moz.build
toolkit/system/osxDHCPClient/nsOSXDHCPClient.h
toolkit/system/osxDHCPClient/nsOSXDHCPClient.mm
--- a/toolkit/moz.build
+++ b/toolkit/moz.build
@@ -33,17 +33,18 @@ if CONFIG['MOZ_MAINTENANCE_SERVICE']:
         'components/maintenanceservice'
     ]
 
 DIRS += ['xre']
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk3':
     DIRS += ['system/unixproxy']
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
-    DIRS += ['system/osxproxy']
+    DIRS += ['system/osxproxy',
+            'system/osxDHCPClient']
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     DIRS += ['system/windowsproxy',
             'system/windowsDHCPClient']
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     DIRS += ['system/androidproxy']
 
 TEST_HARNESS_FILES.testing.mochitest.browser.toolkit.crashreporter.test.browser += [
     'crashreporter/test/browser/crashreport.sjs',
new file mode 100644
--- /dev/null
+++ b/toolkit/system/osxDHCPClient/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/.
+
+with Files('**'):
+    BUG_COMPONENT = ('Core', 'Networking: HTTP')
+
+SOURCES += [
+    'nsOSXDHCPClient.mm'
+]
+
+FINAL_LIBRARY = 'xul'
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/toolkit/system/osxDHCPClient/nsOSXDHCPClient.h
@@ -0,0 +1,33 @@
+/* -*- 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"
+
+namespace mozilla {
+namespace toolkit {
+namespace system {
+namespace osxDHCPClient {
+
+class nsOSXDHCPClient final : public nsIDHCPClient
+{
+public:
+  NS_DECL_THREADSAFE_ISUPPORTS
+  NS_DECL_NSIDHCPCLIENT
+
+  nsOSXDHCPClient() {};
+  nsresult Init();
+
+private:
+   ~nsOSXDHCPClient() {};
+};
+
+
+} // namespace osxDHCPClient
+} // namespace system
+} // namespace toolkit
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/toolkit/system/osxDHCPClient/nsOSXDHCPClient.mm
@@ -0,0 +1,84 @@
+/* -*- 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/. */
+#import <Cocoa/Cocoa.h>
+#import <SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h>
+
+#include "nsOSXDHCPClient.h"
+
+#include "nsString.h"
+#include "mozilla/Logging.h"
+#include "mozilla/ModuleUtils.h"
+
+namespace mozilla {
+namespace toolkit {
+namespace system {
+namespace osxDHCPClient {
+
+LazyLogModule gDhcpLog("osxDHCPClient");
+
+#undef LOG
+#define LOG(args) MOZ_LOG(gDhcpLog, LogLevel::Debug, args)
+#undef WARN
+#define WARN(args) MOZ_LOG(gDhcpLog, LogLevel::Warning, args)
+
+NS_IMPL_ISUPPORTS(nsOSXDHCPClient, nsIDHCPClient)
+
+NS_IMETHODIMP
+nsOSXDHCPClient::GetOption(uint8_t aOption, nsACString& aRetVal)
+{
+  CFDictionaryRef dict = SCDynamicStoreCopyDHCPInfo(nullptr, nullptr);
+  if (!dict) {
+    WARN(("Failed to execute SCDynamicStoreCopyDHCPInfo in nsOSXDHCPClient::GetOption"));
+    aRetVal.Truncate();
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  CFDataRef ref = DHCPInfoGetOptionData(dict, aOption);
+  if (ref == nullptr) {
+    aRetVal.Truncate();
+  } else {
+    aRetVal.Assign((const char*)CFDataGetBytePtr(ref), CFDataGetLength(ref));
+  }
+  CFRelease(dict);
+
+  LOG(("nsOSXDHCPClient::GetOption retrieved '%s' for DHCP option %u", aRetVal.Data(), aOption));
+  return NS_OK;
+}
+
+nsresult
+nsOSXDHCPClient::Init()
+{
+  return NS_OK;
+}
+
+#define NS_OSXDHCPCLIENTSERVICE_CID  /* {FEBF1D69-4D7D-4891-9524-045AD18B5592} */\
+    { 0xFEBF1D69, 0x4D7D, 0x4891, \
+         {0x95, 0x24, 0x04, 0x5a, 0xd1, 0x8b, 0x55, 0x92 } }
+
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsOSXDHCPClient, Init)
+NS_DEFINE_NAMED_CID(NS_OSXDHCPCLIENTSERVICE_CID);
+
+static const mozilla::Module::CIDEntry kSysDHCPClientCIDs[] = {
+  { &kNS_OSXDHCPCLIENTSERVICE_CID, false, nullptr, nsOSXDHCPClientConstructor },
+  { nullptr }
+};
+
+static const mozilla::Module::ContractIDEntry kSysDHCPClientContracts[] = {
+  { NS_DHCPCLIENT_CONTRACTID, &kNS_OSXDHCPCLIENTSERVICE_CID },
+  { nullptr }
+};
+
+static const mozilla::Module kSysDHCPClientModule = {
+  mozilla::Module::kVersion,
+  kSysDHCPClientCIDs,
+  kSysDHCPClientContracts
+};
+
+NSMODULE_DEFN(nsDHCPClientModule) = &kSysDHCPClientModule;
+
+} // namespace osxDHCPClient
+} // namespace system
+} // namespace toolkit
+} // namespace mozilla