Added ability to put to cloud files from a local file
Authenticate method now returns an NSError if something goes wrong Change lock mediating access to credentials to recursive
Showing
6 changed files
with
54 additions
and
8 deletions
@@ -21,7 +21,7 @@ | @@ -21,7 +21,7 @@ | ||
21 | #import "ASIInputStream.h" | 21 | #import "ASIInputStream.h" |
22 | 22 | ||
23 | // Automatically set on build | 23 | // Automatically set on build |
24 | -NSString *ASIHTTPRequestVersion = @"v1.5-26 2010-01-20"; | 24 | +NSString *ASIHTTPRequestVersion = @"v1.5-32 2010-01-20"; |
25 | 25 | ||
26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; | 26 | NSString* const NetworkRequestErrorDomain = @"ASIHTTPRequestErrorDomain"; |
27 | 27 |
@@ -58,6 +58,7 @@ | @@ -58,6 +58,7 @@ | ||
58 | // The Object can be created with custom metadata via HTTP headers identified with the “X-Object-Meta-” prefix. | 58 | // The Object can be created with custom metadata via HTTP headers identified with the “X-Object-Meta-” prefix. |
59 | + (id)putObjectRequestWithContainer:(NSString *)containerName object:(ASICloudFilesObject *)object; | 59 | + (id)putObjectRequestWithContainer:(NSString *)containerName object:(ASICloudFilesObject *)object; |
60 | + (id)putObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath contentType:(NSString *)contentType objectData:(NSData *)objectData metadata:(NSDictionary *)metadata etag:(NSString *)etag; | 60 | + (id)putObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath contentType:(NSString *)contentType objectData:(NSData *)objectData metadata:(NSDictionary *)metadata etag:(NSString *)etag; |
61 | ++ (id)putObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath contentType:(NSString *)contentType file:(NSString *)filePath metadata:(NSDictionary *)metadata etag:(NSString *)etag; | ||
61 | 62 | ||
62 | // POST /<api version>/<account>/<container>/<object> | 63 | // POST /<api version>/<account>/<container>/<object> |
63 | // POST operations against an Object name are used to set and overwrite arbitrary key/value metadata. You cannot use the POST operation to change any of the Object's other headers such as Content-Type, ETag, etc. It is not used to upload storage Objects (see PUT). | 64 | // POST operations against an Object name are used to set and overwrite arbitrary key/value metadata. You cannot use the POST operation to change any of the Object's other headers such as Content-Type, ETag, etc. It is not used to upload storage Objects (see PUT). |
@@ -155,7 +155,6 @@ | @@ -155,7 +155,6 @@ | ||
155 | 155 | ||
156 | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath]; | 156 | ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath]; |
157 | [request addRequestHeader:@"Content-Type" value:contentType]; | 157 | [request addRequestHeader:@"Content-Type" value:contentType]; |
158 | - [request addRequestHeader:@"Content-Length" value:[NSString stringWithFormat:@"%i", objectData.length]]; | ||
159 | 158 | ||
160 | // add metadata to headers | 159 | // add metadata to headers |
161 | if (metadata) { | 160 | if (metadata) { |
@@ -168,6 +167,23 @@ | @@ -168,6 +167,23 @@ | ||
168 | return request; | 167 | return request; |
169 | } | 168 | } |
170 | 169 | ||
170 | ++ (id)putObjectRequestWithContainer:(NSString *)containerName objectPath:(NSString *)objectPath contentType:(NSString *)contentType file:(NSString *)filePath metadata:(NSDictionary *)metadata etag:(NSString *)etag | ||
171 | +{ | ||
172 | + ASICloudFilesObjectRequest *request = [ASICloudFilesObjectRequest storageRequestWithMethod:@"PUT" containerName:containerName objectPath:objectPath]; | ||
173 | + [request addRequestHeader:@"Content-Type" value:contentType]; | ||
174 | + | ||
175 | + // add metadata to headers | ||
176 | + if (metadata) { | ||
177 | + for (NSString *key in [metadata keyEnumerator]) { | ||
178 | + [request addRequestHeader:[NSString stringWithFormat:@"X-Object-Meta-%@", key] value:[metadata objectForKey:key]]; | ||
179 | + } | ||
180 | + } | ||
181 | + | ||
182 | + [request setShouldStreamPostDataFromDisk:YES]; | ||
183 | + [request setPostBodyFilePath:filePath]; | ||
184 | + return request; | ||
185 | +} | ||
186 | + | ||
171 | #pragma mark - | 187 | #pragma mark - |
172 | #pragma mark POST - Set Object Metadata | 188 | #pragma mark POST - Set Object Metadata |
173 | 189 |
@@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
27 | #pragma mark Rackspace Cloud Authentication | 27 | #pragma mark Rackspace Cloud Authentication |
28 | 28 | ||
29 | + (id)authenticationRequest; | 29 | + (id)authenticationRequest; |
30 | -+ (void)authenticate; | 30 | ++ (NSError *)authenticate; |
31 | + (NSString *)username; | 31 | + (NSString *)username; |
32 | + (void)setUsername:(NSString *)username; | 32 | + (void)setUsername:(NSString *)username; |
33 | + (NSString *)apiKey; | 33 | + (NSString *)apiKey; |
@@ -20,14 +20,14 @@ static NSString *storageURL = nil; | @@ -20,14 +20,14 @@ static NSString *storageURL = nil; | ||
20 | static NSString *cdnManagementURL = nil; | 20 | static NSString *cdnManagementURL = nil; |
21 | static NSString *rackspaceCloudAuthURL = @"https://auth.api.rackspacecloud.com/v1.0"; | 21 | static NSString *rackspaceCloudAuthURL = @"https://auth.api.rackspacecloud.com/v1.0"; |
22 | 22 | ||
23 | -static NSLock *accessDetailsLock = nil; | 23 | +static NSRecursiveLock *accessDetailsLock = nil; |
24 | 24 | ||
25 | @implementation ASICloudFilesRequest | 25 | @implementation ASICloudFilesRequest |
26 | 26 | ||
27 | + (void)initialize | 27 | + (void)initialize |
28 | { | 28 | { |
29 | if (self == [ASICloudFilesRequest class]) { | 29 | if (self == [ASICloudFilesRequest class]) { |
30 | - accessDetailsLock = [[NSLock alloc] init]; | 30 | + accessDetailsLock = [[NSRecursiveLock alloc] init]; |
31 | } | 31 | } |
32 | } | 32 | } |
33 | 33 | ||
@@ -59,7 +59,7 @@ static NSLock *accessDetailsLock = nil; | @@ -59,7 +59,7 @@ static NSLock *accessDetailsLock = nil; | ||
59 | return request; | 59 | return request; |
60 | } | 60 | } |
61 | 61 | ||
62 | -+ (void)authenticate | 62 | ++ (NSError *)authenticate |
63 | { | 63 | { |
64 | [accessDetailsLock lock]; | 64 | [accessDetailsLock lock]; |
65 | ASIHTTPRequest *request = [ASICloudFilesRequest authenticationRequest]; | 65 | ASIHTTPRequest *request = [ASICloudFilesRequest authenticationRequest]; |
@@ -72,6 +72,7 @@ static NSLock *accessDetailsLock = nil; | @@ -72,6 +72,7 @@ static NSLock *accessDetailsLock = nil; | ||
72 | cdnManagementURL = [responseHeaders objectForKey:@"X-Cdn-Management-Url"]; | 72 | cdnManagementURL = [responseHeaders objectForKey:@"X-Cdn-Management-Url"]; |
73 | } | 73 | } |
74 | [accessDetailsLock unlock]; | 74 | [accessDetailsLock unlock]; |
75 | + return [request error]; | ||
75 | } | 76 | } |
76 | 77 | ||
77 | + (NSString *)username | 78 | + (NSString *)username |
@@ -211,12 +211,40 @@ static NSString *apiKey = @""; | @@ -211,12 +211,40 @@ static NSString *apiKey = @""; | ||
211 | GHAssertEqualStrings(object.name, @"puttestfile.txt", @"Failed to parse object name", @"Failed to parse object name"); | 211 | GHAssertEqualStrings(object.name, @"puttestfile.txt", @"Failed to parse object name", @"Failed to parse object name"); |
212 | GHAssertNotNil(object.data, @"Failed to parse object data"); | 212 | GHAssertNotNil(object.data, @"Failed to parse object data"); |
213 | GHAssertEqualStrings(string, @"this is a test", @"Failed to parse object data", @"Failed to parse object data"); | 213 | GHAssertEqualStrings(string, @"this is a test", @"Failed to parse object data", @"Failed to parse object data"); |
214 | - | 214 | + |
215 | - [string release]; | ||
216 | 215 | ||
217 | ASICloudFilesContainerRequest *deleteContainerRequest = [ASICloudFilesContainerRequest deleteContainerRequest:@"ASICloudFilesTest"]; | 216 | ASICloudFilesContainerRequest *deleteContainerRequest = [ASICloudFilesContainerRequest deleteContainerRequest:@"ASICloudFilesTest"]; |
218 | [deleteContainerRequest startSynchronous]; | 217 | [deleteContainerRequest startSynchronous]; |
219 | 218 | ||
219 | + // Now put the object from a file | ||
220 | + | ||
221 | + createContainerRequest = [ASICloudFilesContainerRequest createContainerRequest:@"ASICloudFilesTest"]; | ||
222 | + [createContainerRequest startSynchronous]; | ||
223 | + | ||
224 | + NSString *filePath = [[self filePathForTemporaryTestFiles] stringByAppendingPathComponent:@"cloudfile"]; | ||
225 | + [data writeToFile:filePath atomically:NO]; | ||
226 | + | ||
227 | + putRequest = [ASICloudFilesObjectRequest putObjectRequestWithContainer:@"ASICloudFilesTest" objectPath:@"puttestfile.txt" contentType:@"text/plain" file:filePath metadata:nil etag:nil]; | ||
228 | + | ||
229 | + [putRequest startSynchronous]; | ||
230 | + | ||
231 | + GHAssertNil([putRequest error], @"Failed to PUT object"); | ||
232 | + | ||
233 | + getRequest = [ASICloudFilesObjectRequest getObjectRequestWithContainer:@"ASICloudFilesTest" objectPath:@"puttestfile.txt"]; | ||
234 | + [getRequest startSynchronous]; | ||
235 | + | ||
236 | + object = [getRequest object]; | ||
237 | + | ||
238 | + GHAssertNotNil(object, @"Failed to retrieve new object"); | ||
239 | + GHAssertNotNil(object.name, @"Failed to parse object name"); | ||
240 | + GHAssertEqualStrings(object.name, @"puttestfile.txt", @"Failed to parse object name", @"Failed to parse object name"); | ||
241 | + GHAssertNotNil(object.data, @"Failed to parse object data"); | ||
242 | + GHAssertEqualStrings(string, @"this is a test", @"Failed to parse object data", @"Failed to parse object data"); | ||
243 | + | ||
244 | + [string release]; | ||
245 | + | ||
246 | + deleteContainerRequest = [ASICloudFilesContainerRequest deleteContainerRequest:@"ASICloudFilesTest"]; | ||
247 | + [deleteContainerRequest startSynchronous]; | ||
220 | } | 248 | } |
221 | 249 | ||
222 | - (void)testPostObject { | 250 | - (void)testPostObject { |
-
Please register or login to post a comment