From 7a1e1a9b1a60c8a51fd65c42285532127e044229 Mon Sep 17 00:00:00 2001 From: SALTWOOD <105980161+SALTWOOD@users.noreply.github.com> Date: Sat, 10 Aug 2024 18:37:11 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E5=B0=86=20Lock=20=E6=8F=90?= =?UTF-8?q?=E5=8F=96=E5=88=B0=E4=B8=80=E4=B8=AA=E5=8D=95=E7=8B=AC=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E8=BF=9B=E8=A1=8C=E7=AE=A1=E7=90=86=20fix:=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E5=90=8C=E6=97=B6=E9=94=81=E5=AE=9A=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E8=B5=84=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Network/WebDav/WebDavClient.cs | 41 ++++++++---------- Network/WebDav/WebDavFileLock.cs | 72 ++++++++++++++++++++++++++++++++ TeraIO.csproj | 8 +++- 3 files changed, 96 insertions(+), 25 deletions(-) create mode 100644 Network/WebDav/WebDavFileLock.cs diff --git a/Network/WebDav/WebDavClient.cs b/Network/WebDav/WebDavClient.cs index 9ab6921..bc1feb5 100644 --- a/Network/WebDav/WebDavClient.cs +++ b/Network/WebDav/WebDavClient.cs @@ -6,13 +6,13 @@ using System.Threading.Tasks; using System.Web; using System.Xml.Linq; +using TeraIO.Runnable; namespace TeraIO.Network.WebDav { public class WebDavClient { protected HttpClient httpClient; - public string? lockToken; public WebDavClient(string baseUrl) { @@ -25,24 +25,24 @@ public void SetUser(string username, string password) this.httpClient.DefaultRequestHeaders.Add("Authorization", $"Basic {Convert.ToBase64String(Encoding.UTF8.GetBytes($"{username}:{password}"))}"); } - public async Task PutFile(string fileName, byte[] data) + public async Task PutFile(string fileName, byte[] data, WebDavFileLock? fileLock = null) { HttpContent content = new ByteArrayContent(data); - if (!string.IsNullOrWhiteSpace(lockToken)) + if (!string.IsNullOrWhiteSpace(fileLock?.LockToken)) { - content.Headers.Add("Lock-Token", lockToken); - content.Headers.Add("If", $"({lockToken})"); + content.Headers.Add("Lock-Token", fileLock?.LockToken); + content.Headers.Add("If", $"({fileLock?.LockToken})"); } return await this.httpClient.PutAsync(fileName, content); } - public async Task PutFile(string fileName, Stream stream) + public async Task PutFile(string fileName, Stream stream, WebDavFileLock? fileLock = null) { HttpContent content = new StreamContent(stream); - if (!string.IsNullOrWhiteSpace(lockToken)) + if (!string.IsNullOrWhiteSpace(fileLock?.LockToken)) { - content.Headers.Add("Lock-Token", lockToken); - content.Headers.Add("If", $"({lockToken})"); + content.Headers.Add("Lock-Token", fileLock?.LockToken); + content.Headers.Add("If", $"({fileLock?.LockToken})"); } return await this.httpClient.PutAsync(fileName, content); } @@ -142,16 +142,14 @@ public async Task Delete(string name) return await this.httpClient.DeleteAsync(name); } - public async Task Lock(string name, int timeout = 60) + public async Task Lock(string name, int timeout = 60) { - HttpRequestMessage message = new HttpRequestMessage(new HttpMethod("LOCK"), name) - { - Content = new StringContent("") - }; - message.Headers.Add("Timeout", $"Second-{timeout}"); - var response = await this.httpClient.SendAsync(message); - this.lockToken = response.Headers.GetValues("Lock-Token").First(); - return response; + WebDavFileLock fileLock = new WebDavFileLock(name); + fileLock.Client.BaseAddress = this.httpClient.BaseAddress; + fileLock.Client.DefaultRequestHeaders.Clear(); + this.httpClient.DefaultRequestHeaders.ForEach(kvp => fileLock.Client.DefaultRequestHeaders.Add(kvp.Key, kvp.Value)); + await fileLock.Lock(); + return fileLock; } public async Task GetFile(string filename) @@ -164,12 +162,9 @@ public async Task GetFileStream(string filename) return await (await this.httpClient.GetAsync(filename)).Content.ReadAsStreamAsync(); } - public async Task Unlock(string name) + public async Task Unlock(WebDavFileLock fileLock) { - HttpRequestMessage message = new HttpRequestMessage(new HttpMethod("UNLOCK"), name); - message.Headers.Add("Lock-Token", this.lockToken); - this.lockToken = null; - return await this.httpClient.SendAsync(message); + await fileLock.Unlock(); } } } diff --git a/Network/WebDav/WebDavFileLock.cs b/Network/WebDav/WebDavFileLock.cs new file mode 100644 index 0000000..2367135 --- /dev/null +++ b/Network/WebDav/WebDavFileLock.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Xml.Linq; + +namespace TeraIO.Network.WebDav +{ + public class WebDavFileLock : IDisposable + { + public string FileName { get; protected set; } + public string? LockToken { get; protected set; } + private bool disposed; + + public HttpClient Client { get; protected set; } + + public WebDavFileLock(string name) + { + this.FileName = name; + this.Client = new HttpClient(); + } + + public async Task Lock(int timeout = 60) + { + HttpRequestMessage message = new HttpRequestMessage(new HttpMethod("LOCK"), this.FileName) + { + Content = new StringContent("") + }; + message.Headers.Add("Timeout", $"Second-{timeout}"); + var response = await this.Client.SendAsync(message); + string lockToken = response.Headers.GetValues("Lock-Token").First(); + } + + public async Task Unlock() + { + HttpRequestMessage message = new HttpRequestMessage(new HttpMethod("UNLOCK"), this.FileName); + message.Headers.Add("Lock-Token", this.LockToken); + this.LockToken = null; + await this.Client.SendAsync(message); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposed) + { + if (disposing) + { + // TODO: 释放托管状态(托管对象) + } + + this.Unlock().Wait(); + disposed = true; + } + } + + // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器 + ~WebDavFileLock() + { + // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 + Dispose(disposing: false); + } + + public void Dispose() + { + // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/TeraIO.csproj b/TeraIO.csproj index 3418a98..5e42449 100644 --- a/TeraIO.csproj +++ b/TeraIO.csproj @@ -18,14 +18,18 @@ + + + + + + - -