Revision 0eea575a trunk/Pithos.Network/CloudFilesClient.cs

b/trunk/Pithos.Network/CloudFilesClient.cs
24 24
    public class CloudFilesClient:ICloudClient
25 25
    {
26 26
        string _rackSpaceAuthUrl = "https://auth.api.rackspacecloud.com";
27
        private string _pithosAuthUrl = "http://pithos.dev.grnet.gr";
27
        private string _pithosAuthUrl = "https://pithos.grnet.gr";
28 28

  
29 29
        private RestClient _client;
30 30
        private readonly TimeSpan _shortTimeout = TimeSpan.FromSeconds(10);
......
53 53

  
54 54
        public void Authenticate(string userName,string apiKey)
55 55
        {
56
            Trace.TraceInformation("[AUTHENTICATE] Start for {0}",userName);
56
            Trace.TraceInformation("[AUTHENTICATE] Start for {0}", userName);
57 57
            if (String.IsNullOrWhiteSpace(userName))
58
                throw new ArgumentNullException("userName","The userName property can't be empty");
58
                throw new ArgumentNullException("userName", "The userName property can't be empty");
59 59
            if (String.IsNullOrWhiteSpace(apiKey))
60 60
                throw new ArgumentNullException("apiKey", "The apiKey property can't be empty");
61
            
62 61

  
63 62
            UserName = userName;
64 63
            ApiKey = apiKey;
65

  
66
            string authUrl = UsePithos ? String.Format("{0}/{1}/{2}", AuthUrl, VersionPath,UserName) 
67
                                    : String.Format("{0}/{1}", AuthUrl, VersionPath);
68
            
69
            var proxy = Proxy != null ? Proxy.ToString():null;
70
            
71
            var authClient = new RestClient{Path=authUrl,Proxy=proxy};            
72
            
73
            authClient.AddHeader("X-Auth-User", UserName);
74
            authClient.AddHeader("X-Auth-Key", ApiKey);            
75 64
            
76
            var response=authClient.Request();
77
            
78
            ThrowIfNotStatusOK(response, "Authentication failed");
65
            var proxy = Proxy != null ? Proxy.ToString() : null;
66
            if (UsePithos)
67
            {
68
                Token = "0000";
69
                string storageUrl = String.Format("{0}/{1}/{2}", AuthUrl, VersionPath, UserName);
70
                StorageUrl = new Uri(storageUrl);
71
            }
72
            else
73
            {
79 74

  
80
            var keys = response.Headers.AllKeys.AsQueryable();
75
                string authUrl = String.Format("{0}/{1}", AuthUrl, VersionPath);
76
                var authClient = new RestClient {Path = authUrl, Proxy = proxy};                
81 77

  
82
            string storageUrl =UsePithos? 
83
                String.Format("{0}/{1}/{2}",AuthUrl,VersionPath,UserName)
84
                :GetHeaderValue("X-Storage-Url", response, keys);
85
            
86
            if (String.IsNullOrWhiteSpace(storageUrl))
87
                throw new InvalidOperationException("Failed to obtain storage url");
88
            StorageUrl = new Uri(storageUrl);
78
                authClient.AddHeader("X-Auth-User", UserName);
79
                authClient.AddHeader("X-Auth-Key", ApiKey);
80

  
81
                var response = authClient.Request();
82

  
83
                ThrowIfNotStatusOK(response, "Authentication failed");
84

  
85
                var keys = response.Headers.AllKeys.AsQueryable();
86

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

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

  
100 98
            _retryPolicy = new RetryPolicy { RetryCount = _retries };
101 99
            _retryPolicy.RetryConditions.Add(new TimeoutRetryCondition());
......
104 102
            _client.FileProgress += OnFileProgress;
105 103
            
106 104
            _client.AddHeader("X-Auth-Token", Token);
107
            if (UsePithos)
105
            /*if (UsePithos)
108 106
            {
109 107
                _client.AddHeader("X-Auth-User", UserName);
110 108
                _client.AddHeader("X-Auth-Key",ApiKey);                
111
            }
109
            }*/
112 110

  
113 111
            Trace.TraceInformation("[AUTHENTICATE] End for {0}", userName);
114 112
        }
......
198 196
            var statusCode = (int)response.StatusCode;
199 197
            if (statusCode < 200 || statusCode >= 300)
200 198
            {
201
                Trace.TraceWarning("ListObjects failed with code {1} - {2}", response.StatusCode, response.StatusDescription);
199
                Trace.TraceWarning("ListObjects failed with code {0} - {1}", response.StatusCode, response.StatusDescription);
202 200
                return new List<ObjectInfo>();
203 201
            }
204 202

  
......
414 412
            if (!File.Exists(fileName))
415 413
                throw new FileNotFoundException("The file does not exist",fileName);
416 414

  
417

  
418
            string url = container + "/" + objectName;
419

  
420
            var request = new RestRequest {Path=url,Method=WebMethod.Put};           
421 415
            
422
/*
423
            if(UploadPercentLimit>0)
424
                request.TaskOptions=new TaskOptions<int>{RateLimitPercent=UploadPercentLimit};
425
*/
426
            Trace.TraceInformation("[PUT] START {0}",objectName);
427
            string etag = hash??CalculateHash(fileName);
428
            request.AddFile(fileName, fileName, fileName);            
429
            //request.AddPostContent(File.ReadAllBytes(fileName));
430
            request.AddHeader("Content-Type","application/octet-stream");
431
            request.AddHeader("ETag", etag);
432
            //_client.TaskOptions = new TaskOptions<int> {RateLimitPercent = 0.5};
433 416
            try
434 417
            {
435

  
436
                var response=_client.Request(request);
437
                Trace.TraceInformation("[PUT] END {0}", objectName);
438

  
439
                if (response.StatusCode == HttpStatusCode.Created)
440
                    return Task.Factory.StartNew(()=>{});
441
                if (response.StatusCode == HttpStatusCode.LengthRequired)
442
                    throw new InvalidOperationException();
443
                else
444
                    throw new WebException(String.Format("GetObject failed with unexpected status code {0}",
445
                            response.StatusCode));
446
                /*            return Task.Factory.FromAsync(_client.BeginRequest(request),ar=>_client.EndRequest(ar))
447
                                .ContinueWith(t=>
448
                                {*/
418
                var url = String.Join("/",new[]{_client.Authority,container,objectName});
419
                var uri = new Uri(url);
420

  
421
                var client = new WebClient();                
422
                string etag = hash ?? CalculateHash(fileName);
423

  
424
                client.Headers.Add("Content-Type", "application/octet-stream");
425
                client.Headers.Add("ETag", etag);
426

  
427
                if(!String.IsNullOrWhiteSpace(_client.Proxy))
428
                    client.Proxy = new WebProxy(_client.Proxy);
429

  
430
                CopyHeaders(_client, client);
431

  
432
                Trace.TraceInformation("[PUT] START {0}", objectName);
433
                client.UploadProgressChanged += (sender, args) =>
434
                {
435
                    Trace.TraceInformation("[PROGRESS] {0} {1}% {2} of {3}", fileName, args.ProgressPercentage, args.BytesSent, args.TotalBytesToSend);
436
                };
437
               
438
                return client.UploadFileTask(uri, "PUT", fileName)
439
                    .ContinueWith(upload=>
440
                                      {
441
                                          client.Dispose();
442

  
443
                                          if (upload.IsFaulted)
444
                                          {                                              
445
                                              Trace.TraceError("[PUT] FAIL for {0} with \r{1}",objectName,upload.Exception);
446
                                          }
447
                                          else
448
                                            Trace.TraceInformation("[PUT] END {0}", objectName);
449
                                      });
449 450
            }
450 451
            catch (Exception exc)
451 452
            {
......
453 454
                throw;
454 455
            }                
455 456

  
456
/*
457
            var response = t.Result;
458
                    if (t.IsFaulted)
459
                        Trace.TraceError("[PUT] END {0} with {1}", objectName, t.Exception);
460
                    else
461
                    {
462
                        Trace.TraceInformation("[PUT] END {0}",objectName);
463
                    }
464
*/
465
                  /*  if (response.StatusCode == HttpStatusCode.Created)
466
                        return;
467
                    if (response.StatusCode == HttpStatusCode.LengthRequired)
468
                        throw new InvalidOperationException();
469
                    else
470
                        throw new WebException(String.Format("GetObject failed with unexpected status code {0}",
471
                                response.StatusCode));*/
472
                /*});*/
457
        }
458

  
459
        /// <summary>
460
        /// Copies headers from a Hammock RestClient to a WebClient
461
        /// </summary>
462
        /// <param name="source">The RestClient from which the headers are copied</param>
463
        /// <param name="target">The WebClient to which the headers are copied</param>
464
        private static void CopyHeaders(RestClient source, WebClient target)
465
        {
466
            Contract.Requires(source!=null,"source can't be null");
467
            Contract.Requires(target != null, "target can't be null");
468
            if (source == null)
469
                throw new ArgumentNullException("source", "source can't be null");
470
            if (source == null)
471
                throw new ArgumentNullException("target", "target can't be null");
472

  
473
            foreach (var header in source.GetAllHeaders())
474
            {
475
                target.Headers.Add(header.Name, header.Value);
476
            }
473 477
        }
474 478

  
475 479
        private static string CalculateHash(string fileName)

Also available in: Unified diff