Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Read system proxy information on macOS #36177

Merged
merged 5 commits into from
Apr 13, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/Common/src/Interop/OSX/Interop.CoreFoundation.CFArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,16 @@ namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFArrayHandle : SafeHandle
{
internal SafeCFArrayHandle()
private SafeCFArrayHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}

internal SafeCFArrayHandle(IntPtr handle, bool ownsHandle)
: base(handle, ownsHandle)
{
}

protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
Expand Down
43 changes: 43 additions & 0 deletions src/Common/src/Interop/OSX/Interop.CoreFoundation.CFDictionary.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal static partial class CoreFoundation
{
[DllImport(Libraries.CoreFoundationLibrary)]
internal static extern IntPtr CFDictionaryGetValue(SafeCFDictionaryHandle handle, IntPtr key);
}
}

namespace Microsoft.Win32.SafeHandles
{
internal sealed class SafeCFDictionaryHandle : SafeHandle
{
private SafeCFDictionaryHandle()
: base(IntPtr.Zero, ownsHandle: true)
{
}

internal SafeCFDictionaryHandle(IntPtr handle, bool ownsHandle)
: base(handle, ownsHandle)
{
}

protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
SetHandle(IntPtr.Zero);
return true;
}

public override bool IsInvalid => handle == IntPtr.Zero;
}
}
23 changes: 23 additions & 0 deletions src/Common/src/Interop/OSX/Interop.CoreFoundation.CFNumber.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal static partial class CoreFoundation
{
internal enum CFNumberType
{
kCFNumberIntType = 9,
}

[DllImport(Libraries.CoreFoundationLibrary)]
private static extern int CFNumberGetValue(IntPtr handle, CFNumberType type, out int value);
}
}
145 changes: 145 additions & 0 deletions src/Common/src/Interop/OSX/Interop.CoreFoundation.CFProxy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;

using CFRunLoopSourceRef = System.IntPtr;

internal static partial class Interop
{
internal static partial class CoreFoundation
{
[DllImport(Libraries.CFNetworkLibrary)]
internal static extern SafeCFDictionaryHandle CFNetworkCopySystemProxySettings();

[DllImport(Libraries.CFNetworkLibrary)]
internal static extern SafeCFArrayHandle CFNetworkCopyProxiesForURL(SafeCreateHandle url, SafeCFDictionaryHandle proxySettings);

internal delegate void CFProxyAutoConfigurationResultCallback(IntPtr client, IntPtr proxyList, IntPtr error);

[DllImport(Libraries.CFNetworkLibrary)]
internal static extern CFRunLoopSourceRef CFNetworkExecuteProxyAutoConfigurationURL(
IntPtr proxyAutoConfigURL,
SafeCreateHandle targetURL,
CFProxyAutoConfigurationResultCallback cb,
ref CFStreamClientContext clientContext);

[DllImport(Libraries.CFNetworkLibrary)]
internal static extern CFRunLoopSourceRef CFNetworkExecuteProxyAutoConfigurationScript(
IntPtr proxyAutoConfigurationScript,
SafeCreateHandle targetURL,
CFProxyAutoConfigurationResultCallback cb,
ref CFStreamClientContext clientContext);

[StructLayout(LayoutKind.Sequential)]
internal struct CFStreamClientContext
{
public IntPtr Version;
public IntPtr Info;
public IntPtr Retain;
public IntPtr Release;
public IntPtr CopyDescription;
}

internal class CFProxy
{
private SafeCFDictionaryHandle _dictionary;

internal static readonly string kCFProxyTypeAutoConfigurationURL;
internal static readonly string kCFProxyTypeAutoConfigurationJavaScript;
internal static readonly string kCFProxyTypeFTP;
internal static readonly string kCFProxyTypeHTTP;
internal static readonly string kCFProxyTypeHTTPS;
internal static readonly string kCFProxyTypeSOCKS;

private static readonly IntPtr kCFProxyAutoConfigurationJavaScriptKey;
private static readonly IntPtr kCFProxyAutoConfigurationURLKey;
private static readonly IntPtr kCFProxyHostNameKey;
private static readonly IntPtr kCFProxyPasswordKey;
private static readonly IntPtr kCFProxyPortNumberKey;
private static readonly IntPtr kCFProxyTypeKey;
private static readonly IntPtr kCFProxyUsernameKey;

static CFProxy()
{
IntPtr lib = NativeLibrary.Load(Interop.Libraries.CFNetworkLibrary);
if (lib != IntPtr.Zero)
{
kCFProxyTypeAutoConfigurationURL = LoadCFStringSymbol(lib, "kCFProxyTypeAutoConfigurationURL");
kCFProxyTypeAutoConfigurationJavaScript = LoadCFStringSymbol(lib, "kCFProxyTypeAutoConfigurationJavaScript");
kCFProxyTypeFTP = LoadCFStringSymbol(lib, "kCFProxyTypeFTP");
kCFProxyTypeHTTP = LoadCFStringSymbol(lib, "kCFProxyTypeHTTP");
kCFProxyTypeHTTPS = LoadCFStringSymbol(lib, "kCFProxyTypeHTTPS");
kCFProxyTypeSOCKS = LoadCFStringSymbol(lib, "kCFProxyTypeSOCKS");

kCFProxyAutoConfigurationJavaScriptKey = LoadSymbol(lib, "kCFProxyAutoConfigurationJavaScriptKey");
kCFProxyAutoConfigurationURLKey = LoadSymbol(lib, "kCFProxyAutoConfigurationURLKey");
kCFProxyHostNameKey = LoadSymbol(lib, "kCFProxyHostNameKey");
kCFProxyPasswordKey = LoadSymbol(lib, "kCFProxyPasswordKey");
kCFProxyPortNumberKey = LoadSymbol(lib, "kCFProxyPortNumberKey");
kCFProxyTypeKey = LoadSymbol(lib, "kCFProxyTypeKey");
kCFProxyUsernameKey = LoadSymbol(lib, "kCFProxyUsernameKey");
}
}

public CFProxy(SafeCFDictionaryHandle dictionary)
{
_dictionary = dictionary;
}

private static IntPtr LoadSymbol(IntPtr lib, string name)
{
IntPtr indirect = NativeLibrary.GetExport(lib, name);
return indirect == IntPtr.Zero ? IntPtr.Zero : Marshal.ReadIntPtr(indirect);
filipnavara marked this conversation as resolved.
Show resolved Hide resolved
}

private static string LoadCFStringSymbol(IntPtr lib, string name)
{
using (SafeCFStringHandle cfString = new SafeCFStringHandle(LoadSymbol(lib, name), false))
{
Debug.Assert(!cfString.IsInvalid);
return Interop.CoreFoundation.CFStringToString(cfString);
}
}

private string GetString(IntPtr key)
{
IntPtr dictValue = CFDictionaryGetValue(_dictionary, key);
if (dictValue != IntPtr.Zero)
{
using (SafeCFStringHandle handle = new SafeCFStringHandle(dictValue, false))
{
return CFStringToString(handle);
}
}
return null;
}

public string ProxyType => GetString(kCFProxyTypeKey);
public string HostName => GetString(kCFProxyHostNameKey);
public string Username => GetString(kCFProxyUsernameKey);
public string Password => GetString(kCFProxyPasswordKey);

public int PortNumber
{
get
{
IntPtr dictValue = CFDictionaryGetValue(_dictionary, kCFProxyPortNumberKey);
if (dictValue != IntPtr.Zero && CFNumberGetValue(dictValue, CFNumberType.kCFNumberIntType, out int value) > 0)
{
return value;
}
return -1;
}
}

public IntPtr AutoConfigurationURL => CFDictionaryGetValue(_dictionary, kCFProxyAutoConfigurationURLKey);
public IntPtr AutoConfigurationJavaScript => CFDictionaryGetValue(_dictionary, kCFProxyAutoConfigurationJavaScriptKey);
}
}
}
5 changes: 5 additions & 0 deletions src/Common/src/Interop/OSX/Interop.CoreFoundation.CFString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ internal SafeCFStringHandle()
{
}

internal SafeCFStringHandle(IntPtr handle, bool ownsHandle)
: base(handle, ownsHandle)
{
}

protected override bool ReleaseHandle()
{
Interop.CoreFoundation.CFRelease(handle);
Expand Down
30 changes: 30 additions & 0 deletions src/Common/src/Interop/OSX/Interop.CoreFoundation.CFUrl.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;

internal static partial class Interop
{
internal static partial class CoreFoundation
{
[DllImport(Libraries.CoreFoundationLibrary)]
private static extern SafeCreateHandle CFURLCreateWithString(
IntPtr allocator,
SafeCreateHandle str,
IntPtr baseUrl);

internal static SafeCreateHandle CFURLCreateWithString(string url)
{
Debug.Assert(url != null);
using (SafeCreateHandle stringHandle = CFStringCreateWithCString(url))
{
return CFURLCreateWithString(IntPtr.Zero, stringHandle, IntPtr.Zero);
}
}
}
}
3 changes: 2 additions & 1 deletion src/Common/src/Interop/OSX/Interop.Libraries.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ internal static partial class Interop
internal static partial class Libraries
{
internal const string CoreFoundationLibrary = "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation";
internal const string CoreServicesLibrary = "/System/Library/Frameworks/CoreServices.framework/CoreServices";
internal const string CoreServicesLibrary = "/System/Library/Frameworks/CoreServices.framework/CoreServices";
internal const string CFNetworkLibrary = "/System/Library/Frameworks/CFNetwork.framework/CFNetwork";
internal const string libproc = "libproc";
internal const string LibSystemCommonCrypto = "/usr/lib/system/libcommonCrypto";
internal const string LibSystemKernel = "/usr/lib/system/libsystem_kernel";
Expand Down
15 changes: 14 additions & 1 deletion src/Common/src/Interop/OSX/Interop.RunLoop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ internal static partial class RunLoop
#endif
internal extern static void CFRunLoopRun();

/// <summary>
/// Runs the current thread’s CFRunLoop object in a particular mode.
/// </summary>
[DllImport(Interop.Libraries.CoreFoundationLibrary)]
internal extern static int CFRunLoopRunInMode(CFStringRef mode, double seconds, int returnAfterSourceHandled);

/// <summary>
/// Notifies a RunLoop to stop and return control to the execution context that called CFRunLoopRun
/// </summary>
Expand Down Expand Up @@ -66,7 +72,14 @@ internal static partial class RunLoop
/// <param name="mode">The run loop mode of rl from which to remove source.</param>
[DllImport(Interop.Libraries.CoreFoundationLibrary)]
internal static extern void CFRunLoopRemoveSource(CFRunLoopRef rl, CFRunLoopSourceRef source, CFStringRef mode);


/// <summary>
/// Invalidates a CFRunLoopSource object, stopping it from ever firing again.
/// </summary>
/// <param name="source">The run loop source to invalidate.</param>
[DllImport(Interop.Libraries.CoreFoundationLibrary)]
internal static extern void CFRunLoopSourceInvalidate(CFRunLoopSourceRef source);

/// <summary>
/// Returns a bool that indicates whether the run loop is waiting for an event.
/// </summary>
Expand Down
44 changes: 43 additions & 1 deletion src/System.Net.Http/src/System.Net.Http.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,6 @@
</ItemGroup>
<!-- SocketsHttpHandler platform parts -->
<ItemGroup Condition=" '$(TargetsUnix)' == 'true' And '$(TargetGroup)' == 'netcoreapp'">
<Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.Unix.cs" />
<Compile Include="System\Net\Http\SocketsHttpHandler\HttpEnvironmentProxy.cs" />
<Compile Include="$(CommonPath)\System\Net\ContextAwareResult.Unix.cs">
<Link>Common\System\Net\ContextAwareResult.Unix.cs</Link>
Expand Down Expand Up @@ -256,6 +255,49 @@
<Link>Common\System\Net\Security\Unix\SafeDeleteNegoContext.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetsUnix)' == 'true' And '$(TargetsOSX)' != 'true' And '$(TargetGroup)' == 'netcoreapp'">
<Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.Unix.cs" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetsOSX)' == 'true' And '$(TargetGroup)' == 'netcoreapp'">
<Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.OSX.cs" />
<Compile Include="System\Net\Http\SocketsHttpHandler\MacProxy.cs" />
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFArray.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFArray.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFData.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFData.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFDictionary.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFDictionary.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFProxy.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFProxy.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFUrl.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFUrl.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFString.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFString.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFNumber.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFString.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.CoreFoundation.CFError.cs">
<Link>Common\Interop\OSX\Interop.CoreFoundation.CFError.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.RunLoop.cs">
<Link>Common\Interop\OSX\Interop.RunLoop.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\OSX\Interop.Libraries.cs">
<Link>Common\Interop\OSX\Interop.Libraries.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Microsoft\Win32\SafeHandles\SafeCreateHandle.OSX.cs">
<Link>Common\Microsoft\Win32\SafeHandles\SafeCreateHandle.OSX.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(TargetGroup)' == 'netcoreapp'">
<Compile Include="System\Net\Http\SocketsHttpHandler\SystemProxyInfo.Windows.cs" />
<Compile Include="System\Net\Http\SocketsHttpHandler\HttpSystemProxy.cs" />
Expand Down
Loading