wasDAVClient – Diff between revs 4 and 5

Subversion Repositories:
Rev:
Show entire fileIgnore whitespace
Rev 4 Rev 5
Line -... Line 1...
-   1 ///////////////////////////////////////////////////////////////////////////
-   2 // Copyright (C) Wizardry and Steamworks 2016 - License: GNU GPLv3 //
-   3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
-   4 // rights of fair usage, the disclaimer and warranty conditions. //
-   5 ///////////////////////////////////////////////////////////////////////////
-   6 // Originally based on: WebDAV .NET client by Sergey Kazantsev
-   7  
1 using System; 8 using System;
2 using System.Collections.Generic; 9 using System.Collections.Generic;
3 using System.IO; 10 using System.IO;
4 using System.Linq; 11 using System.Linq;
5 using System.Net; 12 using System.Net;
6 using System.Net.Http; 13 using System.Net.Http;
Line 45... Line 52...
45 private string _basePath = "/"; 52 private string _basePath = "/";
Line 46... Line 53...
46   53  
47 private string _encodedBasePath; 54 private string _encodedBasePath;
Line 48... Line -...
48 private string _server; -  
49   55 private string _server;
50   56  
51 public Client(NetworkCredential credential = null) 57 public Client(ICredentials credential = null)
Line 52... Line 58...
52 { 58 {
53 var handler = new HttpClientHandler(); 59 var handler = new HttpClientHandler();
Line 62... Line 68...
62 { 68 {
63 handler.Credentials = credential; 69 handler.Credentials = credential;
64 handler.PreAuthenticate = true; 70 handler.PreAuthenticate = true;
65 } 71 }
Line 66... Line -...
66   -  
67 _client = new HttpClient(handler); 72  
68 _client.Timeout = TimeSpan.FromSeconds(Timeout); 73 _client = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(Timeout)};
Line 69... Line -...
69 _client.DefaultRequestHeaders.ExpectContinue = false; -  
70   74 _client.DefaultRequestHeaders.ExpectContinue = false;
71 _uploadClient = new HttpClient(handler); 75  
72 _uploadClient.Timeout = TimeSpan.FromSeconds(Timeout); 76 _uploadClient = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(Timeout)};
Line 73... Line 77...
73 _uploadClient.DefaultRequestHeaders.ExpectContinue = false; 77 _uploadClient.DefaultRequestHeaders.ExpectContinue = false;
Line 79... Line 83...
79 /// Specify the WebDAV hostname (required). 83 /// Specify the WebDAV hostname (required).
80 /// </summary> 84 /// </summary>
81 public string Server 85 public string Server
82 { 86 {
83 get { return _server; } 87 get { return _server; }
84 set -  
85 { -  
86 value = value.TrimEnd('/'); 88 set { _server = value.TrimEnd('/'); }
87 _server = value; -  
88 } -  
89 } 89 }
Line 90... Line 90...
90   90  
91 /// <summary> 91 /// <summary>
92 /// Specify the path of a WebDAV directory to use as 'root' (default: /) 92 /// Specify the path of a WebDAV directory to use as 'root' (default: /)
Line 169... Line 169...
169 throw new wasDAVException("Failed deserializing data returned from server."); 169 throw new wasDAVException("Failed deserializing data returned from server.");
170 } 170 }
Line 171... Line 171...
171   171  
Line 172... Line -...
172 var listUrl = listUri.ToString(); -  
173   172 var listUrl = listUri.ToString();
174 var result = new List<Item>(items.Count()); 173  
175 foreach (var item in items) -  
176 { 174 return items.AsParallel().Select(async item =>
177 // If it's not a collection, add it to the result 175 {
-   176 switch (!item.IsCollection)
178 if (!item.IsCollection) 177 {
-   178 case true:
-   179 return item;
-   180 default:
-   181 // If it's not the requested parent folder, add it to the result
-   182 if (!string.Equals((await GetServerUrl(item.Href, true).ConfigureAwait(false)).ToString(),
-   183 listUrl, StringComparison.CurrentCultureIgnoreCase))
-   184 {
-   185 return item;
179 { 186 }
-   187 break;
180 result.Add(item); 188 }
181 } -  
182 else -  
183 { -  
184 // If it's not the requested parent folder, add it to the result -  
185 var fullHref = await GetServerUrl(item.Href, true).ConfigureAwait(false); -  
186 if (!string.Equals(fullHref.ToString(), listUrl, StringComparison.CurrentCultureIgnoreCase)) 189  
187 { -  
188 result.Add(item); -  
189 } -  
190 } -  
191 } 190 return null;
192 return result; 191 }).Select(o => o.Result).OfType<Item>();
193 } 192 }
194 } 193 }
195 finally -  
196 { 194 finally
197 if (response != null) 195 {
198 response.Dispose(); 196 response?.Dispose();
Line 199... Line 197...
199 } 197 }
200 } 198 }
201   199  
202 /// <summary> 200 /// <summary>
203 /// List all files present on the server. 201 /// List all files present on the server.
204 /// </summary> 202 /// </summary>
205 /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> 203 /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
206 public async Task<Item> GetFolder(string path = "/") -  
207 { 204 public async Task<Item> GetFolder(string path = "/")
Line 208... Line 205...
208 var listUri = await GetServerUrl(path, true).ConfigureAwait(false); 205 {
209 return await Get(listUri.Uri, path).ConfigureAwait(false); 206 return await Get((await GetServerUrl(path, true).ConfigureAwait(false)).Uri).ConfigureAwait(false);
210 } 207 }
211   208  
212 /// <summary> 209 /// <summary>
213 /// List all files present on the server. 210 /// List all files present on the server.
214 /// </summary> 211 /// </summary>
215 /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> -  
216 public async Task<Item> GetFile(string path = "/") 212 /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
Line 217... Line 213...
217 { 213 public async Task<Item> GetFile(string path = "/")
218 var listUri = await GetServerUrl(path, false).ConfigureAwait(false); 214 {
219 return await Get(listUri.Uri, path).ConfigureAwait(false); 215 return await Get((await GetServerUrl(path, false).ConfigureAwait(false)).Uri).ConfigureAwait(false);
220 } 216 }
221   217  
222   218  
223 /// <summary> 219 /// <summary>
224 /// List all files present on the server. 220 /// List all files present on the server.
225 /// </summary> 221 /// </summary>
Line 226... Line -...
226 /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> -  
227 private async Task<Item> Get(Uri listUri, string path) 222 /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns>
Line 228... Line 223...
228 { 223 private async Task<Item> Get(Uri listUri)
229 // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4 224 {
230 IDictionary<string, string> headers = new Dictionary<string, string>(); 225 // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4
Line 242... Line 237...
242   237  
243 if (response.StatusCode != HttpStatusCode.OK && 238 if (response.StatusCode != HttpStatusCode.OK &&
244 (int) response.StatusCode != HttpStatusCode_MultiStatus) 239 (int) response.StatusCode != HttpStatusCode_MultiStatus)
245 { 240 {
246 throw new wasDAVException((int) response.StatusCode, 241 throw new wasDAVException((int) response.StatusCode,
247 string.Format("Failed retrieving item/folder (Status Code: {0})", response.StatusCode)); 242 $"Failed retrieving item/folder (Status Code: {response.StatusCode})");
Line 248... Line 243...
248 } 243 }
249   244  
250 using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) 245 using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
Line 259... Line 254...
259 return result; 254 return result;
260 } 255 }
261 } 256 }
262 finally 257 finally
263 { 258 {
264 if (response != null) -  
265 response.Dispose(); 259 response?.Dispose();
266 } 260 }
267 } 261 }
Line 268... Line 262...
268   262  
269 /// <summary> 263 /// <summary>
Line 311... Line 305...
311   305  
312 return response.IsSuccessStatusCode; 306 return response.IsSuccessStatusCode;
313 } 307 }
314 finally 308 finally
315 { -  
316 if (response != null) 309 {
317 response.Dispose(); 310 response?.Dispose();
318 } 311 }
Line 319... Line 312...
319 } 312 }
320   313  
321   314  
322 /// <summary> 315 /// <summary>
323 /// Create a directory on the server 316 /// Create a directory on the server
324 /// </summary> 317 /// </summary>
325 /// <param name="remotePath">Destination path of the directory on the server</param> 318 /// <param name="remotePath">Destination path of the directory on the server.</param>
326 /// <param name="name"></param> 319 /// <param name="name">The name of the folder to create.</param>
327 public async Task<bool> CreateDir(string remotePath, string name) 320 public async Task<bool> CreateDir(string remotePath, string name)
328 { 321 {
Line 348... Line 341...
348   341  
349 return response.IsSuccessStatusCode; 342 return response.IsSuccessStatusCode;
350 } 343 }
351 finally 344 finally
352 { -  
353 if (response != null) 345 {
354 response.Dispose(); 346 response?.Dispose();
355 } 347 }
Line 356... Line 348...
356 } 348 }
357   349  
358 public async Task DeleteFolder(string href) 350 public async Task DeleteFolder(string href)
359 { -  
360 var listUri = await GetServerUrl(href, true).ConfigureAwait(false); 351 {
Line 361... Line 352...
361 await Delete(listUri.Uri).ConfigureAwait(false); 352 await Delete((await GetServerUrl(href, true).ConfigureAwait(false)).Uri).ConfigureAwait(false);
362 } 353 }
363   354  
364 public async Task DeleteFile(string href) -  
365 { 355 public async Task DeleteFile(string href)
Line 366... Line 356...
366 var listUri = await GetServerUrl(href, false).ConfigureAwait(false); 356 {
367 await Delete(listUri.Uri).ConfigureAwait(false); 357 await Delete((await GetServerUrl(href, false).ConfigureAwait(false)).Uri).ConfigureAwait(false);
Line 380... Line 370...
380 } 370 }
Line 381... Line 371...
381   371  
382 public async Task<bool> MoveFolder(string srcFolderPath, string dstFolderPath) 372 public async Task<bool> MoveFolder(string srcFolderPath, string dstFolderPath)
383 { 373 {
-   374 // Should have a trailing slash.
384 // Should have a trailing slash. 375 return
385 var srcUri = await GetServerUrl(srcFolderPath, true).ConfigureAwait(false); 376 await
386 var dstUri = await GetServerUrl(dstFolderPath, true).ConfigureAwait(false); -  
387   377 Move((await GetServerUrl(srcFolderPath, true).ConfigureAwait(false)).Uri,
388 return await Move(srcUri.Uri, dstUri.Uri).ConfigureAwait(false); 378 (await GetServerUrl(dstFolderPath, true).ConfigureAwait(false)).Uri).ConfigureAwait(false);
Line 389... Line 379...
389 } 379 }
390   380  
391 public async Task<bool> MoveFile(string srcFilePath, string dstFilePath) 381 public async Task<bool> MoveFile(string srcFilePath, string dstFilePath)
-   382 {
392 { 383 // Should not have a trailing slash.
393 // Should not have a trailing slash. 384 return
394 var srcUri = await GetServerUrl(srcFilePath, false).ConfigureAwait(false); -  
395 var dstUri = await GetServerUrl(dstFilePath, false).ConfigureAwait(false); 385 await
396   386 Move((await GetServerUrl(srcFilePath, false).ConfigureAwait(false)).Uri,
Line 397... Line 387...
397 return await Move(srcUri.Uri, dstUri.Uri).ConfigureAwait(false); 387 (await GetServerUrl(dstFilePath, false).ConfigureAwait(false)).Uri).ConfigureAwait(false);
398 } 388 }
399   389  
Line 400... Line 390...
400   390  
-   391 private async Task<bool> Move(Uri srcUri, Uri dstUri)
401 private async Task<bool> Move(Uri srcUri, Uri dstUri) 392 {
-   393 const string requestContent = "MOVE";
Line 402... Line 394...
402 { 394  
403 const string requestContent = "MOVE"; 395 IDictionary<string, string> headers = new Dictionary<string, string>
404   396 {
405 IDictionary<string, string> headers = new Dictionary<string, string>(); 397 {"Destination", dstUri.ToString()}
Line 434... Line 426...
434 IDictionary<string, string> headers = null, byte[] content = null) 426 IDictionary<string, string> headers = null, byte[] content = null)
435 { 427 {
436 using (var request = new HttpRequestMessage(method, uri)) 428 using (var request = new HttpRequestMessage(method, uri))
437 { 429 {
438 request.Headers.Connection.Add("Keep-Alive"); 430 request.Headers.Connection.Add("Keep-Alive");
439 if (!string.IsNullOrWhiteSpace(UserAgent)) 431 request.Headers.UserAgent.Add(!string.IsNullOrWhiteSpace(UserAgent)
440 request.Headers.UserAgent.Add(new ProductInfoHeaderValue(UserAgent, UserAgentVersion)); 432 ? new ProductInfoHeaderValue(UserAgent, UserAgentVersion)
441 else -  
442 request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion)); 433 : new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion));
Line 443... Line 434...
443   434  
444 if (headers != null) 435 if (headers != null)
445 { 436 {
446 foreach (var key in headers.Keys) 437 foreach (var key in headers.Keys)
Line 471... Line 462...
471 IDictionary<string, string> headers = null) 462 IDictionary<string, string> headers = null)
472 { 463 {
473 using (var request = new HttpRequestMessage(method, uri)) 464 using (var request = new HttpRequestMessage(method, uri))
474 { 465 {
475 request.Headers.Connection.Add("Keep-Alive"); 466 request.Headers.Connection.Add("Keep-Alive");
476 if (!string.IsNullOrWhiteSpace(UserAgent)) 467 request.Headers.UserAgent.Add(!string.IsNullOrWhiteSpace(UserAgent)
477 request.Headers.UserAgent.Add(new ProductInfoHeaderValue(UserAgent, UserAgentVersion)); 468 ? new ProductInfoHeaderValue(UserAgent, UserAgentVersion)
478 else -  
479 request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion)); 469 : new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion));
Line 480... Line 470...
480   470  
481 if (headers != null) 471 if (headers != null)
482 { 472 {
483 foreach (var key in headers.Keys) 473 foreach (var key in headers.Keys)
Line 490... Line 480...
490 if (content != null) 480 if (content != null)
491 { 481 {
492 request.Content = new StreamContent(content); 482 request.Content = new StreamContent(content);
493 } 483 }
Line 494... Line -...
494   -  
495 var client = _uploadClient ?? _client; 484  
496 return await client.SendAsync(request).ConfigureAwait(false); 485 return await (_uploadClient ?? _client).SendAsync(request).ConfigureAwait(false);
497 } 486 }
Line 498... Line 487...
498 } 487 }
499   488  
Line 516... Line 505...
516 { 505 {
517 // Resolve the base path on the server 506 // Resolve the base path on the server
518 if (_encodedBasePath == null) 507 if (_encodedBasePath == null)
519 { 508 {
520 var baseUri = new UriBuilder(_server) {Path = _basePath}; 509 var baseUri = new UriBuilder(_server) {Path = _basePath};
521 var root = await Get(baseUri.Uri, null).ConfigureAwait(false); 510 var root = await Get(baseUri.Uri).ConfigureAwait(false);
Line 522... Line 511...
522   511  
523 _encodedBasePath = root.Href; 512 _encodedBasePath = root.Href;
Line 580... Line 569...
580 } 569 }
581 } 570 }
Line 582... Line 571...
582   571  
583 public void Dispose() 572 public void Dispose()
584 { -  
585 if(_client != null) 573 {
586 _client.Dispose(); -  
587 if (_uploadClient != null) 574 _client?.Dispose();
588 _uploadClient.Dispose(); 575 _uploadClient?.Dispose();
Line 589... Line 576...
589 } 576 }
590   577  
591 #endregion 578 #endregion
592 } 579 }