diff --git a/WebDAVClient/Client.cs b/WebDAVClient/Client.cs index 5768479..18bda6b 100644 --- a/WebDAVClient/Client.cs +++ b/WebDAVClient/Client.cs @@ -6,7 +6,7 @@ using System.Net.Http.Headers; using System.Net.Security; using System.Text; -using System.Threading; +using System.Threading; using System.Threading.Tasks; using WebDAVClient.Helpers; using WebDAVClient.HttpClient; @@ -45,12 +45,12 @@ public class Client : IClient ""; private static readonly byte[] s_propFindRequestContentBytes = Encoding.UTF8.GetBytes(c_propFindRequestContent); - private IHttpClientWrapper m_httpClientWrapper; - private readonly bool m_shouldDispose; + private IHttpClientWrapper m_httpClientWrapper; + private readonly bool m_shouldDispose; private string m_server; private string m_basePath = "/"; private string m_encodedBasePath; - private bool m_disposedValue; + private bool m_disposedValue; #region WebDAV connection parameters @@ -107,13 +107,14 @@ public string BasePath /// Specify the certificates validation logic /// public RemoteCertificateValidationCallback ServerCertificateValidationCallback { get; set; } + #endregion public Client(NetworkCredential credential = null, TimeSpan? uploadTimeout = null, IWebProxy proxy = null) { var handler = new HttpClientHandler(); if (proxy != null && handler.SupportsProxy) - { + { handler.Proxy = proxy; } if (handler.SupportsAutomaticDecompression) @@ -129,6 +130,7 @@ public Client(NetworkCredential credential = null, TimeSpan? uploadTimeout = nul { handler.UseDefaultCredentials = true; } + handler.ServerCertificateCustomValidationCallback = ServerCertificateValidation; var client = new System.Net.Http.HttpClient(handler, disposeHandler: true); client.DefaultRequestHeaders.ExpectContinue = false; @@ -228,7 +230,7 @@ public async Task> List(string path = "/", int? depth = 1, Can } finally { - response?.Dispose(); + response?.Dispose(); } } @@ -260,8 +262,8 @@ public async Task GetFile(string path = "/", CancellationToken cancellatio public Task Download(string remoteFilePath, CancellationToken cancellationToken = default) { var headers = new Dictionary(1 + (CustomHeaders?.Count ?? 0)) - { - { "translate", "f" } + { + { "translate", "f" } }; if (CustomHeaders != null) { @@ -527,11 +529,11 @@ private async Task Delete(Uri listUri, CancellationToken cancellationToken = def private async Task Get(Uri listUri, CancellationToken cancellationToken = default) { // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4 - IDictionary headers = new Dictionary(1 + (CustomHeaders?.Count ?? 0)) - { - { "Depth", "0" } - }; - + IDictionary headers = new Dictionary(1 + (CustomHeaders?.Count ?? 0)) + { + { "Depth", "0" } + }; + if (CustomHeaders != null) { foreach (var keyValuePair in CustomHeaders) @@ -566,7 +568,7 @@ private async Task Get(Uri listUri, CancellationToken cancellationToken = } finally { - response?.Dispose(); + response?.Dispose(); } } @@ -574,11 +576,11 @@ private async Task Move(Uri srcUri, Uri dstUri, CancellationToken cancella { const string requestContent = "MOVE"; - IDictionary headers = new Dictionary(1 + (CustomHeaders?.Count ?? 0)) - { - { "Destination", dstUri.ToString() } - }; - + IDictionary headers = new Dictionary(1 + (CustomHeaders?.Count ?? 0)) + { + { "Destination", dstUri.ToString() } + }; + if (CustomHeaders != null) { foreach (var keyValuePair in CustomHeaders) @@ -602,9 +604,9 @@ private async Task Copy(Uri srcUri, Uri dstUri, CancellationToken cancella { const string requestContent = "COPY"; - IDictionary headers = new Dictionary(1 + (CustomHeaders?.Count ?? 0)) - { - { "Destination", dstUri.ToString() } + IDictionary headers = new Dictionary(1 + (CustomHeaders?.Count ?? 0)) + { + { "Destination", dstUri.ToString() } }; if (CustomHeaders != null) @@ -741,9 +743,9 @@ private async Task GetServerUrl(string path, bool appendTrailingSlas { Path = m_basePath }; - if (Port != null) + if (Port != null) { - baseUri.Port = (int)Port; + baseUri.Port = (int)Port; } var root = await Get(baseUri.Uri).ConfigureAwait(false); @@ -762,11 +764,11 @@ private async Task GetServerUrl(string path, bool appendTrailingSlas // Otherwise, use the resolved base path relatively to the server var baseUri = new UriBuilder(m_server) { - Path = m_encodedBasePath + Path = m_encodedBasePath }; - if (Port != null) + if (Port != null) { - baseUri.Port = (int)Port; + baseUri.Port = (int)Port; } return baseUri; } @@ -794,7 +796,7 @@ private async Task GetServerUrl(string path, bool appendTrailingSlas baseUri = new UriBuilder(m_server); if (Port!= null) { - baseUri.Port = (int)Port; + baseUri.Port = (int)Port; } // Ensure we don't add the base path twice @@ -807,8 +809,8 @@ private async Task GetServerUrl(string path, bool appendTrailingSlas finalPath = finalPath.TrimEnd('/') + "/"; baseUri.Path = finalPath; - } - + } + return baseUri; } } @@ -819,43 +821,43 @@ private async Task GetServerUrl(string path, bool appendTrailingSlas #region WebDAV Connection Helpers - public bool ServerCertificateValidation(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors) + public bool ServerCertificateValidation(HttpRequestMessage requestMessage, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (ServerCertificateValidationCallback != null) { - return ServerCertificateValidationCallback(sender, certification, chain, sslPolicyErrors); + return ServerCertificateValidationCallback(requestMessage, certification, chain, sslPolicyErrors); } - return false; + return sslPolicyErrors == SslPolicyErrors.None; } #endregion #region IDisposable methods - protected virtual void Dispose(bool disposing) - { - if (!m_disposedValue) - { - if (disposing) - { - if (m_shouldDispose) - { - if (m_httpClientWrapper is IDisposable httpClientWrapperDisposable) - { - httpClientWrapperDisposable.Dispose(); - m_httpClientWrapper = null; - } - } - } - - m_disposedValue = true; - } - } - - public void Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); - } + protected virtual void Dispose(bool disposing) + { + if (!m_disposedValue) + { + if (disposing) + { + if (m_shouldDispose) + { + if (m_httpClientWrapper is IDisposable httpClientWrapperDisposable) + { + httpClientWrapperDisposable.Dispose(); + m_httpClientWrapper = null; + } + } + } + + m_disposedValue = true; + } + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } #endregion } } diff --git a/WebDAVClient/IClient.cs b/WebDAVClient/IClient.cs index 7b4b12d..328c791 100644 --- a/WebDAVClient/IClient.cs +++ b/WebDAVClient/IClient.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Net.Security; using System.Threading; using System.Threading.Tasks; using WebDAVClient.Model; @@ -39,6 +40,11 @@ public interface IClient : IDisposable /// ICollection> CustomHeaders { get; set; } + /// + /// Specify the certificates validation logic + /// + RemoteCertificateValidationCallback ServerCertificateValidationCallback { get; set; } + /// /// List all files present on the server. ///