Revision a27aa447 trunk/Pithos.Network/CloudFilesClient.cs

b/trunk/Pithos.Network/CloudFilesClient.cs
453 453

  
454 454
        }
455 455

  
456
        public Task<string> PutHashMap(string container, string objectName, TreeHash hash)
456
        public Task<IList<string>> PutHashMap(string container, string objectName, TreeHash hash)
457 457
        {
458 458
            if (String.IsNullOrWhiteSpace(container))
459 459
                throw new ArgumentNullException("container");
......
482 482
            
483 483
            return uploadTask.ContinueWith(t =>
484 484
            {
485
                
485

  
486
                var empty = (IList<string>)new List<string>();
486 487
                
487 488

  
488 489
                //The server will respond either with 201-created if all blocks were already on the server
489
                if (client.StatusCode == HttpStatusCode.Created)
490
                if (client.StatusCode == HttpStatusCode.Created)                    
491
                {
490 492
                    //in which case we return an empty hash list
491
                    return t.Result;
493
                    return empty;
494
                }
492 495
                //or with a 409-conflict and return the list of missing parts
493 496
                //A 409 will cause an exception so we need to check t.IsFaulted to avoid propagating the exception                
494 497
                if (t.IsFaulted)
......
502 505
                        using (var stream = response.GetResponseStream())
503 506
                        using(var reader=new StreamReader(stream))
504 507
                        {
505
                            var content=reader.ReadToEnd();
506
                            return content;
508
                            //We need to cleanup the content before returning it because it contains
509
                            //error content after the list of hashes
510
                            var hashes = new List<string>();
511
                            string line=null;
512
                            //All lines up to the first empty line are hashes
513
                            while(!String.IsNullOrWhiteSpace(line=reader.ReadLine()))
514
                            {
515
                                hashes.Add(line);
516
                            }
517

  
518
                            return hashes;
507 519
                        }                        
508 520
                    }
509 521
                    else
......
516 528
                {
517 529
                    Trace.TraceWarning("Unexcpected status code when putting map: {0} - {1}",client.StatusCode,client.StatusDescription);                    
518 530
                }
519
                return t.Result;
531
                return empty;
520 532
            });
521 533

  
522 534
        }
523 535

  
536
        public Task<byte[]> GetBlock(string container, Uri relativeUrl, long start, long? end=null)
537
        {
538
            if (String.IsNullOrWhiteSpace(Token))
539
                throw new InvalidOperationException("Invalid Token");
540
            if (StorageUrl == null)
541
                throw new InvalidOperationException("Invalid Storage Url");
542
            if (String.IsNullOrWhiteSpace(container))
543
                throw new ArgumentNullException("container");
544
            if (relativeUrl== null)
545
                throw new ArgumentNullException("relativeUrl");
546
            if (end.HasValue && end<0)
547
                throw new ArgumentOutOfRangeException("end");
548
            if (start<0)
549
                throw new ArgumentOutOfRangeException("start");
550
            Contract.EndContractBlock();
551

  
552
            var builder = GetAddressBuilder(container, relativeUrl.ToString());
553

  
554
            var uri = builder.Uri;
555

  
556
            //Don't use a timeout because putting the hashmap may be a long process
557
            var client = new RestClient(_baseClient) {Timeout = 0, RangeFrom = start, RangeTo = end};
558
            return client.DownloadDataTask(uri)
559
                .ContinueWith(t=>
560
                                  {
561
                                      client.Dispose();
562
                                      return t.Result;
563
                                  });
564
        }
565

  
566

  
567
        public Task PostBlock(string container,byte[] block)
568
        {
569
            if (String.IsNullOrWhiteSpace(container))
570
                throw new ArgumentNullException("container");
571
            if (block == null)
572
                throw new ArgumentNullException("block");
573
            if (String.IsNullOrWhiteSpace(Token))
574
                throw new InvalidOperationException("Invalid Token");
575
            if (StorageUrl == null)
576
                throw new InvalidOperationException("Invalid Storage Url");            
577
            Contract.EndContractBlock();
578

  
579
            var builder = GetAddressBuilder(container, "");
580
            //We are doing an update
581
            builder.Query = "update";
582
            var uri = builder.Uri;
583
                        
584
            //Don't use a timeout because putting the hashmap may be a long process
585
            var client = new RestClient(_baseClient) { Timeout = 0 };                                   
586
            client.Headers[HttpRequestHeader.ContentType] = "application/octet-stream";
587

  
588
            Trace.TraceInformation("[BLOCK POST] START");
589

  
590
            //Not much point to this as the server will timeout if we try to get the 
591
            //hashmap too quickly.
592
            var tcs = new TaskCompletionSource<bool>();
593

  
594
            client.UploadProgressChanged += (sender, args) =>
595
            {
596
                Trace.TraceInformation("[BLOCK POST PROGRESS] {0}% {1} of {2}",
597
                                        args.ProgressPercentage, args.BytesSent,
598
                                        args.TotalBytesToSend);
599
                if (args.BytesSent == args.TotalBytesToSend)
600
                    tcs.SetResult(false);                
601
            };
602

  
603
            client.UploadFileCompleted += (sender, args) =>
604
            {
605
                if (args.Error != null)
606
                    tcs.SetException(args.Error);
607
                else
608
                {
609
                    Trace.TraceInformation("[BLOCK POST PROGRESS] Completed ");
610
                    tcs.TrySetResult(true);
611
                }
612
            };
613

  
614

  
615

  
616
            client.UploadDataTask(uri, "POST", block);
617

  
618
            //Send the block
619
            var uploadTask = tcs.Task
620
                .ContinueWith(upload =>
621
                {
622
                    client.Dispose();
623

  
624
                    if (upload.IsFaulted)
625
                    {
626
                        var exception = upload.Exception.InnerException;
627
                        Trace.TraceError("[BLOCK POST] FAIL with \r{0}", exception);                        
628
                        throw exception;
629
                    }
630
                    else
631
                    {
632
                        Trace.TraceInformation("[BLOCK POST] END");                        
633
                    }
634
                });
635
            return uploadTask;            
636
        }
637

  
524 638

  
525 639
        public Task<TreeHash> GetHashMap(string container, string objectName)
526 640
        {
......
637 751
                                          client.Dispose();
638 752

  
639 753
                                          if (upload.IsFaulted)
640
                                          {                                              
641
                                              Trace.TraceError("[PUT] FAIL for {0} with \r{1}",objectName,upload.Exception);
754
                                          {
755
                                              var exc = upload.Exception.InnerException;
756
                                              Trace.TraceError("[PUT] FAIL for {0} with \r{1}",objectName,exc);
757
                                              throw exc;
642 758
                                          }
643 759
                                          else
644 760
                                            Trace.TraceInformation("[PUT] END {0}", objectName);

Also available in: Unified diff