Remove dedicated UWP builds and code.

This commit is contained in:
Christian Kratky
2019-08-11 22:07:57 +02:00
parent 8ad1fb2871
commit 6d0e2c2022
19 changed files with 26 additions and 783 deletions
@@ -1,196 +0,0 @@
#if WINDOWS_UWP
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Security.Cryptography.Certificates;
using MQTTnet.Channel;
using MQTTnet.Client.Options;
using MQTTnet.Server;
namespace MQTTnet.Implementations
{
public class MqttTcpChannel : IMqttChannel
{
private readonly MqttClientTcpOptions _options;
private readonly int _bufferSize;
private StreamSocket _socket;
private Stream _readStream;
private Stream _writeStream;
public MqttTcpChannel(IMqttClientOptions clientOptions)
{
_options = (MqttClientTcpOptions)clientOptions.ChannelOptions;
_bufferSize = _options.BufferSize;
}
public MqttTcpChannel(StreamSocket socket, X509Certificate2 clientCertificate, IMqttServerOptions serverOptions)
{
_socket = socket ?? throw new ArgumentNullException(nameof(socket));
_bufferSize = serverOptions.DefaultEndpointOptions.BufferSize;
CreateStreams();
IsSecureConnection = socket.Information.ProtectionLevel >= SocketProtectionLevel.Tls12;
ClientCertificate = clientCertificate;
Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort;
}
public static Func<MqttClientTcpOptions, IEnumerable<ChainValidationResult>> CustomIgnorableServerCertificateErrorsResolver { get; set; }
public string Endpoint { get; private set; }
public bool IsSecureConnection { get; }
public X509Certificate2 ClientCertificate { get; }
public async Task ConnectAsync(CancellationToken cancellationToken)
{
if (_socket == null)
{
_socket = new StreamSocket();
_socket.Control.NoDelay = _options.NoDelay;
_socket.Control.KeepAlive = true;
}
if (_options.TlsOptions?.UseTls != true)
{
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString());
}
else
{
_socket.Control.ClientCertificate = LoadCertificate(_options);
foreach (var ignorableChainValidationResult in ResolveIgnorableServerCertificateErrors())
{
_socket.Control.IgnorableServerCertificateErrors.Add(ignorableChainValidationResult);
}
var socketProtectionLevel = SocketProtectionLevel.Tls12;
if (_options.TlsOptions.SslProtocol == SslProtocols.Tls11)
{
socketProtectionLevel = SocketProtectionLevel.Tls11;
}
else if (_options.TlsOptions.SslProtocol == SslProtocols.Tls)
{
socketProtectionLevel = SocketProtectionLevel.Tls10;
}
await _socket.ConnectAsync(new HostName(_options.Server), _options.GetPort().ToString(), socketProtectionLevel);
}
Endpoint = _socket.Information.RemoteAddress + ":" + _socket.Information.RemotePort;
CreateStreams();
}
public Task DisconnectAsync(CancellationToken cancellationToken)
{
Dispose();
return Task.FromResult(0);
}
public Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return _readStream.ReadAsync(buffer, offset, count, cancellationToken);
}
public Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
// In the write method only the internal buffer will be filled. So here is no
// async/await required. The real network transmit is done when calling the
// Flush method.
_writeStream.Write(buffer, offset, count);
return _writeStream.FlushAsync(cancellationToken);
}
public void Dispose()
{
TryDispose(_readStream, () => _readStream = null);
TryDispose(_writeStream, () => _writeStream = null);
TryDispose(_socket, () => _socket = null);
}
private static Certificate LoadCertificate(IMqttClientChannelOptions options)
{
if (options.TlsOptions.Certificates == null || !options.TlsOptions.Certificates.Any())
{
return null;
}
if (options.TlsOptions.Certificates.Count > 1)
{
throw new NotSupportedException("Only one client certificate is supported for UWP.");
}
return new Certificate(options.TlsOptions.Certificates.First().AsBuffer());
}
private IEnumerable<ChainValidationResult> ResolveIgnorableServerCertificateErrors()
{
if (CustomIgnorableServerCertificateErrorsResolver != null)
{
return CustomIgnorableServerCertificateErrorsResolver(_options);
}
var result = new List<ChainValidationResult>();
if (_options.TlsOptions.IgnoreCertificateRevocationErrors)
{
result.Add(ChainValidationResult.RevocationInformationMissing);
//_socket.Control.IgnorableServerCertificateErrors.Add(ChainValidationResult.Revoked); Not supported.
result.Add(ChainValidationResult.RevocationFailure);
}
if (_options.TlsOptions.IgnoreCertificateChainErrors)
{
result.Add(ChainValidationResult.IncompleteChain);
}
if (_options.TlsOptions.AllowUntrustedCertificates)
{
result.Add(ChainValidationResult.Untrusted);
}
return result;
}
private void CreateStreams()
{
// Attention! Do not set the buffer for the read method. This will
// limit the internal buffer and the read operation will hang forever
// if more data than the buffer size was received.
_readStream = _socket.InputStream.AsStreamForRead();
_writeStream = _socket.OutputStream.AsStreamForWrite(_bufferSize);
}
private static void TryDispose(IDisposable disposable, Action afterDispose)
{
try
{
disposable?.Dispose();
}
catch (ObjectDisposedException)
{
}
catch (NullReferenceException)
{
}
finally
{
afterDispose();
}
}
}
}
#endif
@@ -1,4 +1,3 @@
#if !WINDOWS_UWP
using System;
using System.Net.Security;
using System.Net.Sockets;
@@ -72,7 +71,7 @@ namespace MQTTnet.Implementations
// Workaround for: workaround for https://github.com/dotnet/corefx/issues/24430
using (cancellationToken.Register(() => socket.Dispose()))
{
#if NET452 || NET461
#if NET452
await Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, _options.Server, _options.GetPort(), null).ConfigureAwait(false);
#else
await socket.ConnectAsync(_options.Server, _options.GetPort()).ConfigureAwait(false);
@@ -220,5 +219,4 @@ namespace MQTTnet.Implementations
return certificates;
}
}
}
#endif
}
@@ -1,122 +0,0 @@
#if WINDOWS_UWP
using Windows.Networking.Sockets;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
using MQTTnet.Server;
using System;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
namespace MQTTnet.Implementations
{
public class MqttTcpServerAdapter : IMqttServerAdapter
{
private readonly IMqttNetChildLogger _logger;
private IMqttServerOptions _options;
private StreamSocketListener _listener;
public MqttTcpServerAdapter(IMqttNetChildLogger logger)
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter));
}
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
public async Task StartAsync(IMqttServerOptions options)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
if (_listener != null) throw new InvalidOperationException("Server is already started.");
if (options.DefaultEndpointOptions.IsEnabled)
{
_listener = new StreamSocketListener();
// This also affects the client sockets.
_listener.Control.NoDelay = options.DefaultEndpointOptions.NoDelay;
_listener.Control.KeepAlive = true;
_listener.Control.QualityOfService = SocketQualityOfService.LowLatency;
_listener.ConnectionReceived += OnConnectionReceivedAsync;
await _listener.BindServiceNameAsync(options.DefaultEndpointOptions.Port.ToString(), SocketProtectionLevel.PlainSocket);
}
if (options.TlsEndpointOptions.IsEnabled)
{
throw new NotSupportedException("TLS servers are not supported for UWP apps.");
}
}
public Task StopAsync()
{
if (_listener != null)
{
_listener.ConnectionReceived -= OnConnectionReceivedAsync;
}
return Task.FromResult(0);
}
public void Dispose()
{
_listener?.Dispose();
_listener = null;
}
private async void OnConnectionReceivedAsync(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
var clientHandler = ClientHandler;
if (clientHandler != null)
{
X509Certificate2 clientCertificate = null;
if (args.Socket.Control.ClientCertificate != null)
{
try
{
clientCertificate = new X509Certificate2(args.Socket.Control.ClientCertificate.GetCertificateBlob().ToArray());
}
catch (Exception exception)
{
_logger.Warning(exception, "Unable to convert UWP certificate to X509Certificate2.");
}
}
using (var clientAdapter = new MqttChannelAdapter(new MqttTcpChannel(args.Socket, clientCertificate, _options), new MqttPacketFormatterAdapter(), _logger))
{
await clientHandler(clientAdapter).ConfigureAwait(false);
}
}
}
catch (Exception exception)
{
if (exception is ObjectDisposedException)
{
// It can happen that the listener socket is accessed after the cancellation token is already set and the listener socket is disposed.
return;
}
_logger.Error(exception, "Error while handling client connection.");
}
finally
{
try
{
args.Socket.Dispose();
}
catch (Exception exception)
{
_logger.Error(exception, "Error while cleaning up client connection");
}
}
}
}
}
#endif
@@ -1,5 +1,4 @@
#if !WINDOWS_UWP
using System;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
@@ -128,5 +127,4 @@ namespace MQTTnet.Implementations
return clientHandler(channelAdapter);
}
}
}
#endif
}
@@ -1,5 +1,4 @@
#if !WINDOWS_UWP
using System;
using System;
using System.IO;
using System.Net;
using System.Net.Security;
@@ -96,7 +95,7 @@ namespace MQTTnet.Implementations
{
_socket?.Dispose();
#if NETSTANDARD1_3 || NETSTANDARD2_0 || NET461 || NET472
#if NETSTANDARD1_3 || NETSTANDARD2_0
_tlsCertificate?.Dispose();
#endif
}
@@ -107,7 +106,7 @@ namespace MQTTnet.Implementations
{
try
{
#if NET452 || NET461
#if NET452
var clientSocket = await Task.Factory.FromAsync(_socket.BeginAccept, _socket.EndAccept, null).ConfigureAwait(false);
#else
var clientSocket = await _socket.AcceptAsync().ConfigureAwait(false);
@@ -224,5 +223,4 @@ namespace MQTTnet.Implementations
}
}
}
}
#endif
}
@@ -161,10 +161,8 @@ namespace MQTTnet.Implementations
return null;
}
#if WINDOWS_UWP
throw new NotSupportedException("Proxies are not supported in UWP.");
#elif NETSTANDARD1_3
throw new NotSupportedException("Proxies are not supported in netstandard 1.3.");
#if NETSTANDARD1_3
throw new NotSupportedException("Proxies are not supported in netstandard1.3.");
#else
var proxyUri = new Uri(_options.ProxyOptions.Address);