Skip to content

Commit

Permalink
feat: WebDavClient 完成
Browse files Browse the repository at this point in the history
  • Loading branch information
SALTWOOD committed May 19, 2024
1 parent ce90315 commit e2a1da8
Showing 1 changed file with 99 additions and 2 deletions.
101 changes: 99 additions & 2 deletions Network/WebDav/WebDavClient.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml.Linq;

namespace TeraIO.Network.WebDav
{
Expand Down Expand Up @@ -34,6 +36,17 @@ public async Task<HttpResponseMessage> PutFile(string fileName, byte[] data)
return await this.httpClient.PutAsync(fileName, content);
}

public async Task<HttpResponseMessage> PutFile(string fileName, Stream stream)
{
HttpContent content = new StreamContent(stream);
if (!string.IsNullOrWhiteSpace(lockToken))
{
content.Headers.Add("Lock-Token", lockToken);
content.Headers.Add("If", $"({lockToken})");
}
return await this.httpClient.PutAsync(fileName, content);
}

public async Task<HttpResponseMessage> CreateFolder(string folderName)
{
return await this.httpClient.SendAsync(new HttpRequestMessage(new HttpMethod("MKCOL"), folderName));
Expand All @@ -44,12 +57,86 @@ public async Task<bool> Exists(string name)
return (await this.httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, name))).IsSuccessStatusCode;
}

public async Task<long> GetFileSize(string name)
{
var resp = await this.httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, name));
if (!resp.IsSuccessStatusCode)
{
return 0;
}
if (resp.Content.Headers.TryGetValues("Content-Length", out var fileSize))
{
return long.Parse(fileSize.First());
}
return 0;
}

public async Task<List<string>> ListFilesAndFolders(string folderPath, int depth = -1)
{
var requestMessage = new HttpRequestMessage(new HttpMethod("PROPFIND"), folderPath)
{
Headers =
{
{ "Depth", depth.ToString() }
},
Content = new StringContent(string.Empty)
};
if (depth < 0)
{
requestMessage.Headers.Remove("Depth");
}
requestMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");

var response = await httpClient.SendAsync(requestMessage);
response.EnsureSuccessStatusCode();

var responseContent = await response.Content.ReadAsStringAsync();
return ParsePropFindResponse(responseContent);
}

private List<string> ParsePropFindResponse(string responseContent)
{
XDocument document = XDocument.Parse(responseContent);
XNamespace ns = "DAV:";

List<string> items = new List<string>();

foreach (var response in document.Descendants(ns + "response"))
{
var hrefElement = response.Element(ns + "href");
if (hrefElement != null)
{
items.Add(hrefElement.Value);
}
}

return items;
}

public string GetFileDownloadLink(string filePath)
{
//TODO: GetFileDownloadLink
throw new NotImplementedException("TODO: GetFileDownloadLink");
// Ensure the file path is correctly URL encoded
string encodedFilePath = HttpUtility.UrlEncode(filePath);

// Construct the full URL for downloading the file
string url = $"{httpClient.BaseAddress}{encodedFilePath}";

// Determine if the URL should use https or http
string protocol = url.StartsWith("https", StringComparison.OrdinalIgnoreCase) ? "https" : "http";

// Check the Authorization header for Basic auth and modify the URL accordingly
if (httpClient.DefaultRequestHeaders.Authorization != null &&
httpClient.DefaultRequestHeaders.Authorization.Scheme.Equals("Basic", StringComparison.OrdinalIgnoreCase))
{
string? authPart = httpClient.DefaultRequestHeaders.Authorization.Parameter;
string authContents = Encoding.UTF8.GetString(Convert.FromBase64String(authPart ?? ""));
url = url.Replace($"{protocol}://", $"{protocol}://{authContents}@");
}

return url;
}


public async Task<HttpResponseMessage> Delete(string name)
{
return await this.httpClient.DeleteAsync(name);
Expand All @@ -67,6 +154,16 @@ public async Task<HttpResponseMessage> Lock(string name, int timeout = 60)
return response;
}

public async Task<byte[]> GetFile(string filename)
{
return await (await this.httpClient.GetAsync(filename)).Content.ReadAsByteArrayAsync();
}

public async Task<Stream> GetFileStream(string filename)
{
return await (await this.httpClient.GetAsync(filename)).Content.ReadAsStreamAsync();
}

public async Task<HttpResponseMessage> Unlock(string name)
{
HttpRequestMessage message = new HttpRequestMessage(new HttpMethod("UNLOCK"), name);
Expand Down

0 comments on commit e2a1da8

Please sign in to comment.