/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/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); |
} |
} |
} |