mirror of
https://gitee.com/csharpui/CPF.git
synced 2026-01-09 18:04:50 +08:00
初始化
This commit is contained in:
131
CPF.Mac/Mac/CoreServices/CFHTTPAuthentication.cs
Normal file
131
CPF.Mac/Mac/CoreServices/CFHTTPAuthentication.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using CPF.Mac.CoreFoundation;
|
||||
using CPF.Mac.ObjCRuntime;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace CPF.Mac.CoreServices
|
||||
{
|
||||
public class CFHTTPAuthentication : CFType, INativeObject, IDisposable
|
||||
{
|
||||
internal IntPtr handle;
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckHandle();
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValid => CFHTTPAuthenticationIsValid(Handle, IntPtr.Zero);
|
||||
|
||||
public bool RequiresAccountDomain => CFHTTPAuthenticationRequiresAccountDomain(Handle);
|
||||
|
||||
public bool RequiresOrderedRequests => CFHTTPAuthenticationRequiresOrderedRequests(Handle);
|
||||
|
||||
public bool RequiresUserNameAndPassword => CFHTTPAuthenticationRequiresUserNameAndPassword(Handle);
|
||||
|
||||
internal CFHTTPAuthentication(IntPtr handle)
|
||||
: this(handle, owns: false)
|
||||
{
|
||||
}
|
||||
|
||||
internal CFHTTPAuthentication(IntPtr handle, bool owns)
|
||||
{
|
||||
if (!owns)
|
||||
{
|
||||
CFObject.CFRetain(handle);
|
||||
}
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork", EntryPoint = "CFHTTPAuthenticationGetTypeID")]
|
||||
public static extern int GetTypeID();
|
||||
|
||||
~CFHTTPAuthentication()
|
||||
{
|
||||
Dispose(disposing: false);
|
||||
}
|
||||
|
||||
protected void CheckHandle()
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType().Name);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
CFObject.CFRelease(handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHTTPAuthenticationCreateFromResponse(IntPtr allocator, IntPtr response);
|
||||
|
||||
public static CFHTTPAuthentication CreateFromResponse(CFHTTPMessage response)
|
||||
{
|
||||
if (response.IsRequest)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
IntPtr value = CFHTTPAuthenticationCreateFromResponse(IntPtr.Zero, response.Handle);
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new CFHTTPAuthentication(value);
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPAuthenticationIsValid(IntPtr handle, IntPtr error);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPAuthenticationAppliesToRequest(IntPtr handle, IntPtr request);
|
||||
|
||||
public bool AppliesToRequest(CFHTTPMessage request)
|
||||
{
|
||||
if (!request.IsRequest)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
return CFHTTPAuthenticationAppliesToRequest(Handle, request.Handle);
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPAuthenticationRequiresAccountDomain(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPAuthenticationRequiresOrderedRequests(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPAuthenticationRequiresUserNameAndPassword(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHTTPAuthenticationCopyMethod(IntPtr handle);
|
||||
|
||||
public string GetMethod()
|
||||
{
|
||||
IntPtr value = CFHTTPAuthenticationCopyMethod(Handle);
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
using (CFString x = new CFString(value))
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
439
CPF.Mac/Mac/CoreServices/CFHTTPMessage.cs
Normal file
439
CPF.Mac/Mac/CoreServices/CFHTTPMessage.cs
Normal file
@@ -0,0 +1,439 @@
|
||||
using CPF.Mac.CoreFoundation;
|
||||
using CPF.Mac.Foundation;
|
||||
using CPF.Mac.ObjCRuntime;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace CPF.Mac.CoreServices
|
||||
{
|
||||
public class CFHTTPMessage : CFType, INativeObject, IDisposable
|
||||
{
|
||||
private struct CFStreamError
|
||||
{
|
||||
public int domain;
|
||||
|
||||
public int code;
|
||||
}
|
||||
|
||||
private enum ErrorHTTPAuthentication
|
||||
{
|
||||
TypeUnsupported = -1000,
|
||||
BadUserName = -1001,
|
||||
BadPassword = -1002
|
||||
}
|
||||
|
||||
public enum AuthenticationScheme
|
||||
{
|
||||
Default,
|
||||
Basic,
|
||||
Negotiate,
|
||||
NTLM,
|
||||
Digest
|
||||
}
|
||||
|
||||
internal IntPtr handle;
|
||||
|
||||
private static readonly NSString _HTTPVersion1_0;
|
||||
|
||||
private static readonly NSString _HTTPVersion1_1;
|
||||
|
||||
private static readonly NSString _AuthenticationSchemeBasic;
|
||||
|
||||
private static readonly NSString _AuthenticationSchemeNegotiate;
|
||||
|
||||
private static readonly NSString _AuthenticationSchemeNTLM;
|
||||
|
||||
private static readonly NSString _AuthenticationSchemeDigest;
|
||||
|
||||
private static readonly NSString _AuthenticationUsername;
|
||||
|
||||
private static readonly NSString _AuthenticationPassword;
|
||||
|
||||
private static readonly NSString _AuthenticationAccountDomain;
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckHandle();
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRequest
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckHandle();
|
||||
return CFHTTPMessageIsRequest(Handle);
|
||||
}
|
||||
}
|
||||
|
||||
public CFIndex ResponseStatusCode
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsRequest)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
return CFHTTPMessageGetResponseStatusCode(Handle);
|
||||
}
|
||||
}
|
||||
|
||||
public string ResponseStatusLine
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsRequest)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
IntPtr value = CFHTTPMessageCopyResponseStatusLine(Handle);
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
using (NSString nSString = new NSString(value))
|
||||
{
|
||||
return nSString.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Version Version
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckHandle();
|
||||
IntPtr intPtr = CFHTTPMessageCopyVersion(handle);
|
||||
try
|
||||
{
|
||||
if (intPtr.Equals(_HTTPVersion1_0.Handle))
|
||||
{
|
||||
return HttpVersion.Version10;
|
||||
}
|
||||
return HttpVersion.Version11;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (intPtr != IntPtr.Zero)
|
||||
{
|
||||
CFObject.CFRelease(intPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsHeaderComplete
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckHandle();
|
||||
return CFHTTPMessageIsHeaderComplete(Handle);
|
||||
}
|
||||
}
|
||||
|
||||
internal CFHTTPMessage(IntPtr handle)
|
||||
: this(handle, owns: false)
|
||||
{
|
||||
}
|
||||
|
||||
internal CFHTTPMessage(IntPtr handle, bool owns)
|
||||
{
|
||||
if (!owns)
|
||||
{
|
||||
CFObject.CFRetain(handle);
|
||||
}
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
static CFHTTPMessage()
|
||||
{
|
||||
IntPtr value = Dlfcn.dlopen("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork", 0);
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
try
|
||||
{
|
||||
_HTTPVersion1_0 = GetStringConstant(value, "kCFHTTPVersion1_0");
|
||||
_HTTPVersion1_1 = GetStringConstant(value, "kCFHTTPVersion1_1");
|
||||
_AuthenticationSchemeBasic = GetStringConstant(value, "kCFHTTPAuthenticationSchemeBasic");
|
||||
_AuthenticationSchemeNegotiate = GetStringConstant(value, "kCFHTTPAuthenticationSchemeNegotiate");
|
||||
_AuthenticationSchemeNTLM = GetStringConstant(value, "kCFHTTPAuthenticationSchemeNTLM");
|
||||
_AuthenticationSchemeDigest = GetStringConstant(value, "kCFHTTPAuthenticationSchemeDigest");
|
||||
_AuthenticationUsername = GetStringConstant(value, "kCFHTTPAuthenticationUsername");
|
||||
_AuthenticationPassword = GetStringConstant(value, "kCFHTTPAuthenticationPassword");
|
||||
_AuthenticationAccountDomain = GetStringConstant(value, "kCFHTTPAuthenticationAccountDomain");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dlfcn.dlclose(value);
|
||||
}
|
||||
}
|
||||
|
||||
private static NSString GetStringConstant(IntPtr handle, string name)
|
||||
{
|
||||
NSString stringConstant = Dlfcn.GetStringConstant(handle, name);
|
||||
if (stringConstant == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot get '{name}' property.");
|
||||
}
|
||||
return stringConstant;
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork", EntryPoint = "CFHTTPMessageGetTypeID")]
|
||||
public static extern int GetTypeID();
|
||||
|
||||
~CFHTTPMessage()
|
||||
{
|
||||
Dispose(disposing: false);
|
||||
}
|
||||
|
||||
protected void CheckHandle()
|
||||
{
|
||||
if (handle == IntPtr.Zero)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType().Name);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
CFObject.CFRelease(handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
private static IntPtr GetVersion(Version version)
|
||||
{
|
||||
if (version == null || version.Equals(HttpVersion.Version11))
|
||||
{
|
||||
return _HTTPVersion1_1.Handle;
|
||||
}
|
||||
if (version.Equals(HttpVersion.Version10))
|
||||
{
|
||||
return _HTTPVersion1_0.Handle;
|
||||
}
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHTTPMessageCreateEmpty(IntPtr allocator, bool isRequest);
|
||||
|
||||
public static CFHTTPMessage CreateEmpty(bool request)
|
||||
{
|
||||
IntPtr value = CFHTTPMessageCreateEmpty(IntPtr.Zero, request);
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new CFHTTPMessage(value);
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHTTPMessageCreateRequest(IntPtr allocator, IntPtr requestMethod, IntPtr url, IntPtr httpVersion);
|
||||
|
||||
public static CFHTTPMessage CreateRequest(CFUrl url, NSString method, Version version)
|
||||
{
|
||||
IntPtr value = CFHTTPMessageCreateRequest(IntPtr.Zero, method.Handle, url.Handle, GetVersion(version));
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new CFHTTPMessage(value);
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPMessageIsRequest(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern CFIndex CFHTTPMessageGetResponseStatusCode(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHTTPMessageCopyResponseStatusLine(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHTTPMessageCopyVersion(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPMessageIsHeaderComplete(IntPtr handle);
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPMessageAppendBytes(IntPtr message, ref byte[] newBytes, CFIndex numBytes);
|
||||
|
||||
public bool AppendBytes(byte[] bytes)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
throw new ArgumentNullException("bytes");
|
||||
}
|
||||
return AppendBytes(bytes, bytes.Length);
|
||||
}
|
||||
|
||||
public bool AppendBytes(byte[] bytes, int count)
|
||||
{
|
||||
if (bytes == null)
|
||||
{
|
||||
throw new ArgumentNullException("bytes");
|
||||
}
|
||||
return CFHTTPMessageAppendBytes(Handle, ref bytes, count);
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHTTPMessageCopyAllHeaderFields(IntPtr handle);
|
||||
|
||||
public NSDictionary GetAllHeaderFields()
|
||||
{
|
||||
CheckHandle();
|
||||
IntPtr value = CFHTTPMessageCopyAllHeaderFields(handle);
|
||||
if (value == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new NSDictionary(value);
|
||||
}
|
||||
|
||||
private InvalidOperationException GetException(ErrorHTTPAuthentication code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case ErrorHTTPAuthentication.BadUserName:
|
||||
throw new InvalidOperationException("Bad username.");
|
||||
case ErrorHTTPAuthentication.BadPassword:
|
||||
throw new InvalidOperationException("Bad password.");
|
||||
case ErrorHTTPAuthentication.TypeUnsupported:
|
||||
throw new InvalidOperationException("Authentication type not supported.");
|
||||
default:
|
||||
throw new InvalidOperationException("Unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPMessageApplyCredentials(IntPtr request, IntPtr auth, IntPtr user, IntPtr pass, out CFStreamError error);
|
||||
|
||||
public void ApplyCredentials(CFHTTPAuthentication auth, string userName, string password, string domain = null)
|
||||
{
|
||||
if (auth.RequiresAccountDomain)
|
||||
{
|
||||
ApplyCredentialDictionary(auth, userName, password, domain);
|
||||
return;
|
||||
}
|
||||
CFString cFString = new CFString(userName);
|
||||
CFString cFString2 = new CFString(password);
|
||||
try
|
||||
{
|
||||
if (!CFHTTPMessageApplyCredentials(Handle, auth.Handle, cFString.Handle, cFString2.Handle, out CFStreamError error))
|
||||
{
|
||||
throw GetException((ErrorHTTPAuthentication)error.code);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
cFString.Dispose();
|
||||
cFString2.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal static IntPtr GetAuthScheme(AuthenticationScheme scheme)
|
||||
{
|
||||
switch (scheme)
|
||||
{
|
||||
case AuthenticationScheme.Default:
|
||||
return IntPtr.Zero;
|
||||
case AuthenticationScheme.Basic:
|
||||
return _AuthenticationSchemeBasic.Handle;
|
||||
case AuthenticationScheme.Negotiate:
|
||||
return _AuthenticationSchemeNegotiate.Handle;
|
||||
case AuthenticationScheme.NTLM:
|
||||
return _AuthenticationSchemeNTLM.Handle;
|
||||
case AuthenticationScheme.Digest:
|
||||
return _AuthenticationSchemeDigest.Handle;
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPMessageAddAuthentication(IntPtr request, IntPtr response, IntPtr username, IntPtr password, IntPtr scheme, bool forProxy);
|
||||
|
||||
public bool AddAuthentication(CFHTTPMessage failureResponse, NSString username, NSString password, AuthenticationScheme scheme, bool forProxy)
|
||||
{
|
||||
return CFHTTPMessageAddAuthentication(Handle, failureResponse.Handle, username.Handle, password.Handle, GetAuthScheme(scheme), forProxy);
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern bool CFHTTPMessageApplyCredentialDictionary(IntPtr request, IntPtr auth, IntPtr dict, out CFStreamError error);
|
||||
|
||||
public void ApplyCredentialDictionary(CFHTTPAuthentication auth, string userName, string password, string domain = null)
|
||||
{
|
||||
NSString[] array = new NSString[3];
|
||||
CFString[] array2 = new CFString[3];
|
||||
array[0] = _AuthenticationUsername;
|
||||
array[1] = _AuthenticationPassword;
|
||||
array[2] = _AuthenticationAccountDomain;
|
||||
array2[0] = userName;
|
||||
array2[1] = password;
|
||||
array2[2] = ((domain != null) ? ((CFString)domain) : null);
|
||||
CFDictionary cFDictionary = CFDictionary.FromObjectsAndKeys(array2, array);
|
||||
try
|
||||
{
|
||||
if (!CFHTTPMessageApplyCredentialDictionary(Handle, auth.Handle, cFDictionary.Handle, out CFStreamError error))
|
||||
{
|
||||
throw GetException((ErrorHTTPAuthentication)error.code);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
cFDictionary.Dispose();
|
||||
array2[0].Dispose();
|
||||
array2[1].Dispose();
|
||||
if (array2[2] != null)
|
||||
{
|
||||
array2[2].Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern void CFHTTPMessageSetHeaderFieldValue(IntPtr message, IntPtr headerField, IntPtr value);
|
||||
|
||||
public void SetHeaderFieldValue(string name, string value)
|
||||
{
|
||||
NSString nSString = (NSString)name;
|
||||
NSString nSString2 = (value != null) ? ((NSString)value) : null;
|
||||
IntPtr value2 = (nSString2 != null) ? nSString2.Handle : IntPtr.Zero;
|
||||
CFHTTPMessageSetHeaderFieldValue(Handle, nSString.Handle, value2);
|
||||
nSString.Dispose();
|
||||
if (nSString2 != null)
|
||||
{
|
||||
nSString2.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern void CFHTTPMessageSetBody(IntPtr message, IntPtr data);
|
||||
|
||||
internal void SetBody(CFData data)
|
||||
{
|
||||
CFHTTPMessageSetBody(Handle, data.Handle);
|
||||
}
|
||||
|
||||
public void SetBody(byte[] buffer)
|
||||
{
|
||||
using (CFDataBuffer cFDataBuffer = new CFDataBuffer(buffer))
|
||||
{
|
||||
CFHTTPMessageSetBody(Handle, cFDataBuffer.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
184
CPF.Mac/Mac/CoreServices/CFHTTPStream.cs
Normal file
184
CPF.Mac/Mac/CoreServices/CFHTTPStream.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using CPF.Mac.CoreFoundation;
|
||||
using CPF.Mac.Foundation;
|
||||
using CPF.Mac.ObjCRuntime;
|
||||
using System;
|
||||
|
||||
namespace CPF.Mac.CoreServices
|
||||
{
|
||||
public class CFHTTPStream : CFReadStream
|
||||
{
|
||||
private static readonly NSString _AttemptPersistentConnection;
|
||||
|
||||
private static readonly NSString _FinalURL;
|
||||
|
||||
private static readonly NSString _FinalRequest;
|
||||
|
||||
private static readonly NSString _Proxy;
|
||||
|
||||
private static readonly NSString _RequestBytesWrittenCount;
|
||||
|
||||
private static readonly NSString _ResponseHeader;
|
||||
|
||||
private static readonly NSString _ShouldAutoredirect;
|
||||
|
||||
public CFUrl FinalURL
|
||||
{
|
||||
get
|
||||
{
|
||||
IntPtr property = GetProperty(_FinalURL);
|
||||
if (property == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (CFType.GetTypeID(property) != CFUrl.GetTypeID())
|
||||
{
|
||||
CFObject.CFRelease(property);
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
return new CFUrl(property);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AttemptPersistentConnection
|
||||
{
|
||||
get
|
||||
{
|
||||
IntPtr property = GetProperty(_AttemptPersistentConnection);
|
||||
if (property == IntPtr.Zero)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (property == CFBoolean.False.Handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (property == CFBoolean.True.Handle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(_AttemptPersistentConnection, CFBoolean.FromBoolean(value));
|
||||
}
|
||||
}
|
||||
|
||||
public int RequestBytesWrittenCount
|
||||
{
|
||||
get
|
||||
{
|
||||
IntPtr property = GetProperty(_RequestBytesWrittenCount);
|
||||
if (property == IntPtr.Zero)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
using (NSNumber nSNumber = new NSNumber(property))
|
||||
{
|
||||
return nSNumber.Int32Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldAutoredirect
|
||||
{
|
||||
get
|
||||
{
|
||||
IntPtr property = GetProperty(_ShouldAutoredirect);
|
||||
if (property == IntPtr.Zero)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (property == CFBoolean.False.Handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (property == CFBoolean.True.Handle)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
set
|
||||
{
|
||||
SetProperty(_ShouldAutoredirect, CFBoolean.FromBoolean(value));
|
||||
}
|
||||
}
|
||||
|
||||
internal CFDictionary Proxy
|
||||
{
|
||||
set
|
||||
{
|
||||
SetProperty(_Proxy, value);
|
||||
}
|
||||
}
|
||||
|
||||
static CFHTTPStream()
|
||||
{
|
||||
IntPtr intPtr = Dlfcn.dlopen("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork", 0);
|
||||
if (intPtr == IntPtr.Zero)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
try
|
||||
{
|
||||
_AttemptPersistentConnection = GetStringConstant(intPtr, "kCFStreamPropertyHTTPAttemptPersistentConnection");
|
||||
_FinalURL = GetStringConstant(intPtr, "kCFStreamPropertyHTTPFinalURL");
|
||||
_FinalRequest = GetStringConstant(intPtr, "kCFStreamPropertyHTTPFinalRequest");
|
||||
_Proxy = GetStringConstant(intPtr, "kCFStreamPropertyHTTPProxy");
|
||||
_RequestBytesWrittenCount = GetStringConstant(intPtr, "kCFStreamPropertyHTTPRequestBytesWrittenCount");
|
||||
_ResponseHeader = GetStringConstant(intPtr, "kCFStreamPropertyHTTPResponseHeader");
|
||||
_ShouldAutoredirect = GetStringConstant(intPtr, "kCFStreamPropertyHTTPShouldAutoredirect");
|
||||
}
|
||||
finally
|
||||
{
|
||||
Dlfcn.dlclose(intPtr);
|
||||
}
|
||||
}
|
||||
|
||||
private static NSString GetStringConstant(IntPtr handle, string name)
|
||||
{
|
||||
NSString stringConstant = Dlfcn.GetStringConstant(handle, name);
|
||||
if (stringConstant == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot get '{name}' property.");
|
||||
}
|
||||
return stringConstant;
|
||||
}
|
||||
|
||||
internal CFHTTPStream(IntPtr handle)
|
||||
: base(handle)
|
||||
{
|
||||
}
|
||||
|
||||
public CFHTTPMessage GetFinalRequest()
|
||||
{
|
||||
IntPtr property = GetProperty(_FinalRequest);
|
||||
if (property == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (CFType.GetTypeID(property) != CFHTTPMessage.GetTypeID())
|
||||
{
|
||||
CFObject.CFRelease(property);
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
return new CFHTTPMessage(property);
|
||||
}
|
||||
|
||||
public CFHTTPMessage GetResponseHeader()
|
||||
{
|
||||
IntPtr property = GetProperty(_ResponseHeader);
|
||||
if (property == IntPtr.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (CFType.GetTypeID(property) != CFHTTPMessage.GetTypeID())
|
||||
{
|
||||
CFObject.CFRelease(property);
|
||||
throw new InvalidCastException();
|
||||
}
|
||||
return new CFHTTPMessage(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
48
CPF.Mac/Mac/CoreServices/CFHost.cs
Normal file
48
CPF.Mac/Mac/CoreServices/CFHost.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using CPF.Mac.CoreFoundation;
|
||||
using CPF.Mac.ObjCRuntime;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace CPF.Mac.CoreServices
|
||||
{
|
||||
internal class CFHost : INativeObject, IDisposable
|
||||
{
|
||||
internal IntPtr handle;
|
||||
|
||||
public IntPtr Handle => handle;
|
||||
|
||||
private CFHost(IntPtr handle)
|
||||
{
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
~CFHost()
|
||||
{
|
||||
Dispose(disposing: false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
CFObject.CFRelease(handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("/System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/CFNetwork")]
|
||||
private static extern IntPtr CFHostCreateWithName(IntPtr allocator, IntPtr name);
|
||||
|
||||
public static CFHost Create(string name)
|
||||
{
|
||||
CFString cFString = new CFString(name);
|
||||
return new CFHost(CFHostCreateWithName(IntPtr.Zero, cFString.Handle));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user