wasDAVClient – Diff between revs 6 and 8
?pathlinks?
Rev 6 | Rev 8 | |||
---|---|---|---|---|
Line 68... | Line 68... | |||
68 | { |
68 | { |
|
69 | handler.Credentials = credential; |
69 | handler.Credentials = credential; |
|
70 | handler.PreAuthenticate = true; |
70 | handler.PreAuthenticate = true; |
|
71 | } |
71 | } |
|
Line 72... | Line 72... | |||
72 | |
72 | |
|
73 | _client = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(Timeout)}; |
73 | _client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(Timeout) }; |
|
Line 74... | Line 74... | |||
74 | _client.DefaultRequestHeaders.ExpectContinue = false; |
74 | _client.DefaultRequestHeaders.ExpectContinue = false; |
|
75 | |
75 | |
|
76 | _uploadClient = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(Timeout)}; |
76 | _uploadClient = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(Timeout) }; |
|
Line 77... | Line 77... | |||
77 | _uploadClient.DefaultRequestHeaders.ExpectContinue = false; |
77 | _uploadClient.DefaultRequestHeaders.ExpectContinue = false; |
|
Line 122... | Line 122... | |||
122 | /// <summary> |
122 | /// <summary> |
|
123 | /// The HTTP request timeout in seconds. |
123 | /// The HTTP request timeout in seconds. |
|
124 | /// </summary> |
124 | /// </summary> |
|
125 | public int Timeout { get; set; } = 60; |
125 | public int Timeout { get; set; } = 60; |
|
Line 126... | Line 126... | |||
126 | |
126 | |
|
Line 127... | Line 127... | |||
127 | #endregion |
127 | #endregion WebDAV connection parameters |
|
Line 128... | Line 128... | |||
128 | |
128 | |
|
129 | #region WebDAV operations |
129 | #region WebDAV operations |
|
130 | |
130 | |
|
131 | /// <summary> |
131 | /// <summary> |
|
132 | /// List all files present on the server. |
132 | /// List all files present on the server. |
|
133 | /// </summary> |
133 | /// </summary> |
|
134 | /// <param name="path">List only files in this path</param> |
134 | /// <param name="path">List only files in this path</param> |
|
135 | /// <param name="depth">Recursion depth</param> |
135 | /// <param name="depth">Recursion depth</param> |
|
136 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
136 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
|
Line 137... | Line 137... | |||
137 | public async Task<IEnumerable<Item>> List(string path = "/", int? depth = 1) |
137 | public async Task<IEnumerable<Item>> List(string path = "/", string depth = Constants.DavDepth.MEMBERS) |
|
138 | { |
138 | { |
|
139 | var listUri = await GetServerUrl(path, true).ConfigureAwait(false); |
- | ||
140 | |
- | ||
141 | // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4 |
139 | var listUri = await GetServerUrl(path, true).ConfigureAwait(false); |
|
142 | IDictionary<string, string> headers = new Dictionary<string, string>(); |
- | ||
Line 143... | Line 140... | |||
143 | if (depth != null) |
140 | |
|
Line 144... | Line 141... | |||
144 | { |
141 | // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4 |
|
145 | headers.Add("Depth", depth.ToString()); |
142 | IDictionary<string, string> headers = new Dictionary<string, string>(); |
|
Line 153... | Line 150... | |||
153 | await |
150 | await |
|
154 | HttpRequest(listUri.Uri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)) |
151 | HttpRequest(listUri.Uri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)) |
|
155 | .ConfigureAwait(false); |
152 | .ConfigureAwait(false); |
|
Line 156... | Line 153... | |||
156 | |
153 | |
|
157 | if (response.StatusCode != HttpStatusCode.OK && |
154 | if (response.StatusCode != HttpStatusCode.OK && |
|
158 | (int) response.StatusCode != HttpStatusCode_MultiStatus) |
155 | (int)response.StatusCode != HttpStatusCode_MultiStatus) |
|
159 | { |
156 | { |
|
160 | throw new wasDAVException((int) response.StatusCode, "Failed retrieving items in folder."); |
157 | throw new wasDAVException((int)response.StatusCode, "Failed retrieving items in folder."); |
|
Line 161... | Line 158... | |||
161 | } |
158 | } |
|
162 | |
159 | |
|
163 | using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) |
160 | using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) |
|
Line 175... | Line 172... | |||
175 | { |
172 | { |
|
176 | switch (!item.IsCollection) |
173 | switch (!item.IsCollection) |
|
177 | { |
174 | { |
|
178 | case true: |
175 | case true: |
|
179 | return item; |
176 | return item; |
|
- | 177 | |
||
180 | default: |
178 | default: |
|
181 | // If it's not the requested parent folder, add it to the result |
179 | // 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(), |
180 | if (!string.Equals((await GetServerUrl(item.Href, true).ConfigureAwait(false)).ToString(), |
|
183 | listUrl, StringComparison.CurrentCultureIgnoreCase)) |
181 | listUrl, StringComparison.CurrentCultureIgnoreCase)) |
|
184 | { |
182 | { |
|
Line 213... | Line 211... | |||
213 | public async Task<Item> GetFile(string path = "/") |
211 | public async Task<Item> GetFile(string path = "/") |
|
214 | { |
212 | { |
|
215 | return await Get((await GetServerUrl(path, false).ConfigureAwait(false)).Uri).ConfigureAwait(false); |
213 | return await Get((await GetServerUrl(path, false).ConfigureAwait(false)).Uri).ConfigureAwait(false); |
|
216 | } |
214 | } |
|
Line 217... | Line -... | |||
217 | |
- | ||
218 | |
215 | |
|
219 | /// <summary> |
216 | /// <summary> |
|
220 | /// List all files present on the server. |
217 | /// List all files present on the server. |
|
221 | /// </summary> |
218 | /// </summary> |
|
222 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
219 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
|
Line 234... | Line 231... | |||
234 | await |
231 | await |
|
235 | HttpRequest(listUri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)) |
232 | HttpRequest(listUri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)) |
|
236 | .ConfigureAwait(false); |
233 | .ConfigureAwait(false); |
|
Line 237... | Line 234... | |||
237 | |
234 | |
|
238 | if (response.StatusCode != HttpStatusCode.OK && |
235 | if (response.StatusCode != HttpStatusCode.OK && |
|
239 | (int) response.StatusCode != HttpStatusCode_MultiStatus) |
236 | (int)response.StatusCode != HttpStatusCode_MultiStatus) |
|
240 | { |
237 | { |
|
241 | throw new wasDAVException((int) response.StatusCode, |
238 | throw new wasDAVException((int)response.StatusCode, |
|
242 | $"Failed retrieving item/folder (Status Code: {response.StatusCode})"); |
239 | $"Failed retrieving item/folder (Status Code: {response.StatusCode})"); |
|
Line 243... | Line 240... | |||
243 | } |
240 | } |
|
244 | |
241 | |
|
Line 267... | Line 264... | |||
267 | public async Task<Stream> Download(string remoteFilePath) |
264 | public async Task<Stream> Download(string remoteFilePath) |
|
268 | { |
265 | { |
|
269 | // Should not have a trailing slash. |
266 | // Should not have a trailing slash. |
|
270 | var downloadUri = await GetServerUrl(remoteFilePath, false).ConfigureAwait(false); |
267 | var downloadUri = await GetServerUrl(remoteFilePath, false).ConfigureAwait(false); |
|
Line 271... | Line 268... | |||
271 | |
268 | |
|
272 | var dictionary = new Dictionary<string, string> {{"translate", "f"}}; |
269 | var dictionary = new Dictionary<string, string> { { "translate", "f" } }; |
|
273 | var response = await HttpRequest(downloadUri.Uri, HttpMethod.Get, dictionary).ConfigureAwait(false); |
270 | var response = await HttpRequest(downloadUri.Uri, HttpMethod.Get, dictionary).ConfigureAwait(false); |
|
274 | if (response.StatusCode != HttpStatusCode.OK) |
271 | if (response.StatusCode != HttpStatusCode.OK) |
|
275 | { |
272 | { |
|
276 | throw new wasDAVException((int) response.StatusCode, "Failed retrieving file."); |
273 | throw new wasDAVException((int)response.StatusCode, "Failed retrieving file."); |
|
277 | } |
274 | } |
|
278 | return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); |
275 | return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); |
|
Line 279... | Line 276... | |||
279 | } |
276 | } |
|
Line 298... | Line 295... | |||
298 | |
295 | |
|
299 | if (response.StatusCode != HttpStatusCode.OK && |
296 | if (response.StatusCode != HttpStatusCode.OK && |
|
300 | response.StatusCode != HttpStatusCode.NoContent && |
297 | response.StatusCode != HttpStatusCode.NoContent && |
|
301 | response.StatusCode != HttpStatusCode.Created) |
298 | response.StatusCode != HttpStatusCode.Created) |
|
302 | { |
299 | { |
|
303 | throw new wasDAVException((int) response.StatusCode, "Failed uploading file."); |
300 | throw new wasDAVException((int)response.StatusCode, "Failed uploading file."); |
|
Line 304... | Line 301... | |||
304 | } |
301 | } |
|
305 | |
302 | |
|
306 | return response.IsSuccessStatusCode; |
303 | return response.IsSuccessStatusCode; |
|
307 | } |
304 | } |
|
308 | finally |
305 | finally |
|
309 | { |
306 | { |
|
310 | response?.Dispose(); |
307 | response?.Dispose(); |
|
Line 311... | Line -... | |||
311 | } |
- | ||
312 | } |
308 | } |
|
313 | |
309 | } |
|
314 | |
310 | |
|
315 | /// <summary> |
311 | /// <summary> |
|
316 | /// Create a directory on the server |
312 | /// Create a directory on the server |
|
Line 328... | Line 324... | |||
328 | try |
324 | try |
|
329 | { |
325 | { |
|
330 | response = await HttpRequest(dirUri.Uri, MkCol).ConfigureAwait(false); |
326 | response = await HttpRequest(dirUri.Uri, MkCol).ConfigureAwait(false); |
|
Line 331... | Line 327... | |||
331 | |
327 | |
|
332 | if (response.StatusCode == HttpStatusCode.Conflict) |
328 | if (response.StatusCode == HttpStatusCode.Conflict) |
|
Line 333... | Line 329... | |||
333 | throw new wasDAVConflictException((int) response.StatusCode, "Failed creating folder."); |
329 | throw new wasDAVConflictException((int)response.StatusCode, "Failed creating folder."); |
|
334 | |
330 | |
|
335 | if (response.StatusCode != HttpStatusCode.OK && |
331 | if (response.StatusCode != HttpStatusCode.OK && |
|
336 | response.StatusCode != HttpStatusCode.NoContent && |
332 | response.StatusCode != HttpStatusCode.NoContent && |
|
337 | response.StatusCode != HttpStatusCode.Created) |
333 | response.StatusCode != HttpStatusCode.Created) |
|
338 | { |
334 | { |
|
Line 339... | Line 335... | |||
339 | throw new wasDAVException((int) response.StatusCode, "Failed creating folder."); |
335 | throw new wasDAVException((int)response.StatusCode, "Failed creating folder."); |
|
340 | } |
336 | } |
|
341 | |
337 | |
|
Line 355... | Line 351... | |||
355 | public async Task DeleteFile(string href) |
351 | public async Task DeleteFile(string href) |
|
356 | { |
352 | { |
|
357 | await Delete((await GetServerUrl(href, false).ConfigureAwait(false)).Uri).ConfigureAwait(false); |
353 | await Delete((await GetServerUrl(href, false).ConfigureAwait(false)).Uri).ConfigureAwait(false); |
|
358 | } |
354 | } |
|
Line 359... | Line -... | |||
359 | |
- | ||
360 | |
355 | |
|
361 | private async Task Delete(Uri listUri) |
356 | private async Task Delete(Uri listUri) |
|
362 | { |
357 | { |
|
Line 363... | Line 358... | |||
363 | var response = await HttpRequest(listUri, HttpMethod.Delete).ConfigureAwait(false); |
358 | var response = await HttpRequest(listUri, HttpMethod.Delete).ConfigureAwait(false); |
|
364 | |
359 | |
|
365 | if (response.StatusCode != HttpStatusCode.OK && |
360 | if (response.StatusCode != HttpStatusCode.OK && |
|
366 | response.StatusCode != HttpStatusCode.NoContent) |
361 | response.StatusCode != HttpStatusCode.NoContent) |
|
367 | { |
362 | { |
|
368 | throw new wasDAVException((int) response.StatusCode, "Failed deleting item."); |
363 | throw new wasDAVException((int)response.StatusCode, "Failed deleting item."); |
|
Line 369... | Line 364... | |||
369 | } |
364 | } |
|
370 | } |
365 | } |
|
Line 385... | Line 380... | |||
385 | await |
380 | await |
|
386 | Move((await GetServerUrl(srcFilePath, false).ConfigureAwait(false)).Uri, |
381 | Move((await GetServerUrl(srcFilePath, false).ConfigureAwait(false)).Uri, |
|
387 | (await GetServerUrl(dstFilePath, false).ConfigureAwait(false)).Uri).ConfigureAwait(false); |
382 | (await GetServerUrl(dstFilePath, false).ConfigureAwait(false)).Uri).ConfigureAwait(false); |
|
388 | } |
383 | } |
|
Line 389... | Line -... | |||
389 | |
- | ||
390 | |
384 | |
|
391 | private async Task<bool> Move(Uri srcUri, Uri dstUri) |
385 | private async Task<bool> Move(Uri srcUri, Uri dstUri) |
|
392 | { |
386 | { |
|
Line 393... | Line 387... | |||
393 | const string requestContent = "MOVE"; |
387 | const string requestContent = "MOVE"; |
|
Line 403... | Line 397... | |||
403 | .ConfigureAwait(false); |
397 | .ConfigureAwait(false); |
|
Line 404... | Line 398... | |||
404 | |
398 | |
|
405 | if (response.StatusCode != HttpStatusCode.OK && |
399 | if (response.StatusCode != HttpStatusCode.OK && |
|
406 | response.StatusCode != HttpStatusCode.Created) |
400 | response.StatusCode != HttpStatusCode.Created) |
|
407 | { |
401 | { |
|
408 | throw new wasDAVException((int) response.StatusCode, "Failed moving file."); |
402 | throw new wasDAVException((int)response.StatusCode, "Failed moving file."); |
|
Line 409... | Line 403... | |||
409 | } |
403 | } |
|
410 | |
404 | |
|
Line 411... | Line 405... | |||
411 | return response.IsSuccessStatusCode; |
405 | return response.IsSuccessStatusCode; |
|
Line 412... | Line 406... | |||
412 | } |
406 | } |
|
Line 413... | Line 407... | |||
413 | |
407 | |
|
414 | #endregion |
408 | #endregion WebDAV operations |
|
Line 506... | Line 500... | |||
506 | private async Task<UriBuilder> GetServerUrl(string path, bool appendTrailingSlash) |
500 | private async Task<UriBuilder> GetServerUrl(string path, bool appendTrailingSlash) |
|
507 | { |
501 | { |
|
508 | // Resolve the base path on the server |
502 | // Resolve the base path on the server |
|
509 | if (_encodedBasePath == null) |
503 | if (_encodedBasePath == null) |
|
510 | { |
504 | { |
|
511 | var baseUri = new UriBuilder(_server) {Path = _basePath}; |
505 | var baseUri = new UriBuilder(_server) { Path = _basePath }; |
|
512 | var root = await Get(baseUri.Uri).ConfigureAwait(false); |
506 | var root = await Get(baseUri.Uri).ConfigureAwait(false); |
|
Line 513... | Line 507... | |||
513 | |
507 | |
|
514 | _encodedBasePath = root.Href; |
508 | _encodedBasePath = root.Href; |
|
Line 515... | Line -... | |||
515 | } |
- | ||
516 | |
509 | } |
|
517 | |
510 | |
|
518 | // If we've been asked for the "root" folder |
511 | // If we've been asked for the "root" folder |
|
519 | if (string.IsNullOrEmpty(path)) |
512 | if (string.IsNullOrEmpty(path)) |
|
520 | { |
513 | { |
|
Line 524... | Line 517... | |||
524 | { |
517 | { |
|
525 | return new UriBuilder(absoluteBaseUri); |
518 | return new UriBuilder(absoluteBaseUri); |
|
526 | } |
519 | } |
|
Line 527... | Line 520... | |||
527 | |
520 | |
|
528 | // Otherwise, use the resolved base path relatively to the server |
521 | // Otherwise, use the resolved base path relatively to the server |
|
529 | var baseUri = new UriBuilder(_server) {Path = _encodedBasePath}; |
522 | var baseUri = new UriBuilder(_server) { Path = _encodedBasePath }; |
|
530 | return baseUri; |
523 | return baseUri; |
|
Line 531... | Line 524... | |||
531 | } |
524 | } |
|
532 | |
525 | |
|
Line 564... | Line 557... | |||
564 | finalPath = finalPath.TrimEnd('/') + "/"; |
557 | finalPath = finalPath.TrimEnd('/') + "/"; |
|
Line 565... | Line 558... | |||
565 | |
558 | |
|
566 | baseUri.Path = finalPath; |
559 | baseUri.Path = finalPath; |
|
Line 567... | Line -... | |||
567 | } |
- | ||
568 | |
560 | } |
|
569 | |
561 | |
|
570 | return baseUri; |
562 | return baseUri; |
|
Line 571... | Line 563... | |||
571 | } |
563 | } |
|
572 | } |
564 | } |
|
573 | |
565 | |
|
574 | public void Dispose() |
566 | public void Dispose() |
|
575 | { |
567 | { |
|
Line 576... | Line 568... | |||
576 | _client?.Dispose(); |
568 | _client?.Dispose(); |
|
577 | _uploadClient?.Dispose(); |
569 | _uploadClient?.Dispose(); |
|
578 | } |
- | ||
579 | |
570 | } |
|
- | 571 | |