wasDAVClient – Diff between revs 2 and 3
?pathlinks?
Rev 2 | Rev 3 | |||
---|---|---|---|---|
Line 12... | Line 12... | |||
12 | |
12 | |
|
13 | namespace wasDAVClient |
13 | namespace wasDAVClient |
|
14 | { |
14 | { |
|
15 | public class Client : IClient |
15 | public class Client : IClient |
|
16 | { |
- | ||
17 | private static readonly HttpMethod PropFind = new HttpMethod("PROPFIND"); |
- | ||
18 | private static readonly HttpMethod MoveMethod = new HttpMethod("MOVE"); |
- | ||
19 | |
- | ||
20 | private static readonly HttpMethod MkCol = new HttpMethod(WebRequestMethods.Http.MkCol); |
- | ||
21 | |
16 | { |
|
Line 22... | Line 17... | |||
22 | private const int HttpStatusCode_MultiStatus = 207; |
17 | private const int HttpStatusCode_MultiStatus = 207; |
|
23 | |
18 | |
|
24 | // http://webdav.org/specs/rfc4918.html#METHOD_PROPFIND |
19 | // http://webdav.org/specs/rfc4918.html#METHOD_PROPFIND |
|
Line 36... | Line 31... | |||
36 | //" <getetag/>" + |
31 | //" <getetag/>" + |
|
37 | //" <resourcetype/>" + |
32 | //" <resourcetype/>" + |
|
38 | //" </prop> " + |
33 | //" </prop> " + |
|
39 | "</propfind>"; |
34 | "</propfind>"; |
|
Line -... | Line 35... | |||
- | 35 | |
||
- | 36 | private static readonly HttpMethod PropFind = new HttpMethod("PROPFIND"); |
||
- | 37 | private static readonly HttpMethod MoveMethod = new HttpMethod("MOVE"); |
||
- | 38 | |
||
- | 39 | private static readonly HttpMethod MkCol = new HttpMethod(WebRequestMethods.Http.MkCol); |
||
40 | |
40 | |
|
Line 41... | Line 41... | |||
41 | private static readonly string AssemblyVersion = typeof(IClient).Assembly.GetName().Version.ToString(); |
41 | private static readonly string AssemblyVersion = typeof(IClient).Assembly.GetName().Version.ToString(); |
|
42 | |
42 | |
|
43 | private readonly HttpClient _client; |
- | ||
44 | private readonly HttpClient _uploadClient; |
43 | private readonly HttpClient _client; |
|
Line 45... | Line 44... | |||
45 | private string _server; |
44 | private readonly HttpClient _uploadClient; |
|
- | 45 | private string _basePath = "/"; |
||
- | 46 | |
||
Line -... | Line 47... | |||
- | 47 | private string _encodedBasePath; |
||
- | 48 | private string _server; |
||
- | 49 | |
||
Line -... | Line 50... | |||
- | 50 | |
||
- | 51 | public Client(NetworkCredential credential = null) |
||
- | 52 | { |
||
- | 53 | var handler = new HttpClientHandler(); |
||
- | 54 | |
||
- | 55 | if (handler.SupportsProxy) |
||
- | 56 | handler.Proxy = WebRequest.DefaultWebProxy; |
||
- | 57 | |
||
- | 58 | if (handler.SupportsAutomaticDecompression) |
||
- | 59 | handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; |
||
- | 60 | |
||
- | 61 | if (credential != null) |
||
- | 62 | { |
||
- | 63 | handler.Credentials = credential; |
||
- | 64 | handler.PreAuthenticate = true; |
||
- | 65 | } |
||
- | 66 | |
||
- | 67 | _client = new HttpClient(handler); |
||
- | 68 | _client.Timeout = TimeSpan.FromSeconds(Timeout); |
||
- | 69 | _client.DefaultRequestHeaders.ExpectContinue = false; |
||
Line 46... | Line 70... | |||
46 | private string _basePath = "/"; |
70 | |
|
Line 47... | Line 71... | |||
47 | |
71 | _uploadClient = new HttpClient(handler); |
|
48 | private string _encodedBasePath; |
72 | _uploadClient.Timeout = TimeSpan.FromSeconds(Timeout); |
|
49 | |
73 | _uploadClient.DefaultRequestHeaders.ExpectContinue = false; |
|
50 | |
74 | } |
|
51 | |
75 | |
|
52 | #region WebDAV connection parameters |
- | ||
53 | |
- | ||
54 | /// <summary> |
76 | #region WebDAV connection parameters |
|
55 | /// Specify the WebDAV hostname (required). |
- | ||
56 | /// </summary> |
77 | |
|
57 | public string Server |
78 | /// <summary> |
|
58 | { |
79 | /// Specify the WebDAV hostname (required). |
|
59 | get |
80 | /// </summary> |
|
60 | { |
81 | public string Server |
|
61 | return _server; |
82 | { |
|
Line 62... | Line 83... | |||
62 | } |
83 | get { return _server; } |
|
63 | set |
84 | set |
|
64 | { |
85 | { |
|
65 | value = value.TrimEnd('/'); |
86 | value = value.TrimEnd('/'); |
|
66 | _server = value; |
87 | _server = value; |
|
67 | } |
- | ||
68 | } |
- | ||
69 | |
88 | } |
|
70 | /// <summary> |
- | ||
71 | /// Specify the path of a WebDAV directory to use as 'root' (default: /) |
89 | } |
|
72 | /// </summary> |
90 | |
|
73 | public string BasePath |
91 | /// <summary> |
|
74 | { |
92 | /// Specify the path of a WebDAV directory to use as 'root' (default: /) |
|
75 | get |
93 | /// </summary> |
|
Line 85... | Line 103... | |||
85 | _basePath = "/" + value + "/"; |
103 | _basePath = "/" + value + "/"; |
|
86 | } |
104 | } |
|
87 | } |
105 | } |
|
Line 88... | Line 106... | |||
88 | |
106 | |
|
89 | /// <summary> |
107 | /// <summary> |
|
90 | /// Specify an port (default: null = auto-detect) |
108 | /// Specify an port (default: null = auto-detect) |
|
91 | /// </summary> |
109 | /// </summary> |
|
92 | public int? Port |
- | ||
93 | { |
- | ||
94 | get; set; |
- | ||
Line 95... | Line 110... | |||
95 | } |
110 | public int? Port { get; set; } |
|
96 | |
111 | |
|
97 | /// <summary> |
112 | /// <summary> |
|
98 | /// Specify the UserAgent (and UserAgent version) string to use in requests |
113 | /// Specify the UserAgent (and UserAgent version) string to use in requests |
|
99 | /// </summary> |
- | ||
100 | public string UserAgent |
- | ||
101 | { |
- | ||
Line 102... | Line 114... | |||
102 | get; set; |
114 | /// </summary> |
|
103 | } |
115 | public string UserAgent { get; set; } |
|
104 | |
116 | |
|
105 | /// <summary> |
117 | /// <summary> |
|
106 | /// Specify the UserAgent (and UserAgent version) string to use in requests |
- | ||
107 | /// </summary> |
- | ||
108 | public string UserAgentVersion |
- | ||
109 | { |
- | ||
110 | get; set; |
- | ||
111 | } |
- | ||
Line 112... | Line -... | |||
112 | |
- | ||
113 | #endregion |
- | ||
114 | |
- | ||
115 | |
- | ||
116 | public Client(NetworkCredential credential = null, TimeSpan? timeout = null, IWebProxy proxy = null) |
- | ||
117 | { |
- | ||
118 | var handler = new HttpClientHandler(); |
- | ||
119 | if (proxy != null && handler.SupportsProxy) |
- | ||
120 | handler.Proxy = proxy; |
118 | /// Specify the UserAgent (and UserAgent version) string to use in requests |
|
121 | if (handler.SupportsAutomaticDecompression) |
119 | /// </summary> |
|
122 | handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; |
- | ||
123 | if (credential != null) |
- | ||
124 | { |
- | ||
125 | handler.Credentials = credential; |
- | ||
126 | handler.PreAuthenticate = true; |
- | ||
127 | } |
- | ||
128 | |
- | ||
129 | _client = new HttpClient(handler); |
120 | public string UserAgentVersion { get; set; } |
|
130 | _client.DefaultRequestHeaders.ExpectContinue = false; |
- | ||
131 | |
- | ||
132 | if (timeout != null) |
121 | |
|
133 | { |
- | ||
Line 134... | Line 122... | |||
134 | _uploadClient = new HttpClient(handler); |
122 | /// <summary> |
|
Line 135... | Line 123... | |||
135 | _uploadClient.DefaultRequestHeaders.ExpectContinue = false; |
123 | /// The HTTP request timeout in seconds. |
|
Line 136... | Line 124... | |||
136 | _uploadClient.Timeout = timeout.Value; |
124 | /// </summary> |
|
137 | } |
125 | public int Timeout { get; set; } = 60; |
|
138 | |
126 | |
|
139 | } |
127 | #endregion |
|
140 | |
128 | |
|
141 | #region WebDAV operations |
129 | #region WebDAV operations |
|
142 | |
130 | |
|
Line 155... | Line 143... | |||
155 | if (depth != null) |
143 | if (depth != null) |
|
156 | { |
144 | { |
|
157 | headers.Add("Depth", depth.ToString()); |
145 | headers.Add("Depth", depth.ToString()); |
|
158 | } |
146 | } |
|
Line 159... | Line -... | |||
159 | |
- | ||
160 | |
147 | |
|
Line 161... | Line 148... | |||
161 | HttpResponseMessage response = null; |
148 | HttpResponseMessage response = null; |
|
162 | |
149 | |
|
- | 150 | try |
||
- | 151 | { |
||
163 | try |
152 | response = |
|
- | 153 | await |
||
Line 164... | Line 154... | |||
164 | { |
154 | HttpRequest(listUri.Uri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)) |
|
165 | response = await HttpRequest(listUri.Uri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)).ConfigureAwait(false); |
155 | .ConfigureAwait(false); |
|
166 | |
156 | |
|
167 | if (response.StatusCode != HttpStatusCode.OK && |
157 | if (response.StatusCode != HttpStatusCode.OK && |
|
168 | (int)response.StatusCode != HttpStatusCode_MultiStatus) |
158 | (int) response.StatusCode != HttpStatusCode_MultiStatus) |
|
Line 169... | Line 159... | |||
169 | { |
159 | { |
|
170 | throw new wasDAVException((int)response.StatusCode, "Failed retrieving items in folder."); |
160 | throw new wasDAVException((int) response.StatusCode, "Failed retrieving items in folder."); |
|
171 | } |
161 | } |
|
Line 199... | Line 189... | |||
199 | } |
189 | } |
|
200 | } |
190 | } |
|
201 | } |
191 | } |
|
202 | return result; |
192 | return result; |
|
203 | } |
193 | } |
|
204 | |
- | ||
205 | } |
194 | } |
|
206 | finally |
195 | finally |
|
207 | { |
196 | { |
|
208 | if (response != null) |
197 | if (response != null) |
|
209 | response.Dispose(); |
198 | response.Dispose(); |
|
210 | } |
199 | } |
|
211 | } |
200 | } |
|
Line 212... | Line 201... | |||
212 | |
201 | |
|
213 | /// <summary> |
202 | /// <summary> |
|
214 | /// List all files present on the server. |
203 | /// List all files present on the server. |
|
215 | /// </summary> |
204 | /// </summary> |
|
216 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
205 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
|
217 | public async Task<Item> GetFolder(string path = "/") |
206 | public async Task<Item> GetFolder(string path = "/") |
|
218 | { |
207 | { |
|
219 | var listUri = await GetServerUrl(path, true).ConfigureAwait(false); |
208 | var listUri = await GetServerUrl(path, true).ConfigureAwait(false); |
|
220 | return await Get(listUri.Uri, path).ConfigureAwait(false); |
209 | return await Get(listUri.Uri, path).ConfigureAwait(false); |
|
Line 221... | Line 210... | |||
221 | } |
210 | } |
|
222 | |
211 | |
|
223 | /// <summary> |
212 | /// <summary> |
|
224 | /// List all files present on the server. |
213 | /// List all files present on the server. |
|
225 | /// </summary> |
214 | /// </summary> |
|
226 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
215 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
|
227 | public async Task<Item> GetFile(string path = "/") |
216 | public async Task<Item> GetFile(string path = "/") |
|
228 | { |
217 | { |
|
229 | var listUri = await GetServerUrl(path, false).ConfigureAwait(false); |
218 | var listUri = await GetServerUrl(path, false).ConfigureAwait(false); |
|
Line 230... | Line 219... | |||
230 | return await Get(listUri.Uri, path).ConfigureAwait(false); |
219 | return await Get(listUri.Uri, path).ConfigureAwait(false); |
|
231 | } |
220 | } |
|
232 | |
221 | |
|
233 | |
222 | |
|
234 | /// <summary> |
223 | /// <summary> |
|
235 | /// List all files present on the server. |
224 | /// List all files present on the server. |
|
236 | /// </summary> |
- | ||
237 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
225 | /// </summary> |
|
238 | private async Task<Item> Get(Uri listUri, string path) |
226 | /// <returns>A list of files (entries without a trailing slash) and directories (entries with a trailing slash)</returns> |
|
239 | { |
227 | private async Task<Item> Get(Uri listUri, string path) |
|
Line 240... | Line 228... | |||
240 | |
228 | { |
|
Line 241... | Line 229... | |||
241 | // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4 |
229 | // Depth header: http://webdav.org/specs/rfc4918.html#rfc.section.9.1.4 |
|
242 | IDictionary<string, string> headers = new Dictionary<string, string>(); |
230 | IDictionary<string, string> headers = new Dictionary<string, string>(); |
|
- | 231 | headers.Add("Depth", "0"); |
||
- | 232 | |
||
243 | headers.Add("Depth", "0"); |
233 | |
|
- | 234 | HttpResponseMessage response = null; |
||
Line 244... | Line 235... | |||
244 | |
235 | |
|
245 | |
236 | try |
|
246 | HttpResponseMessage response = null; |
237 | { |
|
- | 238 | response = |
||
247 | |
239 | await |
|
248 | try |
240 | HttpRequest(listUri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)) |
|
Line 249... | Line 241... | |||
249 | { |
241 | .ConfigureAwait(false); |
|
250 | response = await HttpRequest(listUri, PropFind, headers, Encoding.UTF8.GetBytes(PropFindRequestContent)).ConfigureAwait(false); |
242 | |
|
251 | |
243 | if (response.StatusCode != HttpStatusCode.OK && |
|
Line 273... | Line 265... | |||
273 | response.Dispose(); |
265 | response.Dispose(); |
|
274 | } |
266 | } |
|
275 | } |
267 | } |
|
Line 276... | Line 268... | |||
276 | |
268 | |
|
277 | /// <summary> |
269 | /// <summary> |
|
278 | /// Download a file from the server |
270 | /// Download a file from the server |
|
279 | /// </summary> |
271 | /// </summary> |
|
280 | /// <param name="remoteFilePath">Source path and filename of the file on the server</param> |
272 | /// <param name="remoteFilePath">Source path and filename of the file on the server</param> |
|
281 | public async Task<Stream> Download(string remoteFilePath) |
273 | public async Task<Stream> Download(string remoteFilePath) |
|
282 | { |
274 | { |
|
283 | // Should not have a trailing slash. |
275 | // Should not have a trailing slash. |
|
Line 284... | Line 276... | |||
284 | var downloadUri = await GetServerUrl(remoteFilePath, false).ConfigureAwait(false); |
276 | var downloadUri = await GetServerUrl(remoteFilePath, false).ConfigureAwait(false); |
|
285 | |
277 | |
|
286 | var dictionary = new Dictionary<string, string> { { "translate", "f" } }; |
278 | var dictionary = new Dictionary<string, string> {{"translate", "f"}}; |
|
287 | var response = await HttpRequest(downloadUri.Uri, HttpMethod.Get, dictionary).ConfigureAwait(false); |
279 | var response = await HttpRequest(downloadUri.Uri, HttpMethod.Get, dictionary).ConfigureAwait(false); |
|
288 | if (response.StatusCode != HttpStatusCode.OK) |
280 | if (response.StatusCode != HttpStatusCode.OK) |
|
289 | { |
281 | { |
|
290 | throw new wasDAVException((int)response.StatusCode, "Failed retrieving file."); |
282 | throw new wasDAVException((int) response.StatusCode, "Failed retrieving file."); |
|
291 | } |
283 | } |
|
Line 292... | Line 284... | |||
292 | return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); |
284 | return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); |
|
293 | } |
285 | } |
|
294 | |
286 | |
|
295 | /// <summary> |
287 | /// <summary> |
|
296 | /// Download a file from the server |
288 | /// Download a file from the server |
|
297 | /// </summary> |
289 | /// </summary> |
|
298 | /// <param name="remoteFilePath">Source path and filename of the file on the server</param> |
290 | /// <param name="remoteFilePath">Source path and filename of the file on the server</param> |
|
299 | /// <param name="content"></param> |
291 | /// <param name="content"></param> |
|
300 | /// <param name="name"></param> |
292 | /// <param name="name"></param> |
|
- | 293 | public async Task<bool> Upload(string remoteFilePath, Stream content, string name) |
||
301 | public async Task<bool> Upload(string remoteFilePath, Stream content, string name) |
294 | { |
|
Line 302... | Line 295... | |||
302 | { |
295 | // Should not have a trailing slash. |
|
Line 303... | Line 296... | |||
303 | // Should not have a trailing slash. |
296 | var uploadUri = |
|
304 | var uploadUri = await GetServerUrl(remoteFilePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false); |
297 | await GetServerUrl(remoteFilePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false); |
|
Line 311... | Line 304... | |||
311 | |
304 | |
|
312 | if (response.StatusCode != HttpStatusCode.OK && |
305 | if (response.StatusCode != HttpStatusCode.OK && |
|
313 | response.StatusCode != HttpStatusCode.NoContent && |
306 | response.StatusCode != HttpStatusCode.NoContent && |
|
314 | response.StatusCode != HttpStatusCode.Created) |
307 | response.StatusCode != HttpStatusCode.Created) |
|
315 | { |
308 | { |
|
316 | throw new wasDAVException((int)response.StatusCode, "Failed uploading file."); |
309 | throw new wasDAVException((int) response.StatusCode, "Failed uploading file."); |
|
Line 317... | Line 310... | |||
317 | } |
310 | } |
|
318 | |
311 | |
|
319 | return response.IsSuccessStatusCode; |
312 | return response.IsSuccessStatusCode; |
|
320 | } |
313 | } |
|
321 | finally |
314 | finally |
|
322 | { |
315 | { |
|
323 | if (response != null) |
316 | if (response != null) |
|
324 | response.Dispose(); |
- | ||
325 | } |
317 | response.Dispose(); |
|
Line 326... | Line 318... | |||
326 | |
318 | } |
|
327 | } |
319 | } |
|
328 | |
320 | |
|
329 | |
321 | |
|
330 | /// <summary> |
322 | /// <summary> |
|
331 | /// Create a directory on the server |
323 | /// Create a directory on the server |
|
332 | /// </summary> |
324 | /// </summary> |
|
333 | /// <param name="remotePath">Destination path of the directory on the server</param> |
325 | /// <param name="remotePath">Destination path of the directory on the server</param> |
|
- | 326 | /// <param name="name"></param> |
||
334 | /// <param name="name"></param> |
327 | public async Task<bool> CreateDir(string remotePath, string name) |
|
Line 335... | Line 328... | |||
335 | public async Task<bool> CreateDir(string remotePath, string name) |
328 | { |
|
Line 336... | Line 329... | |||
336 | { |
329 | // Should not have a trailing slash. |
|
337 | // Should not have a trailing slash. |
330 | var dirUri = |
|
338 | var dirUri = await GetServerUrl(remotePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false); |
331 | await GetServerUrl(remotePath.TrimEnd('/') + "/" + name.TrimStart('/'), false).ConfigureAwait(false); |
|
Line 339... | Line 332... | |||
339 | |
332 | |
|
340 | HttpResponseMessage response = null; |
333 | HttpResponseMessage response = null; |
|
Line 341... | Line 334... | |||
341 | |
334 | |
|
342 | try |
335 | try |
|
343 | { |
336 | { |
|
344 | response = await HttpRequest(dirUri.Uri, MkCol).ConfigureAwait(false); |
337 | response = await HttpRequest(dirUri.Uri, MkCol).ConfigureAwait(false); |
|
345 | |
338 | |
|
346 | if (response.StatusCode == HttpStatusCode.Conflict) |
339 | if (response.StatusCode == HttpStatusCode.Conflict) |
|
Line 347... | Line 340... | |||
347 | throw new wasDAVConflictException((int)response.StatusCode, "Failed creating folder."); |
340 | throw new wasDAVConflictException((int) response.StatusCode, "Failed creating folder."); |
|
348 | |
341 | |
|
349 | if (response.StatusCode != HttpStatusCode.OK && |
342 | if (response.StatusCode != HttpStatusCode.OK && |
|
Line 380... | Line 373... | |||
380 | var response = await HttpRequest(listUri, HttpMethod.Delete).ConfigureAwait(false); |
373 | var response = await HttpRequest(listUri, HttpMethod.Delete).ConfigureAwait(false); |
|
Line 381... | Line 374... | |||
381 | |
374 | |
|
382 | if (response.StatusCode != HttpStatusCode.OK && |
375 | if (response.StatusCode != HttpStatusCode.OK && |
|
383 | response.StatusCode != HttpStatusCode.NoContent) |
376 | response.StatusCode != HttpStatusCode.NoContent) |
|
384 | { |
377 | { |
|
385 | throw new wasDAVException((int)response.StatusCode, "Failed deleting item."); |
378 | throw new wasDAVException((int) response.StatusCode, "Failed deleting item."); |
|
386 | } |
379 | } |
|
Line 387... | Line 380... | |||
387 | } |
380 | } |
|
388 | |
381 | |
|
389 | public async Task<bool> MoveFolder(string srcFolderPath, string dstFolderPath) |
382 | public async Task<bool> MoveFolder(string srcFolderPath, string dstFolderPath) |
|
390 | { |
383 | { |
|
391 | // Should have a trailing slash. |
384 | // Should have a trailing slash. |
|
Line 392... | Line 385... | |||
392 | var srcUri = await GetServerUrl(srcFolderPath, true).ConfigureAwait(false); |
385 | var srcUri = await GetServerUrl(srcFolderPath, true).ConfigureAwait(false); |
|
393 | var dstUri = await GetServerUrl(dstFolderPath, true).ConfigureAwait(false); |
- | ||
394 | |
386 | var dstUri = await GetServerUrl(dstFolderPath, true).ConfigureAwait(false); |
|
Line 395... | Line 387... | |||
395 | return await Move(srcUri.Uri, dstUri.Uri).ConfigureAwait(false); |
387 | |
|
396 | |
388 | return await Move(srcUri.Uri, dstUri.Uri).ConfigureAwait(false); |
|
397 | } |
389 | } |
|
Line 411... | Line 403... | |||
411 | const string requestContent = "MOVE"; |
403 | const string requestContent = "MOVE"; |
|
Line 412... | Line 404... | |||
412 | |
404 | |
|
413 | IDictionary<string, string> headers = new Dictionary<string, string>(); |
405 | IDictionary<string, string> headers = new Dictionary<string, string>(); |
|
Line -... | Line 406... | |||
- | 406 | headers.Add("Destination", dstUri.ToString()); |
||
- | 407 | |
||
414 | headers.Add("Destination", dstUri.ToString()); |
408 | var response = |
|
- | 409 | await |
||
Line 415... | Line 410... | |||
415 | |
410 | HttpRequest(srcUri, MoveMethod, headers, Encoding.UTF8.GetBytes(requestContent)) |
|
416 | var response = await HttpRequest(srcUri, MoveMethod, headers, Encoding.UTF8.GetBytes(requestContent)).ConfigureAwait(false); |
411 | .ConfigureAwait(false); |
|
417 | |
412 | |
|
418 | if (response.StatusCode != HttpStatusCode.OK && |
413 | if (response.StatusCode != HttpStatusCode.OK && |
|
419 | response.StatusCode != HttpStatusCode.Created) |
414 | response.StatusCode != HttpStatusCode.Created) |
|
Line 420... | Line 415... | |||
420 | { |
415 | { |
|
421 | throw new wasDAVException((int)response.StatusCode, "Failed moving file."); |
416 | throw new wasDAVException((int) response.StatusCode, "Failed moving file."); |
|
Line 422... | Line 417... | |||
422 | } |
417 | } |
|
Line 423... | Line 418... | |||
423 | |
418 | |
|
Line 424... | Line 419... | |||
424 | return response.IsSuccessStatusCode; |
419 | return response.IsSuccessStatusCode; |
|
425 | } |
420 | } |
|
426 | |
421 | |
|
427 | #endregion |
422 | #endregion |
|
428 | |
423 | |
|
429 | #region Server communication |
424 | #region Server communication |
|
430 | |
425 | |
|
431 | /// <summary> |
426 | /// <summary> |
|
- | 427 | /// Perform the WebDAV call and fire the callback when finished. |
||
432 | /// Perform the WebDAV call and fire the callback when finished. |
428 | /// </summary> |
|
433 | /// </summary> |
429 | /// <param name="uri"></param> |
|
434 | /// <param name="uri"></param> |
430 | /// <param name="method"></param> |
|
435 | /// <param name="method"></param> |
431 | /// <param name="headers"></param> |
|
436 | /// <param name="headers"></param> |
432 | /// <param name="content"></param> |
|
Line 445... | Line 441... | |||
445 | else |
441 | else |
|
446 | request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion)); |
442 | request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion)); |
|
Line 447... | Line 443... | |||
447 | |
443 | |
|
448 | if (headers != null) |
444 | if (headers != null) |
|
449 | { |
445 | { |
|
450 | foreach (string key in headers.Keys) |
446 | foreach (var key in headers.Keys) |
|
451 | { |
447 | { |
|
452 | request.Headers.Add(key, headers[key]); |
448 | request.Headers.Add(key, headers[key]); |
|
453 | } |
449 | } |
|
Line 463... | Line 459... | |||
463 | return await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); |
459 | return await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false); |
|
464 | } |
460 | } |
|
465 | } |
461 | } |
|
Line 466... | Line 462... | |||
466 | |
462 | |
|
467 | /// <summary> |
463 | /// <summary> |
|
468 | /// Perform the WebDAV call and fire the callback when finished. |
464 | /// Perform the WebDAV call and fire the callback when finished. |
|
469 | /// </summary> |
465 | /// </summary> |
|
470 | /// <param name="uri"></param> |
466 | /// <param name="uri"></param> |
|
471 | /// <param name="headers"></param> |
467 | /// <param name="headers"></param> |
|
472 | /// <param name="method"></param> |
468 | /// <param name="method"></param> |
|
473 | /// <param name="content"></param> |
469 | /// <param name="content"></param> |
|
- | 470 | private async Task<HttpResponseMessage> HttpUploadRequest(Uri uri, HttpMethod method, Stream content, |
||
474 | private async Task<HttpResponseMessage> HttpUploadRequest(Uri uri, HttpMethod method, Stream content, IDictionary<string, string> headers = null) |
471 | IDictionary<string, string> headers = null) |
|
475 | { |
472 | { |
|
476 | using (var request = new HttpRequestMessage(method, uri)) |
473 | using (var request = new HttpRequestMessage(method, uri)) |
|
477 | { |
474 | { |
|
478 | request.Headers.Connection.Add("Keep-Alive"); |
475 | request.Headers.Connection.Add("Keep-Alive"); |
|
Line 481... | Line 478... | |||
481 | else |
478 | else |
|
482 | request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion)); |
479 | request.Headers.UserAgent.Add(new ProductInfoHeaderValue("WebDAVClient", AssemblyVersion)); |
|
Line 483... | Line 480... | |||
483 | |
480 | |
|
484 | if (headers != null) |
481 | if (headers != null) |
|
485 | { |
482 | { |
|
486 | foreach (string key in headers.Keys) |
483 | foreach (var key in headers.Keys) |
|
487 | { |
484 | { |
|
488 | request.Headers.Add(key, headers[key]); |
485 | request.Headers.Add(key, headers[key]); |
|
489 | } |
486 | } |
|
Line 499... | Line 496... | |||
499 | return await client.SendAsync(request).ConfigureAwait(false); |
496 | return await client.SendAsync(request).ConfigureAwait(false); |
|
500 | } |
497 | } |
|
501 | } |
498 | } |
|
Line 502... | Line 499... | |||
502 | |
499 | |
|
503 | /// <summary> |
500 | /// <summary> |
|
504 | /// Try to create an Uri with kind UriKind.Absolute |
501 | /// Try to create an Uri with kind UriKind.Absolute |
|
505 | /// This particular implementation also works on Mono/Linux |
502 | /// This particular implementation also works on Mono/Linux |
|
506 | /// It seems that on Mono it is expected behaviour that uris |
503 | /// It seems that on Mono it is expected behaviour that uris |
|
507 | /// of kind /a/b are indeed absolute uris since it referes to a file in /a/b. |
504 | /// of kind /a/b are indeed absolute uris since it referes to a file in /a/b. |
|
508 | /// https://bugzilla.xamarin.com/show_bug.cgi?id=30854 |
505 | /// https://bugzilla.xamarin.com/show_bug.cgi?id=30854 |
|
509 | /// </summary> |
506 | /// </summary> |
|
510 | /// <param name="uriString"></param> |
507 | /// <param name="uriString"></param> |
|
511 | /// <param name="uriResult"></param> |
508 | /// <param name="uriResult"></param> |
|
512 | /// <returns></returns> |
509 | /// <returns></returns> |
|
Line 518... | Line 515... | |||
518 | private async Task<UriBuilder> GetServerUrl(string path, bool appendTrailingSlash) |
515 | private async Task<UriBuilder> GetServerUrl(string path, bool appendTrailingSlash) |
|
519 | { |
516 | { |
|
520 | // Resolve the base path on the server |
517 | // Resolve the base path on the server |
|
521 | if (_encodedBasePath == null) |
518 | if (_encodedBasePath == null) |
|
522 | { |
519 | { |
|
523 | var baseUri = new UriBuilder(_server) { Path = _basePath }; |
520 | var baseUri = new UriBuilder(_server) {Path = _basePath}; |
|
524 | var root = await Get(baseUri.Uri, null).ConfigureAwait(false); |
521 | var root = await Get(baseUri.Uri, null).ConfigureAwait(false); |
|
Line 525... | Line 522... | |||
525 | |
522 | |
|
526 | _encodedBasePath = root.Href; |
523 | _encodedBasePath = root.Href; |
|
Line 536... | Line 533... | |||
536 | { |
533 | { |
|
537 | return new UriBuilder(absoluteBaseUri); |
534 | return new UriBuilder(absoluteBaseUri); |
|
538 | } |
535 | } |
|
Line 539... | Line 536... | |||
539 | |
536 | |
|
540 | // Otherwise, use the resolved base path relatively to the server |
537 | // Otherwise, use the resolved base path relatively to the server |
|
541 | var baseUri = new UriBuilder(_server) { Path = _encodedBasePath }; |
538 | var baseUri = new UriBuilder(_server) {Path = _encodedBasePath}; |
|
542 | return baseUri; |
539 | return baseUri; |
|
Line 543... | Line 540... | |||
543 | } |
540 | } |
|
544 | |
541 | |
|
Line 583... | Line 580... | |||
583 | } |
580 | } |
|
584 | } |
581 | } |
|
Line 585... | Line 582... | |||
585 | |
582 | |
|
586 | #endregion |
583 | #endregion |
|
587 | } |
584 | } |
|
588 | } |
585 | } |