Retry failed browser or node service requests that may have an updated URL in the...
[pithos-macos] / pithos-macos / PithosObjectNode.m
index 416c9f8..ffe8fd1 100644 (file)
@@ -2,7 +2,7 @@
 //  PithosObjectNode.m
 //  pithos-macos
 //
-// Copyright 2011-2012 GRNET S.A. All rights reserved.
+// Copyright 2011-2013 GRNET S.A. All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or
 // without modification, are permitted provided that the following
 #import "ASIPithosObjectRequest.h"
 #import "ASIPithosContainer.h"
 #import "ASIPithosObject.h"
+#import "ASIPithosSharingUser.h"
 #import "ASIDownloadCache.h"
+#import "PithosAccount.h"
 #import "PithosUtilities.h"
 #import "PithosObjectNodeInfoController.h"
 
 @implementation PithosObjectNode
-@synthesize pithos, pithosContainer, pithosObject, versions;
-@synthesize isPublic;
+@synthesize pithosContainer, pithosObject, versions, applyMetadataObjectRequest, refreshMetadataObjectRequest, refreshVersionsObjectRequest;
+@synthesize isPublic, translatedModifiedBy, translatedPermissions;
 
 #pragma mark -
 #pragma mark Object Lifecycle
 
-- (id)initWithPithos:(ASIPithos *)aPithos 
-     pithosContainer:(ASIPithosContainer *)aPithosContainer 
-        pithosObject:(ASIPithosObject *)aPithosObject {
-    if ((self = [super init])) {
-        self.pithos = aPithos;
+- (id)initWithPithosAccountManager:(PithosAccount *)aPithosAccountManager
+                   pithosContainer:(ASIPithosContainer *)aPithosContainer
+                      pithosObject:(ASIPithosObject *)aPithosObject {
+    if ((self = [super initWithPithosAccountManager:aPithosAccountManager])) {
+        isLeafItem = YES;
         self.pithosContainer = aPithosContainer;
         self.pithosObject = aPithosObject;
-        isLeafItem = YES;
     }
     return self;
 }
 
 - (void)dealloc {
     [refreshVersionsObjectRequest clearDelegatesAndCancel];
-    [refreshVersionsObjectRequest release];
     [refreshMetadataObjectRequest clearDelegatesAndCancel];
-    [refreshMetadataObjectRequest release];
     [applyMetadataObjectRequest clearDelegatesAndCancel];
-    [applyMetadataObjectRequest release];
-    [versions release];
-    [pithosObject release];
-    [pithosContainer release];
-    [pithos release];
-    [super dealloc];
 }
 
 #pragma mark -
-#pragma mark Properties
+#pragma mark Internal
 
-- (void)setPithos:(ASIPithos *)aPithos {
-    if (aPithos && ![aPithos isEqualTo:pithos]) {
-        [pithos release];
-        pithos = [aPithos retain];
-        [url release];
-        url = nil;
+- (void)updateModifiedBy {
+    if (!pithosObject.modifiedBy) {
+        self.translatedModifiedBy = nil;
+    } else if (pithosAccountManager) {
+        NSString *displayname = [pithosAccountManager displaynameForUUID:pithosObject.modifiedBy safe:NO];
+        if (displayname) {
+            self.translatedModifiedBy = displayname;
+        } else {
+            [pithosAccountManager updateUserCatalogForDisplaynames:nil UUIDs:[NSArray arrayWithObject:pithosObject.modifiedBy]];
+            self.translatedModifiedBy = [pithosAccountManager displaynameForUUID:pithosObject.modifiedBy safe:YES];
+        }
+    } else {
+        self.translatedModifiedBy = [pithosObject.modifiedBy copy];
     }
 }
 
+- (void)updatePermissions {
+    if (!pithosObject) {
+        self.translatedPermissions = [NSMutableArray array];
+    } else if (pithosAccountManager) {
+        NSMutableSet *UUIDs = [NSMutableSet set];
+        for (ASIPithosSharingUser *sharingUser in pithosObject.permissions) {
+            [UUIDs addObject:sharingUser.name];
+        }
+        [UUIDs removeObject:@""];
+        [UUIDs removeObject:@"*"];
+        if (UUIDs.count) {
+            [pithosAccountManager updateUserCatalogForDisplaynames:nil UUIDs:[UUIDs allObjects]];
+        }
+        
+        NSMutableArray *newTranslatedPermissions = [NSMutableArray arrayWithCapacity:pithosObject.permissions.count];
+        for (ASIPithosSharingUser *sharingUser in pithosObject.permissions) {
+            ASIPithosSharingUser *translatedSharingUser = [sharingUser copy];
+            translatedSharingUser.name = [pithosAccountManager displaynameForUUID:translatedSharingUser.name safe:YES];
+            [newTranslatedPermissions addObject:translatedSharingUser];
+        }
+        self.translatedPermissions = newTranslatedPermissions;
+    } else {
+        self.translatedPermissions = [NSMutableArray arrayWithArray:[pithosObject.permissions copy]];
+    }
+}
+
+#pragma mark -
+#pragma mark Properties
+
 - (NSString *)url {
-    if (url == nil)
-        url = [[NSString alloc] initWithFormat:@"object %@/%@/%@%@", 
-               (sharingAccount ? [pithos storageURLWithAuthUser:sharingAccount] : pithos.storageURL), 
-               pithosContainer.name, 
-               pithosObject.name, 
-               (shared ? @"?shared" : @"")];
-    return url;
+    return [NSString stringWithFormat:@"@object@%@/%@/%@%@",
+            (sharingAccount ? sharingAccount : pithosAccountManager.pithos.authUser),
+            pithosContainer.name,
+            pithosObject.name,
+            (shared ? @"?shared" : @"")];
 }
 
 - (NSArray *)children {
         displayName = [pithosObject.name lastPathComponent];
         if([pithosObject.name hasSuffix:@"/"])
             displayName = [displayName stringByAppendingString:@"/"];
-        [displayName retain];
     }
-    return [[displayName copy] autorelease];
+    return [displayName copy];
 }
 
 - (void)setDisplayName:(NSString *)aDisplayName {    
 
 - (NSImage *)icon {
     if (icon == nil)
-        icon = [[[NSWorkspace sharedWorkspace] iconForFileType:[pithosObject.name pathExtension]] retain];
+        icon = [[NSWorkspace sharedWorkspace] iconForFileType:[pithosObject.name pathExtension]];
     return icon;
 }
 
 - (void)setPithosObject:(ASIPithosObject *)aPithosObject {
     if (![pithosObject isEqualTo:aPithosObject]) {
-        [pithosObject release];
-        pithosObject = [aPithosObject retain];
+        pithosObject = aPithosObject;
+        [self updateModifiedBy];
+        [self updatePermissions];
     }
     self.isPublic = (pithosObject.publicURI != nil);
     // Refresh browser if the object is in my shared and is no longer shared
     if (shared && !pithosObject.sharing)
-        [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosBrowserRefreshNeeeded" object:self];
+        [[NSNotificationCenter defaultCenter] postNotificationName:@"PithosBrowserRefreshNeeded" object:self];
 }
 
 - (void)setLimitedPithosObject:(ASIPithosObject *)aPithosObject {
             self.pithosObject.sharing = aPithosObject.sharing;
             self.pithosObject.publicURI = aPithosObject.publicURI;
             self.pithosObject = pithosObject;
+            [self updatePermissions];
+        } else {
+            [self updateModifiedBy];
         }
     }
 }
 #pragma mark ASIHTTPRequestDelegate
 
 - (void)objectRequestFinished:(ASIPithosObjectRequest *)request {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSLog(@"URL: %@", [request url]);
-    NSLog(@"cached: %d", [request didUseCachedResponse]);
-    
-    if ([request isEqualTo:applyMetadataObjectRequest]) {
-        int responseStatusCode = applyMetadataObjectRequest.responseStatusCode;
-        if (responseStatusCode != 202)
-            [PithosUtilities unexpectedResponseStatusAlertWithRequest:applyMetadataObjectRequest];
-        @synchronized(self) {
-            [applyMetadataObjectRequest release];
-            applyMetadataObjectRequest = nil;
-        }
-        if (responseStatusCode == 202)
-            [self refreshInfo];
-    } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
-        [[pithosNodeInfoController window] makeFirstResponder:nil];
-        self.pithosObject = [refreshMetadataObjectRequest object];
-        @synchronized(self) {
-            [refreshMetadataObjectRequest release];
-            refreshMetadataObjectRequest = nil;
-        }
-    } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
-        [[pithosNodeInfoController window] makeFirstResponder:nil];
-        self.versions = [refreshVersionsObjectRequest versions];
-        @synchronized(self) {
-            [refreshVersionsObjectRequest release];
-            refreshVersionsObjectRequest = nil;
-        }
-    }
-    [pool drain];
-}
-
-- (void)objectRequestFailed:(ASIPithosObjectRequest *)request {
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-    NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue];
-    if (retries > 0) {
-        ASIPithosObjectRequest *newRequest = (ASIPithosObjectRequest *)[[PithosUtilities copyRequest:request] autorelease];
-        [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+    @autoreleasepool {
+        DLog(@"URL: %@", [request url]);
+        DLog(@"cached: %d", [request didUseCachedResponse]);
+        
         if ([request isEqualTo:applyMetadataObjectRequest]) {
+            int responseStatusCode = applyMetadataObjectRequest.responseStatusCode;
+            if (responseStatusCode != 202)
+                [PithosUtilities unexpectedResponseStatusAlertWithRequest:applyMetadataObjectRequest];
             @synchronized(self) {
-                [applyMetadataObjectRequest release];
-                applyMetadataObjectRequest = newRequest;
+                self.applyMetadataObjectRequest = nil;
             }
+            if (responseStatusCode == 202)
+                [self refreshInfo];
         } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
+            [[pithosNodeInfoController window] makeFirstResponder:nil];
+            self.pithosObject = [refreshMetadataObjectRequest object];
             @synchronized(self) {
-                [refreshMetadataObjectRequest release];
-                refreshMetadataObjectRequest = newRequest;
+                self.refreshMetadataObjectRequest = nil;
             }
         } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
+            [[pithosNodeInfoController window] makeFirstResponder:nil];
+            self.versions = [refreshVersionsObjectRequest versions];
             @synchronized(self) {
-                [refreshVersionsObjectRequest release];
-                refreshVersionsObjectRequest = newRequest;
+                self.refreshVersionsObjectRequest = nil;
             }
         }
-        [[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
-    } else {
-        if ([request isEqualTo:applyMetadataObjectRequest]) {
-            dispatch_async(dispatch_get_main_queue(), ^{
-                [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataObjectRequest];
-            });
-            @synchronized(self) {
-                [applyMetadataObjectRequest release];
-                applyMetadataObjectRequest = nil;
+    }
+}
+
+- (void)objectRequestFailed:(ASIPithosObjectRequest *)request {
+    @autoreleasepool {
+        NSUInteger retries = [[request.userInfo objectForKey:@"retries"] unsignedIntegerValue];
+        if (retries > 0) {
+            ASIPithosObjectRequest *newRequest = (ASIPithosObjectRequest *)[PithosUtilities retryWithUpdatedURLRequest:request
+                                                                                               andPithosAccountManager:pithosAccountManager];
+            [(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
+            if ([request isEqualTo:applyMetadataObjectRequest]) {
+                @synchronized(self) {
+                    self.applyMetadataObjectRequest = newRequest;
+                }
+            } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
+                @synchronized(self) {
+                    self.refreshMetadataObjectRequest = newRequest;
+                }
+            } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
+                @synchronized(self) {
+                    self.refreshVersionsObjectRequest = newRequest;
+                }
             }
-        } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
-            dispatch_async(dispatch_get_main_queue(), ^{
+            [[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
+        } else {
+            if ([request isEqualTo:applyMetadataObjectRequest]) {
+                [PithosUtilities httpRequestErrorAlertWithRequest:applyMetadataObjectRequest];
+                @synchronized(self) {
+                    self.applyMetadataObjectRequest = nil;
+                }
+            } else if ([request isEqualTo:refreshMetadataObjectRequest]) {
                 [PithosUtilities httpRequestErrorAlertWithRequest:refreshMetadataObjectRequest];
-            });
-            @synchronized(self) {
-                [refreshMetadataObjectRequest release];
-                refreshMetadataObjectRequest = nil;
-            }
-        } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
-            dispatch_async(dispatch_get_main_queue(), ^{
+                @synchronized(self) {
+                    self.refreshMetadataObjectRequest = nil;
+                }
+            } else if ([request isEqualTo:refreshVersionsObjectRequest]) {
                 [PithosUtilities httpRequestErrorAlertWithRequest:refreshVersionsObjectRequest];
-            });
-            @synchronized(self) {
-                [refreshVersionsObjectRequest release];
-                refreshVersionsObjectRequest = nil;
+                @synchronized(self) {
+                    self.refreshVersionsObjectRequest = nil;
+                }
             }
         }
     }
-    [pool drain];
 }
 
 #pragma mark -
         if (applyMetadataObjectRequest == nil) {
             [[pithosNodeInfoController window] makeFirstResponder:nil];
             if (sharingAccount) {
-                applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithos 
-                                                                                              containerName:pithosContainer.name 
-                                                                                                 objectName:pithosObject.name 
-                                                                                            contentEncoding:nil 
-                                                                                         contentDisposition:nil 
-                                                                                                   manifest:nil 
-                                                                                                    sharing:nil
-                                                                                                   isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
-                                                                                                   metadata:pithosObject.metadata
-                                                                                                     update:NO] retain];
-                [applyMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+                self.applyMetadataObjectRequest = [ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithosAccountManager.pithos
+                                                                                                  containerName:pithosContainer.name
+                                                                                                     objectName:pithosObject.name
+                                                                                                contentEncoding:nil
+                                                                                             contentDisposition:nil
+                                                                                                       manifest:nil
+                                                                                                        sharing:nil
+                                                                                                       isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse)
+                                                                                                       metadata:pithosObject.metadata
+                                                                                                         update:NO];
+                [applyMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithosAccountManager.pithos];
             } else {
-                applyMetadataObjectRequest = [[ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithos 
-                                                                                              containerName:pithosContainer.name 
-                                                                                                 objectName:pithosObject.name 
-                                                                                            contentEncoding:pithosObject.contentEncoding 
-                                                                                         contentDisposition:pithosObject.contentDisposition 
-                                                                                                   manifest:pithosObject.manifest 
-                                                                                                    sharing:(pithosObject.sharing ? pithosObject.sharing : @"")
-                                                                                                   isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse) 
-                                                                                                   metadata:pithosObject.metadata
-                                                                                                     update:NO] retain];
+                NSMutableArray *permissions = [NSMutableArray array];
+                if (translatedPermissions.count) {
+                    for (ASIPithosSharingUser *translatedsSharingUser in translatedPermissions) {
+                        if (translatedsSharingUser.group.length &&
+                            [translatedsSharingUser.group rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@" -_~,;"]].location != NSNotFound) {
+                            NSAlert *alert = [[NSAlert alloc] init];
+                            [alert setMessageText:@"Invalid Input"];
+                            [alert setInformativeText:@"Group names cannot contain ' ', '-', '_', '~', ',' or ';'."];
+                            [alert addButtonWithTitle:@"OK"];
+                            [alert runModal];
+                            return;
+                        }
+                    }
+                    if (pithosAccountManager) {
+                        NSMutableSet *allUsers = [NSMutableSet set];
+                        for (ASIPithosSharingUser *translatedsSharingUser in translatedPermissions) {
+                            if (translatedsSharingUser.name.length) {
+                                [allUsers addObject:translatedsSharingUser.name];
+                            }
+                        }
+                        [allUsers removeObject:@""];
+                        [allUsers removeObject:@"*"];
+                        if (allUsers.count) {
+                            ASIPithosRequest *userCatalogRequest = [pithosAccountManager updateUserCatalogForDisplaynames:[allUsers allObjects]
+                                                                                                                       UUIDs:nil];
+                            if (userCatalogRequest.error || ((userCatalogRequest.responseStatusCode != 200) && (userCatalogRequest.responseStatusCode != 404))) {
+                                return;
+                            } else if (userCatalogRequest.responseStatusCode == 200) {
+                                // Check if all users exist.
+                                NSDictionary *displaynameCatalog = [userCatalogRequest displaynameCatalog];
+                                NSMutableArray *inexistentUsers = [NSMutableArray array];
+                                for (NSString *user in allUsers) {
+                                    if (![displaynameCatalog objectForKey:user]) {
+                                        [inexistentUsers addObject:user];
+                                    }
+                                }
+                                if (!inexistentUsers.count) {
+                                    // Create permissions.
+                                    for (ASIPithosSharingUser *translatedsSharingUser in translatedPermissions) {
+                                        if (translatedsSharingUser.name.length) {
+                                            ASIPithosSharingUser *sharingUser = [translatedsSharingUser copy];
+                                            if (![sharingUser.name isEqualToString:@"*"]) {
+                                                sharingUser.name = [displaynameCatalog objectForKey:sharingUser.name];
+                                            }
+                                            if (!sharingUser.permission) {
+                                                sharingUser.permission = @"read";
+                                            }
+                                            [permissions addObject:sharingUser];
+                                        }
+                                    }
+                                } else {
+                                    NSAlert *alert = [[NSAlert alloc] init];
+                                    if (inexistentUsers.count == 1) {
+                                        [alert setMessageText:@"Invalid User"];
+                                        [alert setInformativeText:[NSString stringWithFormat:@"User '%@' doesn't exist.", [inexistentUsers objectAtIndex:0]]];
+                                    } else {
+                                        [alert setMessageText:@"Invalid Users"];
+                                        [alert setInformativeText:[NSString stringWithFormat:@"Users '%@' don't exist.", [inexistentUsers componentsJoinedByString:@"', '"]]];
+                                    }
+                                    [alert addButtonWithTitle:@"OK"];
+                                    [alert runModal];
+                                    return;
+                                }
+                            } else {
+                                // 404. Since we don't translate to UUIDs, check for invalid chars.
+                                BOOL valid = YES;
+                                // Create permissions.
+                                for (ASIPithosSharingUser *translatedsSharingUser in translatedPermissions) {
+                                    if (translatedsSharingUser.name.length &&
+                                        ([translatedsSharingUser.name rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@" ~,;:"]].location != NSNotFound)) {
+                                        valid = NO;
+                                        break;
+                                    }
+                                }
+                                if (valid) {
+                                    for (ASIPithosSharingUser *translatedsSharingUser in translatedPermissions) {
+                                        if (translatedsSharingUser.name.length) {
+                                            ASIPithosSharingUser *sharingUser = [translatedsSharingUser copy];
+                                            if (!sharingUser.permission) {
+                                                sharingUser.permission = @"read";
+                                            }                                            
+                                            [permissions addObject:sharingUser];
+                                        }
+                                    }
+                                } else {
+                                    NSAlert *alert = [[NSAlert alloc] init];
+                                    [alert setMessageText:@"Invalid Input"];
+                                    [alert setInformativeText:@"Users cannot contain ' ', '~', ',', ';' or ':'."];
+                                    [alert addButtonWithTitle:@"OK"];
+                                    [alert runModal];
+                                    return;
+                                }
+                            }
+                        } else {
+                            for (ASIPithosSharingUser *translatedsSharingUser in translatedPermissions) {
+                                if ([translatedsSharingUser.name isEqualToString:@"*"]) {
+                                    ASIPithosSharingUser *sharingUser = [translatedsSharingUser copy];
+                                    if (!sharingUser.permission) {
+                                        sharingUser.permission = @"read";
+                                    }
+                                    [permissions addObject:sharingUser];
+                                }
+                            }
+                        }
+                    } else {
+                        for (ASIPithosSharingUser *translatedsSharingUser in translatedPermissions) {
+                            if (translatedsSharingUser.name.length) {
+                                ASIPithosSharingUser *sharingUser = [translatedsSharingUser copy];
+                                if (!sharingUser.permission) {
+                                    sharingUser.permission = @"read";
+                                }
+                                [permissions addObject:sharingUser];
+                            }
+                        }
+                    }
+                }
+                pithosObject.permissions = permissions;
+            
+                self.applyMetadataObjectRequest = [ASIPithosObjectRequest updateObjectMetadataRequestWithPithos:pithosAccountManager.pithos
+                                                                                                  containerName:pithosContainer.name
+                                                                                                     objectName:pithosObject.name
+                                                                                                contentEncoding:pithosObject.contentEncoding
+                                                                                             contentDisposition:pithosObject.contentDisposition
+                                                                                                       manifest:pithosObject.manifest
+                                                                                                        sharing:(pithosObject.sharing ? pithosObject.sharing : @"")
+                                                                                                       isPublic:(isPublic ? ASIPithosObjectRequestPublicTrue : ASIPithosObjectRequestPublicFalse)
+                                                                                                       metadata:pithosObject.metadata
+                                                                                                         update:NO];
             }
             applyMetadataObjectRequest.delegate = self;
             applyMetadataObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
 - (void)refreshInfo {
     @synchronized(self) {
         if (refreshMetadataObjectRequest == nil) {
-            refreshMetadataObjectRequest = [[ASIPithosObjectRequest objectMetadataRequestWithPithos:pithos 
-                                                                                      containerName:pithosContainer.name 
-                                                                                         objectName:pithosObject.name] retain];
+            self.refreshMetadataObjectRequest = [ASIPithosObjectRequest objectMetadataRequestWithPithos:pithosAccountManager.pithos
+                                                                                          containerName:pithosContainer.name
+                                                                                             objectName:pithosObject.name];
             if (sharingAccount)
-                [refreshMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+                [refreshMetadataObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithosAccountManager.pithos];
             refreshMetadataObjectRequest.delegate = self;
             refreshMetadataObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
             refreshMetadataObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
                                                      NSStringFromSelector(@selector(objectRequestFinished:)), @"didFinishSelector", 
                                                      NSStringFromSelector(@selector(objectRequestFailed:)), @"didFailSelector", 
                                                      nil];
-            refreshMetadataObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
+            if (!sharingAccount)
+                refreshMetadataObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
             [[PithosUtilities prepareRequest:refreshMetadataObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
         }
     }
 - (void)refreshVersions {
     @synchronized(self) {
         if (refreshVersionsObjectRequest == nil) {
-            refreshVersionsObjectRequest = [[ASIPithosObjectRequest objectVersionsRequestWithPithos:pithos 
-                                                                                      containerName:pithosContainer.name 
-                                                                                         objectName:pithosObject.name] retain];
+            self.refreshVersionsObjectRequest = [ASIPithosObjectRequest objectVersionsRequestWithPithos:pithosAccountManager.pithos
+                                                                                          containerName:pithosContainer.name
+                                                                                             objectName:pithosObject.name];
             if (sharingAccount)
-                [refreshVersionsObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithos];
+                [refreshVersionsObjectRequest setRequestUserFromDefaultTo:sharingAccount withPithos:pithosAccountManager.pithos];
             refreshVersionsObjectRequest.delegate = self;
             refreshVersionsObjectRequest.didFinishSelector = @selector(performRequestFinishedDelegateInBackground:);
             refreshVersionsObjectRequest.didFailSelector = @selector(performRequestFailedDelegateInBackground:);
                                                      NSStringFromSelector(@selector(objectRequestFinished:)), @"didFinishSelector", 
                                                      NSStringFromSelector(@selector(objectRequestFailed:)), @"didFailSelector", 
                                                      nil];
-            refreshVersionsObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
+            if (!sharingAccount)
+                refreshVersionsObjectRequest.downloadCache = [ASIDownloadCache sharedCache];
             [[PithosUtilities prepareRequest:refreshVersionsObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
         }
     }