wasDAVClient

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ HEAD  →  ?path2? @ 1
File deleted
/wasDAVClient/Constants.cs
/wasDAVClient/Client.cs
@@ -1,11 +1,4 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Originally based on: WebDAV .NET client by Sergey Kazantsev
 
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -19,8 +12,13 @@
 
namespace wasDAVClient
{
public class Client : IClient, IDisposable
public class Client : IClient
{
private static readonly HttpMethod PropFind = new HttpMethod("PROPFIND");
private static readonly HttpMethod MoveMethod = new HttpMethod("MOVE");
 
private static readonly HttpMethod MkCol = new HttpMethod(WebRequestMethods.Http.MkCol);
 
private const int HttpStatusCode_MultiStatus = 207;
 
// http://webdav.org/specs/rfc4918.html#METHOD_PROPFIND
@@ -40,60 +38,44 @@
//" </prop> " +
"</propfind>";
 
private static readonly HttpMethod PropFind = new HttpMethod("PROPFIND");
private static readonly HttpMethod MoveMethod = new HttpMethod("MOVE");
 
private static readonly HttpMethod MkCol = new HttpMethod(WebRequestMethods.Http.MkCol);
 
private static readonly string AssemblyVersion = typeof(IClient).Assembly.GetName().Version.ToString();
 
private readonly HttpClient _client;
private readonly HttpClient _uploadClient;
private string _server;
private string _basePath = "/";
 
private string _encodedBasePath;
private string _server;
 
public Client(ICredentials credential = null)
{
var handler = new HttpClientHandler();
 
if (handler.SupportsProxy)
handler.Proxy = WebRequest.DefaultWebProxy;
 
if (handler.SupportsAutomaticDecompression)
handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
 
if (credential != null)
{
handler.Credentials = credential;
handler.PreAuthenticate = true;
}
 
_client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(Timeout) };
_client.DefaultRequestHeaders.ExpectContinue = false;
 
_uploadClient = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(Timeout) };
_uploadClient.DefaultRequestHeaders.ExpectContinue = false;
}
 
#region WebDAV connection parameters
 
/// <summary>
/// Specify the WebDAV hostname (required).
/// Specify the WebDAV hostname (required).
/// </summary>
public string Server
{
get { return _server; }
set { _server = value.TrimEnd('/'); }
get
{
return _server;
}
set
{
value = value.TrimEnd('/');
_server = value;
}
}
 
/// <summary>
/// Specify the path of a WebDAV directory to use as 'root' (default: /)
/// Specify the path of a WebDAV directory to use as 'root' (default: /)
/// </summary>
public string BasePath
{
get { return _basePath; }
get
{
return _basePath;
}
set
{
value = value.Trim('/');
@@ -105,51 +87,82 @@
}
 
/// <summary>
/// Specify an port (default: null = auto-detect)
/// Specify an port (default: null = auto-detect)
/// </summary>
public int? Port { get; set; }
public int? Port
{
get; set;
}
 
/// <summary>
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// </summary>
public string UserAgent { get; set; }
public string UserAgent
{
get; set;
}
 
/// <summary>
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// </summary>
public string UserAgentVersion { get; set; }
public string UserAgentVersion
{
get; set;
}
 
/// <summary>
/// The HTTP request timeout in seconds.
/// </summary>
public int Timeout { get; set; } = 60;
#endregion
 
#endregion WebDAV connection parameters
 
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)
handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
if (credential != null)
{
handler.Credentials = credential;
handler.PreAuthenticate = true;
}
 
_client = new HttpClient(handler);
_client.DefaultRequestHeaders.ExpectContinue = false;
 
if (uploadTimeout != null)
{
_uploadClient = new HttpClient(handler);
_uploadClient.DefaultRequestHeaders.ExpectContinue = false;
_uploadClient.Timeout = uploadTimeout.Value;
}
 
}
 
#region WebDAV operations
 
/// <summary>
/// List all files present on the server.
/// List all files present on the server.
/// </summary>
/// <param name="path">List only files in this path</param>
/// <param name="depth">Recursion depth</param>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
public async Task<IEnumerable<Item>> List(string path = "/", string depth = Constants.DavDepth.MEMBERS)
public async Task<IEnumerable<Item>> List(string path = "/", int? depth = 1)
{
var listUri = await GetServerUrl(path, true).ConfigureAwait(false);
 
// Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4
IDictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Depth", depth);
if (depth != null)
{
headers.Add("Depth", depth.ToString());
}
 
 
HttpResponseMessage response = null;
 
try
{
response =
await
HttpRequest(listUri.Uri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent))
.ConfigureAwait(false);
response = await HttpRequest(listUri.Uri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)).ConfigureAwait(false);
 
if (response.StatusCode != HttpStatusCode.OK &&
(int)response.StatusCode != HttpStatusCode_MultiStatus)
@@ -168,75 +181,78 @@
 
var listUrl = listUri.ToString();
 
return items.AsParallel().Select(async item =>
var result = new List<Item>(items.Count());
foreach (var item in items)
{
switch (!item.IsCollection)
// If it's not a collection, add it to the result
if (!item.IsCollection)
{
case true:
return item;
 
default:
// If it's not the requested parent folder, add it to the result
if (!string.Equals((await GetServerUrl(item.Href, true).ConfigureAwait(false)).ToString(),
listUrl, StringComparison.CurrentCultureIgnoreCase))
{
return item;
}
break;
result.Add(item);
}
else
{
// If it's not the requested parent folder, add it to the result
var fullHref = await GetServerUrl(item.Href, true).ConfigureAwait(false);
if (!string.Equals(fullHref.ToString(), listUrl, StringComparison.CurrentCultureIgnoreCase))
{
result.Add(item);
}
}
}
return result;
}
 
return null;
}).Select(o => o.Result).OfType<Item>();
}
}
finally
{
response?.Dispose();
if (response != null)
response.Dispose();
}
}
 
/// <summary>
/// List all files present on the server.
/// List all files present on the server.
/// </summary>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
public async Task<Item> GetFolder(string path = "/")
{
return await Get((await GetServerUrl(path, true).ConfigureAwait(false)).Uri).ConfigureAwait(false);
var listUri = await GetServerUrl(path, true).ConfigureAwait(false);
return await Get(listUri.Uri, path).ConfigureAwait(false);
}
 
/// <summary>
/// List all files present on the server.
/// List all files present on the server.
/// </summary>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
public async Task<Item> GetFile(string path = "/")
{
return await Get((await GetServerUrl(path, false).ConfigureAwait(false)).Uri).ConfigureAwait(false);
var listUri = await GetServerUrl(path, false).ConfigureAwait(false);
return await Get(listUri.Uri, path).ConfigureAwait(false);
}
 
 
/// <summary>
/// List all files present on the server.
/// List all files present on the server.
/// </summary>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
private async Task<Item> Get(Uri listUri)
private async Task<Item> Get(Uri listUri, string path)
{
 
// Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4
IDictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Depth", "0");
 
 
HttpResponseMessage response = null;
 
try
{
response =
await
HttpRequest(listUri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent))
.ConfigureAwait(false);
response = await HttpRequest(listUri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)).ConfigureAwait(false);
 
if (response.StatusCode != HttpStatusCode.OK &&
(int)response.StatusCode != HttpStatusCode_MultiStatus)
{
throw new wasDAVException((int)response.StatusCode,
$"Failed retrieving item/folder (Status Code: {response.StatusCode})");
throw new wasDAVException((int)response.StatusCode, string.Format("Failed retrieving item/folder (Status Code: {0})", response.StatusCode));
}
 
using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
@@ -253,12 +269,13 @@
}
finally
{
response?.Dispose();
if (response != null)
response.Dispose();
}
}
 
/// <summary>
/// Download a file from the server
/// Download a file from the server
/// </summary>
/// <param name="remoteFilePath">Source path and filename of the file on the server</param>
public async Task<Stream> Download(string remoteFilePath)
@@ -276,7 +293,7 @@
}
 
/// <summary>
/// Download a file from the server
/// Download a file from the server
/// </summary>
/// <param name="remoteFilePath">Source path and filename of the file on the server</param>
/// <param name="content"></param>
@@ -284,8 +301,7 @@
public async Task<bool> Upload(string remoteFilePath, Stream content, string name)
{
// Should not have a trailing slash.
var uploadUri =
await GetServerUrl(remoteFilePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false);
var uploadUri = await GetServerUrl(remoteFilePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false);
 
HttpResponseMessage response = null;
 
@@ -304,20 +320,22 @@
}
finally
{
response?.Dispose();
if (response != null)
response.Dispose();
}
 
}
 
 
/// <summary>
/// Create a directory on the server
/// Create a directory on the server
/// </summary>
/// <param name="remotePath">Destination path of the directory on the server.</param>
/// <param name="name">The name of the folder to create.</param>
/// <param name="remotePath">Destination path of the directory on the server</param>
/// <param name="name"></param>
public async Task<bool> CreateDir(string remotePath, string name)
{
// Should not have a trailing slash.
var dirUri =
await GetServerUrl(remotePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false);
var dirUri = await GetServerUrl(remotePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false);
 
HttpResponseMessage response = null;
 
@@ -339,20 +357,24 @@
}
finally
{
response?.Dispose();
if (response != null)
response.Dispose();
}
}
 
public async Task DeleteFolder(string href)
{
await Delete((await GetServerUrl(href, true).ConfigureAwait(false)).Uri).ConfigureAwait(false);
var listUri = await GetServerUrl(href, true).ConfigureAwait(false);
await Delete(listUri.Uri).ConfigureAwait(false);
}
 
public async Task DeleteFile(string href)
{
await Delete((await GetServerUrl(href, false).ConfigureAwait(false)).Uri).ConfigureAwait(false);
var listUri = await GetServerUrl(href, false).ConfigureAwait(false);
await Delete(listUri.Uri).ConfigureAwait(false);
}
 
 
private async Task Delete(Uri listUri)
{
var response = await HttpRequest(listUri, HttpMethod.Delete).ConfigureAwait(false);
@@ -367,34 +389,31 @@
public async Task<bool> MoveFolder(string srcFolderPath, string dstFolderPath)
{
// Should have a trailing slash.
return
await
Move((await GetServerUrl(srcFolderPath, true).ConfigureAwait(false)).Uri,
(await GetServerUrl(dstFolderPath, true).ConfigureAwait(false)).Uri).ConfigureAwait(false);
var srcUri = await GetServerUrl(srcFolderPath, true).ConfigureAwait(false);
var dstUri = await GetServerUrl(dstFolderPath, true).ConfigureAwait(false);
 
return await Move(srcUri.Uri, dstUri.Uri).ConfigureAwait(false);
 
}
 
public async Task<bool> MoveFile(string srcFilePath, string dstFilePath)
{
// Should not have a trailing slash.
return
await
Move((await GetServerUrl(srcFilePath, false).ConfigureAwait(false)).Uri,
(await GetServerUrl(dstFilePath, false).ConfigureAwait(false)).Uri).ConfigureAwait(false);
var srcUri = await GetServerUrl(srcFilePath, false).ConfigureAwait(false);
var dstUri = await GetServerUrl(dstFilePath, false).ConfigureAwait(false);
 
return await Move(srcUri.Uri, dstUri.Uri).ConfigureAwait(false);
}
 
 
private async Task<bool> Move(Uri srcUri, Uri dstUri)
{
const string requestContent = "MOVE";
 
IDictionary<string, string> headers = new Dictionary<string, string>
{
{"Destination", dstUri.ToString()}
};
IDictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Destination", dstUri.ToString());
 
var response =
await
HttpRequest(srcUri, MoveMethod, headers, Encoding.UTF8.GetBytes(requestContent))
.ConfigureAwait(false);
var response = await HttpRequest(srcUri, MoveMethod, headers, Encoding.UTF8.GetBytes(requestContent)).ConfigureAwait(false);
 
if (response.StatusCode != HttpStatusCode.OK &&
response.StatusCode != HttpStatusCode.Created)
@@ -405,32 +424,30 @@
return response.IsSuccessStatusCode;
}
 
#endregion WebDAV operations
#endregion
 
#region Server communication
 
/// <summary>
/// Perform the WebDAV call and fire the callback when finished.
/// Perform the WebDAV call and fire the callback when finished.
/// </summary>
/// <param name="uri"></param>
/// <param name="method"></param>
/// <param name="headers"></param>
/// <param name="content"></param>
private async Task<HttpResponseMessage> HttpRequest(Uri uri, HttpMethod method,
IDictionary<string, string> headers = null, byte[] content = null)
private async Task<HttpResponseMessage> HttpRequest(Uri uri, HttpMethod method, IDictionary<string, string> headers = null, byte[] content = null)
{
using (var request = new HttpRequestMessage(method, uri))
{
request.Headers.Connection.Add("Keep-Alive");
request.Headers.UserAgent.Add(!string.IsNullOrWhiteSpace(UserAgent)
? new ProductInfoHeaderValue(UserAgent, UserAgentVersion)
: new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion));
request.Headers.Add("Accept", @"*/*");
request.Headers.Add("Accept-Encoding", "gzip,deflate");
if (!string.IsNullOrWhiteSpace(UserAgent))
request.Headers.UserAgent.Add(new ProductInfoHeaderValue(UserAgent, UserAgentVersion));
else
request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion));
 
if (headers != null)
{
foreach (var key in headers.Keys)
foreach (string key in headers.Keys)
{
request.Headers.Add(key, headers[key]);
}
@@ -448,25 +465,25 @@
}
 
/// <summary>
/// Perform the WebDAV call and fire the callback when finished.
/// Perform the WebDAV call and fire the callback when finished.
/// </summary>
/// <param name="uri"></param>
/// <param name="headers"></param>
/// <param name="method"></param>
/// <param name="content"></param>
private async Task<HttpResponseMessage> HttpUploadRequest(Uri uri, HttpMethod method, Stream content,
IDictionary<string, string> headers = null)
private async Task<HttpResponseMessage> HttpUploadRequest(Uri uri, HttpMethod method, Stream content, IDictionary<string, string> headers = null)
{
using (var request = new HttpRequestMessage(method, uri))
{
request.Headers.Connection.Add("Keep-Alive");
request.Headers.UserAgent.Add(!string.IsNullOrWhiteSpace(UserAgent)
? new ProductInfoHeaderValue(UserAgent, UserAgentVersion)
: new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion));
if (!string.IsNullOrWhiteSpace(UserAgent))
request.Headers.UserAgent.Add(new ProductInfoHeaderValue(UserAgent, UserAgentVersion));
else
request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion));
 
if (headers != null)
{
foreach (var key in headers.Keys)
foreach (string key in headers.Keys)
{
request.Headers.Add(key, headers[key]);
}
@@ -478,16 +495,17 @@
request.Content = new StreamContent(content);
}
 
return await (_uploadClient ?? _client).SendAsync(request).ConfigureAwait(false);
var client = _uploadClient ?? _client;
return await client.SendAsync(request).ConfigureAwait(false);
}
}
 
/// <summary>
/// Try to create an Uri with kind UriKind.Absolute
/// This particular implementation also works on Mono/Linux
/// It seems that on Mono it is expected behaviour that uris
/// of kind /a/b are indeed absolute uris since it referes to a file in /a/b.
/// https://bugzilla.xamarin.com/show_bug.cgi?id=30854
/// Try to create an Uri with kind UriKind.Absolute
/// This particular implementation also works on Mono/Linux
/// It seems that on Mono it is expected behaviour that uris
/// of kind /a/b are indeed absolute uris since it referes to a file in /a/b.
/// https://bugzilla.xamarin.com/show_bug.cgi?id=30854
/// </summary>
/// <param name="uriString"></param>
/// <param name="uriResult"></param>
@@ -503,11 +521,12 @@
if (_encodedBasePath == null)
{
var baseUri = new UriBuilder(_server) { Path = _basePath };
var root = await Get(baseUri.Uri).ConfigureAwait(false);
var root = await Get(baseUri.Uri, null).ConfigureAwait(false);
 
_encodedBasePath = root.Href;
}
 
 
// If we've been asked for the "root" folder
if (string.IsNullOrEmpty(path))
{
@@ -559,16 +578,11 @@
baseUri.Path = finalPath;
}
 
 
return baseUri;
}
}
 
public void Dispose()
{
_client?.Dispose();
_uploadClient?.Dispose();
}
 
#endregion Server communication
#endregion
}
}
/wasDAVClient/Helpers/ResponseParser.cs
@@ -1,11 +1,4 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Originally based on: WebDAV .NET client by Sergey Kazantsev
 
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -16,19 +9,12 @@
namespace wasDAVClient.Helpers
{
/// <summary>
/// Represents the parser for response's results.
/// Represents the parser for response's results.
/// </summary>
internal static class ResponseParser
{
internal static XmlReaderSettings XmlReaderSettings = new XmlReaderSettings
{
IgnoreComments = true,
IgnoreProcessingInstructions = true,
IgnoreWhitespace = true
};
 
/// <summary>
/// Parses the disk item.
/// Parses the disk item.
/// </summary>
/// <param name="stream">The response text.</param>
/// <returns>The parsed item.</returns>
@@ -37,8 +23,15 @@
return ParseItems(stream).FirstOrDefault();
}
 
internal static XmlReaderSettings XmlReaderSettings = new XmlReaderSettings
{
IgnoreComments = true,
IgnoreProcessingInstructions = true,
IgnoreWhitespace = true
};
 
/// <summary>
/// Parses the disk items.
/// Parses the disk items.
/// </summary>
/// <param name="stream">The response text.</param>
/// <returns>The list of parsed items.</returns>
@@ -47,6 +40,7 @@
var items = new List<Item>();
using (var reader = XmlReader.Create(stream, XmlReaderSettings))
{
 
Item itemInfo = null;
while (reader.Read())
{
@@ -131,8 +125,7 @@
{
reader.Read();
var resourceType = reader.LocalName.ToLower();
if (string.Equals(resourceType, "collection",
StringComparison.InvariantCultureIgnoreCase))
if (string.Equals(resourceType, "collection", StringComparison.InvariantCultureIgnoreCase))
itemInfo.IsCollection = true;
}
break;
@@ -144,6 +137,11 @@
case "version-controlled-configuration":
reader.Skip();
break;
default:
{
int a = 0;
break;
}
}
}
else if (reader.NodeType == XmlNodeType.EndElement && reader.LocalName.ToLower() == "response")
@@ -166,5 +164,7 @@
 
return items;
}
 
 
}
}
}
/wasDAVClient/Helpers/wasDAVConflictException.cs
@@ -1,54 +1,40 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Originally based on: WebDAV .NET client by Sergey Kazantsev
 
using System;
using System.Runtime.Serialization;
 
namespace wasDAVClient.Helpers
{
public class wasDAVConflictException : wasDAVException
{
public wasDAVConflictException()
{
}
 
public wasDAVConflictException(string message)
: base(message)
{
}
 
public wasDAVConflictException(string message, int hr)
: base(message, hr)
{
}
 
public wasDAVConflictException(string message, Exception innerException)
: base(message, innerException)
{
}
 
public wasDAVConflictException(int httpCode, string message, Exception innerException)
: base(httpCode, message, innerException)
{
}
 
public wasDAVConflictException(int httpCode, string message)
: base(httpCode, message)
{
}
 
public wasDAVConflictException(int httpCode, string message, int hr)
: base(httpCode, message, hr)
{
}
 
protected wasDAVConflictException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
using System;
using System.Runtime.Serialization;
 
namespace wasDAVClient.Helpers
{
public class wasDAVConflictException : wasDAVException
{
public wasDAVConflictException()
{
}
 
public wasDAVConflictException(string message)
: base(message)
{}
 
public wasDAVConflictException(string message, int hr)
: base(message, hr)
{}
 
public wasDAVConflictException(string message, Exception innerException)
: base(message, innerException)
{}
 
public wasDAVConflictException(int httpCode, string message, Exception innerException)
: base(httpCode, message, innerException)
{}
 
public wasDAVConflictException(int httpCode, string message)
: base(httpCode, message)
{}
 
public wasDAVConflictException(int httpCode, string message, int hr)
: base(httpCode, message, hr)
{}
 
protected wasDAVConflictException(SerializationInfo info, StreamingContext context)
: base(info, context)
{}
}
}
/wasDAVClient/Helpers/wasDAVException.cs
@@ -1,70 +1,51 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Originally based on: WebDAV .NET client by Sergey Kazantsev
 
using System;
using System.Runtime.Serialization;
using System.Text;
using System.Web;
 
namespace wasDAVClient.Helpers
{
public class wasDAVException : HttpException
{
public wasDAVException()
{
}
 
public wasDAVException(string message)
: base(message)
{
}
 
public wasDAVException(string message, int hr)
: base(message, hr)
{
}
 
public wasDAVException(string message, Exception innerException)
: base(message, innerException)
{
}
 
public wasDAVException(int httpCode, string message, Exception innerException)
: base(httpCode, message, innerException)
{
}
 
public wasDAVException(int httpCode, string message)
: base(httpCode, message)
{
}
 
public wasDAVException(int httpCode, string message, int hr)
: base(httpCode, message, hr)
{
}
 
protected wasDAVException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
 
public override string ToString()
{
var sb = new StringBuilder();
sb.Append($"HttpStatusCode: {GetHttpCode()}");
sb.Append(Environment.NewLine);
sb.Append($"ErrorCode: {ErrorCode}");
sb.Append(Environment.NewLine);
sb.Append($"Message: {Message}");
sb.Append(Environment.NewLine);
sb.Append(base.ToString());
 
return sb.ToString();
}
}
using System;
using System.Runtime.Serialization;
using System.Web;
 
namespace wasDAVClient.Helpers
{
public class wasDAVException : HttpException
{
public wasDAVException()
{
}
 
public wasDAVException(string message)
: base(message)
{}
 
public wasDAVException(string message, int hr)
: base(message, hr)
{}
 
public wasDAVException(string message, Exception innerException)
: base(message, innerException)
{}
 
public wasDAVException(int httpCode, string message, Exception innerException)
: base(httpCode, message, innerException)
{}
 
public wasDAVException(int httpCode, string message)
: base(httpCode, message)
{}
 
public wasDAVException(int httpCode, string message, int hr)
: base(httpCode, message, hr)
{}
 
protected wasDAVException(SerializationInfo info, StreamingContext context)
: base(info, context)
{}
 
public override string ToString()
{
var s = string.Format("HttpStatusCode: {0}", base.GetHttpCode());
s += Environment.NewLine + string.Format("ErrorCode: {0}", ErrorCode);
s += Environment.NewLine + string.Format("Message: {0}", Message);
s += Environment.NewLine + base.ToString();
 
return s;
}
}
}
/wasDAVClient/IClient.cs
@@ -1,10 +1,3 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Originally based on: WebDAV .NET client by Sergey Kazantsev
 
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
@@ -15,58 +8,58 @@
public interface IClient
{
/// <summary>
/// Specify the WebDAV hostname (required).
/// Specify the WebDAV hostname (required).
/// </summary>
string Server { get; set; }
 
/// <summary>
/// Specify the path of a WebDAV directory to use as 'root' (default: /)
/// Specify the path of a WebDAV directory to use as 'root' (default: /)
/// </summary>
string BasePath { get; set; }
 
/// <summary>
/// Specify an port (default: null = auto-detect)
/// Specify an port (default: null = auto-detect)
/// </summary>
int? Port { get; set; }
 
/// <summary>
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// </summary>
string UserAgent { get; set; }
 
/// <summary>
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// Specify the UserAgent (and UserAgent version) string to use in requests
/// </summary>
string UserAgentVersion { get; set; }
 
string UserAgentVersion { get; set; }
 
 
/// <summary>
/// List all files present on the server.
/// List all files present on the server.
/// </summary>
/// <param name="path">List only files in this path</param>
/// <param name="depth">Recursion depth</param>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
Task<IEnumerable<Item>> List(string path = Constants.DIRECTORY_SEPARATOR, string depth = Constants.DavDepth.MEMBERS);
Task<IEnumerable<Item>> List(string path = "/", int? depth = 1);
 
/// <summary>
/// Get folder information from the server.
/// Get folder information from the server.
/// </summary>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
Task<Item> GetFolder(string path = Constants.DIRECTORY_SEPARATOR);
Task<Item> GetFolder(string path = "/");
 
/// <summary>
/// Get file information from the server.
/// Get file information from the server.
/// </summary>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
Task<Item> GetFile(string path = Constants.DIRECTORY_SEPARATOR);
Task<Item> GetFile(string path = "/");
 
/// <summary>
/// Download a file from the server
/// Download a file from the server
/// </summary>
/// <param name="remoteFilePath">Source path and filename of the file on the server</param>
Task<Stream> Download(string remoteFilePath);
 
/// <summary>
/// Download a file from the server
/// Download a file from the server
/// </summary>
/// <param name="remoteFilePath">Source path and filename of the file on the server</param>
/// <param name="content"></param>
@@ -74,7 +67,7 @@
Task<bool> Upload(string remoteFilePath, Stream content, string name);
 
/// <summary>
/// Create a directory on the server
/// Create a directory on the server
/// </summary>
/// <param name="remotePath">Destination path of the directory on the server</param>
/// <param name="name"></param>
@@ -81,19 +74,19 @@
Task<bool> CreateDir(string remotePath, string name);
 
/// <summary>
/// Get folder information from the server.
/// Get folder information from the server.
/// </summary>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
Task DeleteFolder(string path = Constants.DIRECTORY_SEPARATOR);
Task DeleteFolder(string path = "/");
 
/// <summary>
/// Get file information from the server.
/// Get file information from the server.
/// </summary>
/// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
Task DeleteFile(string path = Constants.DIRECTORY_SEPARATOR);
Task DeleteFile(string path = "/");
 
/// <summary>
/// Move a folder on the server
/// Move a folder on the server
/// </summary>
/// <param name="srcFolderPath">Source path of the folder on the server</param>
/// <param name="dstFolderPath">Destination path of the folder on the server</param>
@@ -100,10 +93,10 @@
Task<bool> MoveFolder(string srcFolderPath, string dstFolderPath);
 
/// <summary>
/// Move a file on the server
/// Move a file on the server
/// </summary>
/// <param name="srcFilePath">Source path and filename of the file on the server</param>
/// <param name="dstFilePath">Destination path and filename of the file on the server</param>
Task<bool> MoveFile(string srcFilePath, string dstFilePath);
}
}
}
/wasDAVClient/Model/Item.cs
@@ -1,12 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
// Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
// rights of fair usage, the disclaimer and warranty conditions. //
///////////////////////////////////////////////////////////////////////////
// Originally based on: WebDAV .NET client by Sergey Kazantsev
using System;
 
using System;
 
namespace wasDAVClient.Model
{
public class Item
@@ -21,4 +14,4 @@
public string DisplayName { get; set; }
public long? ContentLength { get; set; }
}
}
}
/wasDAVClient/Properties/AssemblyInfo.cs
@@ -1,40 +1,36 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
 
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
 
[assembly: AssemblyTitle("WebDAV Client")]
[assembly: AssemblyDescription("A C# WebDAV Client")]
[assembly: AssemblyTitle("wasDAV")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Wizardry and Steamworks")]
[assembly: AssemblyProduct("WebDAV Client")]
[assembly: AssemblyCopyright("(c) Copyright 2016, Wizardry and Steamworks")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("wasDAV")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
 
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
 
[assembly: ComVisible(false)]
 
// The following GUID is for the ID of the typelib if this project is exposed to COM
 
[assembly: Guid("8c9a5d56-e5a1-4e18-bd00-fff55a2ae01d")]
 
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
 
[assembly: AssemblyVersion("1.5.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
/wasDAVClient/wasDAVClient.csproj
@@ -7,8 +7,8 @@
<ProjectGuid>{8C9A5D56-E5A1-4E18-BD00-FFF55A2AE01D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>wasDAVClient</RootNamespace>
<AssemblyName>wasDAVClient</AssemblyName>
<RootNamespace>wasDAV</RootNamespace>
<AssemblyName>wasDAV</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
@@ -33,12 +33,15 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Client.cs" />
<Compile Include="Constants.cs" />
<Compile Include="Helpers\ResponseParser.cs" />
<Compile Include="Helpers\wasDAVConflictException.cs" />
<Compile Include="Helpers\wasDAVException.cs" />