Revision 4d301e8e trunk/Pithos.Network/CloudFilesClient.cs

b/trunk/Pithos.Network/CloudFilesClient.cs
9 9
using System.Security.Cryptography;
10 10
using System.Text;
11 11
using System.Threading.Tasks;
12
using Hammock;
13
using Hammock.Caching;
14
using Hammock.Retries;
15
using Hammock.Serialization;
16
using Hammock.Tasks;
17
using Hammock.Web;
18 12
using Newtonsoft.Json;
19 13
using Pithos.Interfaces;
14
using WebHeaderCollection = System.Net.WebHeaderCollection;
20 15

  
21 16
namespace Pithos.Network
22 17
{
......
24 19
    public class CloudFilesClient:ICloudClient
25 20
    {
26 21

  
27
        private RestClient _client;
22
        private PithosClient _client;
28 23
        private readonly TimeSpan _shortTimeout = TimeSpan.FromSeconds(10);
29
        private readonly int _retries = 5;
30
        private RetryPolicy _retryPolicy;
24
        private readonly int _retries = 5;        
31 25
        public string ApiKey { get; set; }
32 26
        public string UserName { get; set; }
33 27
        public Uri StorageUrl { get; set; }
......
63 57
            UserName = userName;
64 58
            ApiKey = apiKey;
65 59
            
66
            var proxy = Proxy != null ? Proxy.ToString() : null;
67 60
            if (UsePithos)
68 61
            {
69 62
                Token = ApiKey;
......
74 67
            {
75 68

  
76 69
                string authUrl = String.Format("{0}/{1}", AuthenticationUrl, VersionPath);
77
                var authClient = new RestClient {Path = authUrl, Proxy = proxy};                
70
                var authClient = new PithosClient{BaseAddress= authUrl};
71
                if (Proxy != null)
72
                    authClient.Proxy = new WebProxy(Proxy);
78 73

  
79
                authClient.AddHeader("X-Auth-User", UserName);
80
                authClient.AddHeader("X-Auth-Key", ApiKey);
74
                authClient.Headers.Add("X-Auth-User", UserName);
75
                authClient.Headers.Add("X-Auth-Key", ApiKey);
81 76

  
82
                var response = authClient.Request();
77
                var response = authClient.DownloadStringWithRetry("",3);
83 78

  
84
                ThrowIfNotStatusOK(response, "Authentication failed");
79
                authClient.AssertStatusOK("Authentication failed");
85 80

  
86
                var keys = response.Headers.AllKeys.AsQueryable();
81
                //var keys = authClient.ResponseHeaders.AllKeys.AsQueryable();
87 82

  
88
                string storageUrl = GetHeaderValue("X-Storage-Url", response, keys);
83
                string storageUrl = authClient.GetHeaderValue("X-Storage-Url");
89 84
                if (String.IsNullOrWhiteSpace(storageUrl))
90 85
                    throw new InvalidOperationException("Failed to obtain storage url");
91 86
                StorageUrl = new Uri(storageUrl);
92 87

  
93
                var token = GetHeaderValue("X-Auth-Token", response, keys);
88
                var token = authClient.GetHeaderValue("X-Auth-Token");
94 89
                if (String.IsNullOrWhiteSpace(token))
95 90
                    throw new InvalidOperationException("Failed to obtain token url");
96 91
                Token = token;
97 92
            }
98 93

  
99
            _retryPolicy = new RetryPolicy { RetryCount = _retries };
100
            _retryPolicy.RetryConditions.Add(new TimeoutRetryCondition());
94
            /*_retryPolicy = new RetryPolicy { RetryCount = _retries };
95
            _retryPolicy.RetryConditions.Add(new TimeoutRetryCondition());*/
101 96

  
102
            _client = new RestClient { Authority = StorageUrl.AbsoluteUri, Path = UserName, Proxy = proxy };
103
            _client.FileProgress += OnFileProgress;
97
            _client = new PithosClient{
98
                BaseAddress  = StorageUrl.AbsoluteUri,                
99
                Timeout=10000,
100
                Retries=3};
101
            if (Proxy!=null)
102
                _client.Proxy = new WebProxy(Proxy);
103
            //_client.FileProgress += OnFileProgress;
104 104
            
105
            _client.AddHeader("X-Auth-Token", Token);
105
            _client.Headers.Add("X-Auth-Token", Token);
106 106
            /*if (UsePithos)
107 107
            {
108 108
                _client.AddHeader("X-Auth-User", UserName);
......
112 112
            Trace.TraceInformation("[AUTHENTICATE] End for {0}", userName);
113 113
        }
114 114

  
115
        private void OnFileProgress(object sender, FileProgressEventArgs e)
115
       /* private void OnFileProgress(object sender, FileProgressEventArgs e)
116 116
        {
117 117
            Trace.TraceInformation("[PROGRESS] {0} {1:p} {2} of {3}",e.FileName,(double)e.BytesWritten/e.TotalBytes, e.BytesWritten,e.TotalBytes);            
118
        }
118
        }*/
119 119

  
120 120
        public IList<ContainerInfo> ListContainers()
121 121
        {                        
......
123 123
            //appends a / unless a Path is specified.
124 124
            
125 125
            //Create a request with a complete path
126
            var request = new RestRequest { Path = StorageUrl.ToString(), RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
127
            request.AddParameter("format","json");
126
            //var request = new RestRequest { Path = StorageUrl.ToString(), RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
127
            //request.AddParameter("format","json");
128 128
            //Create a client clone
129

  
130
            /*var url = String.Join("/", new[] { _client.Authority, StorageUrl.ToString() });
131
            var builder=new UriBuilder(url);
132
            builder.Query = "format=json";
133
           
134
            var client= new PithosClient(_client){Timeout=10};   */         
135
            var content=_client.DownloadStringWithRetry("",3);
136
            _client.Parameters.Clear();
137
            _client.Parameters.Add("format", "json");
138
            _client.AssertStatusOK("List Containers failed");
139

  
140
            if (_client.StatusCode==HttpStatusCode.NoContent)
141
                return new List<ContainerInfo>();
142
            var infos = JsonConvert.DeserializeObject<IList<ContainerInfo>>(content);
143
            return infos;
144

  
145

  
146
/*
129 147
            var client = new RestClient{Proxy=Proxy.ToString()};
130 148
            foreach (var header in _client.GetAllHeaders())
131 149
            {
132 150
                client.AddHeader(header.Name,header.Value);
133
            }            
151
            }
152

  
153
            
154

  
155

  
134 156

  
135 157
            var response = client.Request(request);
136 158

  
......
142 164

  
143 165
            var infos=JsonConvert.DeserializeObject<IList<ContainerInfo>>(response.Content);
144 166
            
145
            return infos;
167
            return infos;*/
146 168
        }
147 169

  
148 170
        public IList<ObjectInfo> ListObjects(string container)
......
152 174

  
153 175
            Trace.TraceInformation("[START] ListObjects");
154 176

  
155
            var request = new RestRequest { Path = container, RetryPolicy = _retryPolicy, Timeout = TimeSpan.FromMinutes(1) };
156
            request.AddParameter("format", "json");
157
            var response = _client.Request(request);
158
            
159
            var infos = InfosFromContent(response);
177
            //var request = new RestRequest { Path = container, RetryPolicy = _retryPolicy, Timeout = TimeSpan.FromMinutes(1) };
178
            //request.AddParameter("format", "json");
179
            //var response = _client.Request(request);
180

  
181

  
182
/*
183
            var url = String.Join("/", new[] { _client.Authority, container });
184
            var builder = new UriBuilder(url) {Query = "format=json"};
185

  
186
            var client = new PithosClient(_client) { Timeout = 60000 };
187
*/
188
            _client.Parameters.Clear();
189
            _client.Parameters.Add("format", "json");
190
            var content = _client.DownloadStringWithRetry(container, 3);
191

  
192
            _client.AssertStatusOK("ListObjects failed");
193

  
194
            var infos = JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
160 195

  
161 196
            Trace.TraceInformation("[END] ListObjects");
162 197
            return infos;
......
171 206

  
172 207
            Trace.TraceInformation("[START] ListObjects");
173 208

  
174
            var request = new RestRequest { Path = container,RetryPolicy = _retryPolicy, Timeout = TimeSpan.FromMinutes(1) };
209
           /* var request = new RestRequest { Path = container,RetryPolicy = _retryPolicy, Timeout = TimeSpan.FromMinutes(1) };
175 210
            request.AddParameter("format", "json");
176
            request.AddParameter("path", folder);
177
            var response = _client.Request(request);
211
            request.AddParameter("path", folder);*/
212
            
213
            _client.Parameters.Clear();
214
            _client.Parameters.Add("format", "json");
215
            _client.Parameters.Add("path", folder);
216
            var content = _client.DownloadStringWithRetry(container, 3);
217
            _client.AssertStatusOK("ListObjects failed");
218

  
219
            var infos = JsonConvert.DeserializeObject<IList<ObjectInfo>>(content);
220

  
221
           /* var response = _client.Request(request);
178 222
            
179
            var infos = InfosFromContent(response);
223
            var infos = InfosFromContent(response);*/
180 224

  
181 225
            Trace.TraceInformation("[END] ListObjects");
182 226
            return infos;
183 227
        }
184 228

  
185
        private static IList<ObjectInfo> InfosFromContent(RestResponse response)
229
 /*       private static IList<ObjectInfo> InfosFromContent(RestResponse response)
186 230
        {
187 231
            if (response.TimedOut)
188 232
                return new List<ObjectInfo>();
......
204 248
            var infos = JsonConvert.DeserializeObject<IList<ObjectInfo>>(response.Content);
205 249
            return infos;
206 250
        }
207

  
251
*/
208 252
        public bool ContainerExists(string container)
209 253
        {
210 254
            if (String.IsNullOrWhiteSpace(container))
211 255
                throw new ArgumentNullException("container", "The container property can't be empty");
212 256

  
213
            var request = new RestRequest { Path = container, Method = WebMethod.Head, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
214
            var response = _client.Request(request);
257
            _client.Parameters.Clear();
258
            _client.Head(container,3);
259
            //var request = new RestRequest { Path = container, Method = WebMethod.Head, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };            
260
            //var response = _client.Request(request);
215 261

  
216
            switch(response.StatusCode)
262
            switch (_client.StatusCode)
217 263
            {
218 264
                case HttpStatusCode.OK:
219 265
                case HttpStatusCode.NoContent:
......
221 267
                case HttpStatusCode.NotFound:
222 268
                    return false;          
223 269
                default:
224
                    throw CreateWebException("ContainerExists",response.StatusCode);
270
                    throw CreateWebException("ContainerExists", _client.StatusCode);
225 271
            }
226 272
        }
227 273

  
......
233 279
                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
234 280

  
235 281

  
282
/*
236 283
            var request = new RestRequest { Path = container + "/" + objectName, Method = WebMethod.Head,RetryPolicy = _retryPolicy, Timeout = _shortTimeout };
237 284
            var response = _client.Request(request);
285
*/
286
            _client.Parameters.Clear();
287
            _client.Head(container + "/" + objectName, 3);
238 288

  
239
            switch (response.StatusCode)
289
            switch (_client.StatusCode)
240 290
            {
241 291
                case HttpStatusCode.OK:
242 292
                case HttpStatusCode.NoContent:
......
244 294
                case HttpStatusCode.NotFound:
245 295
                    return false;
246 296
                default:
247
                    throw CreateWebException("ObjectExists",response.StatusCode);
297
                    throw CreateWebException("ObjectExists", _client.StatusCode);
248 298
            }
249 299
            
250 300
        }
......
257 307
                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
258 308

  
259 309

  
310
/*
260 311
            var request = new RestRequest { Path = container + "/" + objectName, Method = WebMethod.Head, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
261 312
            var response = _client.Request(request);
313
*/
314
            try
315
            {
316
                _client.Parameters.Clear();
262 317

  
263
            if (response.TimedOut)
264
                return ObjectInfo.Empty;
318
                _client.Head(container + "/" + objectName, 3);
265 319

  
266
            switch (response.StatusCode)
267
            {
268
                case HttpStatusCode.OK:
269
                case HttpStatusCode.NoContent:
270
                    var keys = response.Headers.AllKeys.AsQueryable();
271
                    var tags=(from key in keys
272
                             where key.StartsWith("X-Object-Meta-")
273
                             let name=key.Substring(14)
274
                             select new {Name=name,Value=response.Headers[name]})
275
                             .ToDictionary(t=>t.Name,t=>t.Value);
276
                    var extensions = (from key in keys
277
                                      where key.StartsWith("X-Object-") && !key.StartsWith("X-Object-Meta-")
278
                                      let name = key.Substring(9)
279
                                      select new { Name = name, Value = response.Headers[name] })
280
                             .ToDictionary(t => t.Name, t => t.Value);
281
                    return new ObjectInfo
282
                               {
283
                                   Name = objectName,
284
                                   Bytes = long.Parse(GetHeaderValue("Content-Length", response, keys)),
285
                                   Hash = GetHeaderValue("ETag", response, keys),
286
                                   Content_Type = GetHeaderValue("Content-Type", response, keys),
287
                                   Tags=tags,
288
                                   Extensions=extensions
289
                               };
290
                case HttpStatusCode.NotFound:
320
                if (_client.TimedOut)
291 321
                    return ObjectInfo.Empty;
292
                default:
293
                    if (request.RetryState.RepeatCount > 0)
294
                    {
295
                        Trace.TraceWarning("[RETRY FAIL] GetObjectInfo for {0} failed after {1} retries",
296
                                                      objectName, request.RetryState.RepeatCount);
322

  
323
                switch (_client.StatusCode)
324
                {
325
                    case HttpStatusCode.OK:
326
                    case HttpStatusCode.NoContent:
327
                        var keys = _client.ResponseHeaders.AllKeys.AsQueryable();
328
                        var tags = (from key in keys
329
                                    where key.StartsWith("X-Object-Meta-")
330
                                    let name = key.Substring(14)
331
                                    select new { Name = name, Value = _client.ResponseHeaders[name] })
332
                            .ToDictionary(t => t.Name, t => t.Value);
333
                        var extensions = (from key in keys
334
                                          where key.StartsWith("X-Object-") && !key.StartsWith("X-Object-Meta-")
335
                                          let name = key.Substring(9)
336
                                          select new { Name = name, Value = _client.ResponseHeaders[name] })
337
                            .ToDictionary(t => t.Name, t => t.Value);
338
                        return new ObjectInfo
339
                                   {
340
                                       Name = objectName,
341
                                       Bytes =
342
                                           long.Parse(_client.GetHeaderValue("Content-Length")),
343
                                       Hash = _client.GetHeaderValue("ETag"),
344
                                       Content_Type = _client.GetHeaderValue("Content-Type"),
345
                                       Tags = tags,
346
                                       Extensions = extensions
347
                                   };
348
                    case HttpStatusCode.NotFound:
297 349
                        return ObjectInfo.Empty;
298
                    }
299
                    if (response.InnerException != null)
300
                        throw new WebException(String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}", objectName, response.StatusCode), response.InnerException);
301
                    throw new WebException(String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}", objectName, response.StatusCode));
350
                    default:
351
                        throw new WebException(
352
                            String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}",
353
                                          objectName, _client.StatusCode));
354
                }
302 355
            }
356
            catch (RetryException e)
357
            {
358
                Trace.TraceWarning("[RETRY FAIL] GetObjectInfo for {0} failed.");
359
                return ObjectInfo.Empty;
360
            }
361
            catch (WebException e)
362
            {                
363
                Trace.TraceError(String.Format("[FAIL] GetObjectInfo for {0} failed with unexpected status code {1}",
364
                                              objectName, _client.StatusCode), e);
365
                throw;
366
            }
367
            
303 368
        }
304 369

  
305 370
        public void CreateFolder(string container, string folder)
......
310 375
                throw new ArgumentNullException("folder", "The folder property can't be empty");
311 376

  
312 377
            var folderUrl=String.Format("{0}/{1}",container,folder);
378
/*
313 379
            var request = new RestRequest { Path = folderUrl, Method = WebMethod.Put, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
314 380
            request.AddHeader("Content-Type", @"application/directory");
315 381
            request.AddHeader("Content-Length", "0");
382
*/
383
            
384
            _client.Parameters.Clear();
385
            _client.Headers.Add("Content-Type", @"application/directory");
386
            _client.Headers.Add("Content-Length", "0");
387
            _client.PutWithRetry(folderUrl,3);
316 388

  
317
            var response = _client.Request(request);
318

  
319
            if (response.StatusCode != HttpStatusCode.Created && response.StatusCode != HttpStatusCode.Accepted)
320
                throw CreateWebException("CreateFolder", response.StatusCode);
389
            if (_client.StatusCode != HttpStatusCode.Created && _client.StatusCode != HttpStatusCode.Accepted)
390
                throw CreateWebException("CreateFolder", _client.StatusCode);
321 391

  
322 392
        }
323 393

  
......
326 396
            if (String.IsNullOrWhiteSpace(container))
327 397
                throw new ArgumentNullException("container", "The container property can't be empty");
328 398

  
399
/*
329 400
            var request = new RestRequest { Path = container, Method = WebMethod.Head, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
330 401
            var response = _client.Request(request);
331

  
332
            switch(response.StatusCode)
402
*/
403
            _client.Head(container);
404
            switch (_client.StatusCode)
333 405
            {
334 406
                case HttpStatusCode.NoContent:
335
                    var keys = response.Headers.AllKeys.AsQueryable();
336 407
                    var containerInfo = new ContainerInfo
337 408
                                            {
338 409
                                                Name = container,
339
                                                Count =long.Parse(GetHeaderValue("X-Container-Object-Count", response, keys)),
340
                                                Bytes =long.Parse(GetHeaderValue("X-Container-Bytes-Used", response, keys))
410
                                                Count =long.Parse(_client.GetHeaderValue("X-Container-Object-Count")),
411
                                                Bytes = long.Parse(_client.GetHeaderValue("X-Container-Bytes-Used"))
341 412
                                            };
342 413
                    return containerInfo;
343 414
                case HttpStatusCode.NotFound:
344 415
                    return ContainerInfo.Empty;                    
345 416
                default:
346
                    throw CreateWebException("GetContainerInfo", response.StatusCode);
417
                    throw CreateWebException("GetContainerInfo", _client.StatusCode);
347 418
            }
348 419
        }
349 420

  
......
352 423
            if (String.IsNullOrWhiteSpace(container))
353 424
                throw new ArgumentNullException("container", "The container property can't be empty");
354 425

  
355
            var request = new RestRequest { Path = container, Method = WebMethod.Put, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
356
            
426
/*
427
            var request = new RestRequest { Path = container, Method = WebMethod.Put, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };            
357 428
            var response = _client.Request(request);
358

  
429
*/
430
            _client.PutWithRetry(container,3);
359 431
            var expectedCodes = new[]{HttpStatusCode.Created ,HttpStatusCode.Accepted , HttpStatusCode.OK};
360
            if (!expectedCodes.Contains(response.StatusCode))
361
                throw CreateWebException("CreateContainer", response.StatusCode);
432
            if (!expectedCodes.Contains(_client.StatusCode))
433
                throw CreateWebException("CreateContainer", _client.StatusCode);
362 434
        }
363 435

  
364 436
        public void DeleteContainer(string container)
......
366 438
            if (String.IsNullOrWhiteSpace(container))
367 439
                throw new ArgumentNullException("container", "The container property can't be empty");
368 440

  
441
/*
369 442
            var request = new RestRequest { Path = container, Method = WebMethod.Delete, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
370 443
            var response = _client.Request(request);
371

  
444
*/
445
            _client.DeleteWithRetry(container,3);
372 446
            var expectedCodes = new[] { HttpStatusCode.NotFound, HttpStatusCode.NoContent};
373
            if (!expectedCodes.Contains(response.StatusCode))
374
                throw CreateWebException("DeleteContainer", response.StatusCode);
447
            if (!expectedCodes.Contains(_client.StatusCode))
448
                throw CreateWebException("DeleteContainer", _client.StatusCode);
375 449

  
376 450
        }
377 451

  
......
389 463
                throw new ArgumentNullException("container", "The container property can't be empty");
390 464
            if (String.IsNullOrWhiteSpace(objectName))
391 465
                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
392

  
393
            var request = new RestRequest {Path = container + "/" + objectName, Method = WebMethod.Get};
394 466
            /*
395
                        if (DownloadPercentLimit > 0)
396
                            request.TaskOptions = new TaskOptions<int> { RateLimitPercent = DownloadPercentLimit };
397
            */
467
           var request = new RestRequest {Path = container + "/" + objectName, Method = WebMethod.Get};
468
           
469
                       if (DownloadPercentLimit > 0)
470
                           request.TaskOptions = new TaskOptions<int> { RateLimitPercent = DownloadPercentLimit };
471
           */
398 472
            try
399 473
            {
400
                var url = String.Join("/", new[] {_client.Authority, container, objectName});
474
                var url = String.Join("/", _client.BaseAddress, container, objectName);
401 475
                var uri = new Uri(url);
402 476

  
403
                var client = new WebClient();
404
                if (!String.IsNullOrWhiteSpace(_client.Proxy))
477
                var client = new PithosClient(_client){Timeout=0};
478
               /* if (!String.IsNullOrWhiteSpace(_client.Proxy))
405 479
                    client.Proxy = new WebProxy(_client.Proxy);
406 480

  
407
                CopyHeaders(_client, client);
481
                CopyHeaders(_client, client);*/
408 482

  
409 483
                Trace.TraceInformation("[GET] START {0}", objectName);
410 484
                client.DownloadProgressChanged += (sender, args) => 
......
413 487
                                    args.BytesReceived,
414 488
                                    args.TotalBytesToReceive);
415 489
                
416
                return client.DownloadFileTask(uri, fileName)
490
                return _client.DownloadFileTask(uri, fileName)
417 491
                    .ContinueWith(download =>
418 492
                                      {
419 493
                                          client.Dispose();
......
461 535
            
462 536
            try
463 537
            {
464
                var url = String.Join("/",new[]{_client.Authority,container,objectName});
538
                var url = String.Join("/",_client.BaseAddress,container,objectName);
465 539
                var uri = new Uri(url);
466 540

  
467
                var client = new WebClient();                
541
                var client = new PithosClient(_client){Timeout=0};           
468 542
                string etag = hash ?? CalculateHash(fileName);
469 543

  
470 544
                client.Headers.Add("Content-Type", "application/octet-stream");
471 545
                client.Headers.Add("ETag", etag);
472 546

  
547
/*
473 548
                if(!String.IsNullOrWhiteSpace(_client.Proxy))
474 549
                    client.Proxy = new WebProxy(_client.Proxy);
475 550

  
476 551
                CopyHeaders(_client, client);
552
*/
477 553

  
478 554
                Trace.TraceInformation("[PUT] START {0}", objectName);
479 555
                client.UploadProgressChanged += (sender, args) =>
......
502 578

  
503 579
        }
504 580
       
505

  
581
/*
506 582
        /// <summary>
507 583
        /// Copies headers from a Hammock RestClient to a WebClient
508 584
        /// </summary>
......
521 597
            {
522 598
                target.Headers.Add(header.Name, header.Value);
523 599
            }
524
        }
600
        }*/
601

  
602
       /* /// <summary>
603
        /// Copies headers from a Hammock RestClient to a WebClient
604
        /// </summary>
605
        /// <param name="source">The RestClient from which the headers are copied</param>
606
        /// <param name="target">The WebClient to which the headers are copied</param>
607
        private static void CopyHeaders(RestClient source, WebRequest target)
608
        {
609
            Contract.Requires(source!=null,"source can't be null");
610
            Contract.Requires(target != null, "target can't be null");
611
            if (source == null)
612
                throw new ArgumentNullException("source", "source can't be null");
613
            if (source == null)
614
                throw new ArgumentNullException("target", "target can't be null");
525 615

  
616
            foreach (var header in source.GetAllHeaders())
617
            {
618
                target.Headers.Add(header.Name, header.Value);
619
            }
620
        }*/
621

  
622
        
526 623
        private static string CalculateHash(string fileName)
527 624
        {
528 625
            string hash;
......
544 641
            if (String.IsNullOrWhiteSpace(objectName))
545 642
                throw new ArgumentNullException("objectName", "The objectName property can't be empty");
546 643

  
644
/*
547 645
            var request = new RestRequest { Path = container + "/" + objectName, Method = WebMethod.Delete, RetryPolicy = _retryPolicy,Timeout = _shortTimeout };
548 646
            var response = _client.Request(request);
647
*/
648
            _client.DeleteWithRetry(container + "/" + objectName,3);
549 649

  
550 650
            var expectedCodes = new[] { HttpStatusCode.NotFound, HttpStatusCode.NoContent };
551
            if (!expectedCodes.Contains(response.StatusCode))
552
                throw CreateWebException("DeleteObject", response.StatusCode);
651
            if (!expectedCodes.Contains(_client.StatusCode))
652
                throw CreateWebException("DeleteObject", _client.StatusCode);
553 653
   
554 654
        }
555 655

  
......
567 667
            var targetUrl = targetContainer + "/" + newObjectName;
568 668
            var sourceUrl = String.Format("/{0}/{1}", sourceContainer, oldObjectName);
569 669

  
670
/*
570 671
            var request = new RestRequest { Path = targetUrl, Method = WebMethod.Put };
571 672
            request.AddHeader("X-Copy-From",sourceUrl);
572 673
            request.AddPostContent(new byte[]{});
573 674
            var response = _client.Request(request);
675
*/
574 676

  
677
            var client = new PithosClient(_client);
678
            client.Headers.Add("X-Copy-From", sourceUrl);
679
            client.PutWithRetry(targetUrl,3);
575 680

  
576 681
            var expectedCodes = new[] { HttpStatusCode.OK ,HttpStatusCode.NoContent ,HttpStatusCode.Created };
577
            if (expectedCodes.Contains(response.StatusCode))
682
            if (expectedCodes.Contains(client.StatusCode))
578 683
            {
579 684
                this.DeleteObject(sourceContainer,oldObjectName);
580 685
            }                
581 686
            else
582
                throw CreateWebException("MoveObject", response.StatusCode);
687
                throw CreateWebException("MoveObject", client.StatusCode);
583 688
        }
584 689

  
585
        private string GetHeaderValue(string headerName, RestResponse response, IQueryable<string> keys)
690
      
691

  
692
        /*private string GetHeaderValue(string headerName, WebHeaderCollection headers, IQueryable<string> keys)
586 693
        {
587 694
            if (keys.Any(key => key == headerName))
588
                return response.Headers[headerName];
695
                return headers[headerName];
589 696
            else
590
                throw new WebException(String.Format("The {0}  header is missing",headerName));
697
                throw new WebException(String.Format("The {0}  header is missing", headerName));
698
        }*/
699

  
700
       /* private static void ThrowIfNotStatusOK(RestResponse response, string message)
701
        {
702
            int status = (int)response.StatusCode;
703
            ThrowIfNotStatusOK(status, message);
591 704
        }
592 705

  
593
        private static void ThrowIfNotStatusOK(RestResponse response, string message)
706
        private static void ThrowIfNotStatusOK(HttpWebResponse response, string message)
594 707
        {
595 708
            int status = (int)response.StatusCode;
596
            if (status < 200 || status >= 300)
597
                throw new WebException(String.Format("{0} with code {1}",message, status));
709
            ThrowIfNotStatusOK(status, message);
598 710
        }
599 711

  
712
        private static void ThrowIfNotStatusOK(int status, string message)
713
        {
714
            if (status < 200 || status >= 300)
715
                throw new WebException(String.Format("{0} with code {1}", message, status));
716
        }
717
        */
600 718
        private static WebException CreateWebException(string operation, HttpStatusCode statusCode)
601 719
        {
602 720
            return new WebException(String.Format("{0} failed with unexpected status code {1}", operation, statusCode));
603 721
        }
604 722

  
723
       /* public static Func<T> Retry<T>(Func<int,T> original, int retryCount,int timeout)
724
        {
725
            return () =>
726
            {
727
                while (true)
728
                {
729
                    try
730
                    {
731
                        return original(timeout);
732
                    }
733
                    catch (WebException e)
734
                    {
735
                        if (e.Status == WebExceptionStatus.Timeout)
736
                        {
737
                            if (retryCount == 0)
738
                            {
739
                                throw;
740
                            }
741
                            retryCount--;
742
                        }
743
                        else
744
                        {
745
                            throw;
746
                        }
747
                    }
748
                    catch (Exception e)
749
                    {                                   
750
                            throw;                        
751
                    }
752
                }
753
            };
754
        } */
755

  
756

  
605 757
    }
606 758
}

Also available in: Unified diff