Toggle navigation
Toggle navigation
This project
Loading...
Sign in
iOS
/
asi-http-request
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Ben Copsey
2010-09-19 15:21:54 +0100
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
cd552d7892d7f3c4451a45ce90b7107cde600263
cd552d78
1 parent
484c5978
Added support for S3 storage class (eg Reduced Redundancy)
Added tests for canned ACLs
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
75 additions
and
11 deletions
Classes/S3/ASIS3ObjectRequest.h
Classes/S3/ASIS3ObjectRequest.m
Classes/S3/ASIS3Request.h
Classes/S3/ASIS3Request.m
Classes/Tests/ASIS3RequestTests.m
Classes/S3/ASIS3ObjectRequest.h
View file @
cd552d7
...
...
@@ -10,6 +10,9 @@
#import <Foundation/Foundation.h>
#import "ASIS3Request.h"
// Constants for storage class
extern
NSString
*
const
ASIS3StorageClassStandard
;
extern
NSString
*
const
ASIS3StorageClassReducedRedundancy
;
@interface
ASIS3ObjectRequest
:
ASIS3Request
{
...
...
@@ -28,7 +31,14 @@
// Can be autodetected when PUTing a file from disk, will default to 'application/octet-stream' when PUTing data
NSString
*
mimeType
;
// Set this to specify you want to work with a particular subresource (eg an acl for that resource)
// See requestWithBucket:key:subResource:, below.
NSString
*
subResource
;
// The storage class to be used for PUT requests
// Set this to ASIS3StorageClassReducedRedundancy to save money on storage, at (presumably) a slightly higher risk you will lose the data
// If this is not set, no x-amz-storage-class header will be sent to S3, and their default will be used
NSString
*
storageClass
;
}
// Create a request, building an appropriate url
...
...
@@ -66,5 +76,5 @@
@property
(
retain
,
nonatomic
)
NSString
*
sourceKey
;
@property
(
retain
,
nonatomic
)
NSString
*
mimeType
;
@property
(
retain
,
nonatomic
)
NSString
*
subResource
;
@property
(
retain
,
nonatomic
)
NSString
*
storageClass
;
@end
...
...
Classes/S3/ASIS3ObjectRequest.m
View file @
cd552d7
...
...
@@ -8,6 +8,8 @@
#import "ASIS3ObjectRequest.h"
NSString
*
const
ASIS3StorageClassStandard
=
@"STANDARD"
;
NSString
*
const
ASIS3StorageClassReducedRedundancy
=
@"REDUCED_REDUNDANCY"
;
@implementation
ASIS3ObjectRequest
...
...
@@ -96,13 +98,14 @@
[
sourceKey
release
];
[
sourceBucket
release
];
[
subResource
release
];
[
storageClass
release
];
[
super
dealloc
];
}
-
(
void
)
buildURL
{
if
([
self
subResource
])
{
[
self
setURL
:[
NSURL
URLWithString
:[
NSString
stringWithFormat
:
@"%@://%@.%@%@?%@"
,[
self
requestScheme
],[[
self
class
]
S3Host
],[
ASIS3Request
stringByURLEncodingForS3Path
:[
self
key
]],[
self
subResource
]]]];
[
self
setURL
:[
NSURL
URLWithString
:[
NSString
stringWithFormat
:
@"%@://%@.%@%@?%@"
,[
self
requestScheme
],[
self
bucket
],[
[
self
class
]
S3Host
],[
ASIS3Request
stringByURLEncodingForS3Path
:[
self
key
]],[
self
subResource
]]]];
}
else
{
[
self
setURL
:[
NSURL
URLWithString
:[
NSString
stringWithFormat
:
@"%@://%@.%@%@"
,[
self
requestScheme
],[
self
bucket
],[[
self
class
]
S3Host
],[
ASIS3Request
stringByURLEncodingForS3Path
:[
self
key
]]]]];
}
...
...
@@ -134,6 +137,9 @@
NSString
*
path
=
[
ASIS3Request
stringByURLEncodingForS3Path
:[
self
sourceKey
]];
[
headers
setObject
:[[
self
sourceBucket
]
stringByAppendingString
:
path
]
forKey
:
@"x-amz-copy-source"
];
}
if
([
self
storageClass
])
{
[
headers
setObject
:[
self
storageClass
]
forKey
:
@"x-amz-storage-class"
];
}
return
headers
;
}
...
...
@@ -146,12 +152,11 @@
return
[
super
stringToSignForHeaders
:
canonicalizedAmzHeaders
resource
:
canonicalizedResource
];
}
@synthesize
bucket
;
@synthesize
key
;
@synthesize
sourceBucket
;
@synthesize
sourceKey
;
@synthesize
mimeType
;
@synthesize
subResource
;
@synthesize
storageClass
;
@end
...
...
Classes/S3/ASIS3Request.h
View file @
cd552d7
...
...
@@ -23,13 +23,18 @@ extern NSString *const ASIS3AccessPolicyAuthenticatedRead;
extern
NSString
*
const
ASIS3AccessPolicyBucketOwnerRead
;
extern
NSString
*
const
ASIS3AccessPolicyBucketOwnerFullControl
;
// Constants for requestScheme - defaults is ASIS3RequestSchemeHTTP
extern
NSString
*
const
ASIS3RequestSchemeHTTP
;
extern
NSString
*
const
ASIS3RequestSchemeHTTPS
;
typedef
enum
_ASIS3ErrorType
{
ASIS3ResponseParsingFailedType
=
1
,
ASIS3ResponseErrorType
=
2
}
ASIS3ErrorType
;
extern
NSString
*
const
ASIS3RequestSchemeHTTP
;
extern
NSString
*
const
ASIS3RequestSchemeHTTPS
;
@interface
ASIS3Request
:
ASIHTTPRequest
<
NSCopying
,
NSXMLParserDelegate
>
{
...
...
Classes/S3/ASIS3Request.m
View file @
cd552d7
...
...
@@ -19,7 +19,6 @@ NSString *const ASIS3AccessPolicyBucketOwnerFullControl = @"bucket-owner-full-co
NSString
*
const
ASIS3RequestSchemeHTTP
=
@"http"
;
NSString
*
const
ASIS3RequestSchemeHTTPS
=
@"https"
;
static
NSString
*
sharedAccessKey
=
nil
;
static
NSString
*
sharedSecretAccessKey
=
nil
;
...
...
@@ -119,7 +118,7 @@ static NSString *sharedSecretAccessKey = nil;
// Add a header for the access policy if one was set, otherwise we won't add one (and S3 will default to private)
NSMutableDictionary
*
amzHeaders
=
[
self
S3Headers
];
NSString
*
canonicalizedAmzHeaders
=
@""
;
for
(
NSString
*
header
in
[
amzHeaders
key
Enumerator
])
{
for
(
NSString
*
header
in
[
amzHeaders
key
sSortedByValueUsingSelector
:
@selector
(
compare
:)
])
{
canonicalizedAmzHeaders
=
[
NSString
stringWithFormat
:
@"%@%@:%@
\n
"
,
canonicalizedAmzHeaders
,[
header
lowercaseString
],[
amzHeaders
objectForKey
:
header
]];
[
self
addRequestHeader
:
header
value
:[
amzHeaders
objectForKey
:
header
]];
}
...
...
Classes/Tests/ASIS3RequestTests.m
View file @
cd552d7
...
...
@@ -20,8 +20,6 @@ static NSString *accessKey = @"";
// You should run these tests on a bucket that does not yet exist
static
NSString
*
bucket
=
@""
;
// Used for subclass test
@interface
ASIS3ObjectRequestSubclass
:
ASIS3ObjectRequest
{}
@end
...
...
@@ -220,6 +218,7 @@ static NSString *bucket = @"";
ASIS3ObjectRequest
*
request
=
[
ASIS3ObjectRequest
PUTRequestForFile
:
filePath
withBucket
:
bucket
key
:
key
];
[
request
setSecretAccessKey
:
secretAccessKey
];
[
request
setAccessKey
:
accessKey
];
[
request
setStorageClass
:
ASIS3StorageClassReducedRedundancy
];
[
request
startSynchronous
];
success
=
[[
request
responseString
]
isEqualToString
:
@""
];
GHAssertTrue
(
success
,
@"Failed to PUT a file to S3"
);
...
...
@@ -785,9 +784,55 @@ static NSString *bucket = @"";
// DELETE it
request
=
[
ASIS3ObjectRequest
DELETERequestWithBucket
:
bucket
key
:
@"king"
];
[
request
setRequestScheme
:
ASIS3RequestSchemeHTTPS
];
[
request
startSynchronous
];
success
=
[[
request
responseString
]
isEqualToString
:
@""
];
GHAssertTrue
(
success
,
@"Failed to DELETE the copy from S3"
);
GHAssertTrue
(
success
,
@"Failed to DELETE the object from S3"
);
// Delete the bucket
request
=
[
ASIS3BucketRequest
DELETERequestWithBucket
:
bucket
];
[
request
setRequestScheme
:
ASIS3RequestSchemeHTTPS
];
[
request
startSynchronous
];
GHAssertNil
([
request
error
],
@"Failed to delete a bucket"
);
[
ASIS3Request
setSharedAccessKey
:
nil
];
[
ASIS3Request
setSharedSecretAccessKey
:
nil
];
}
// Ideally this test would actually parse the ACL XML and check it, but for now it just makes sure S3 doesn't return an error
-
(
void
)
testCannedACLs
{
[
ASIS3Request
setSharedAccessKey
:
accessKey
];
[
ASIS3Request
setSharedSecretAccessKey
:
secretAccessKey
];
// Create a bucket
ASIS3Request
*
request
=
[
ASIS3BucketRequest
PUTRequestWithBucket
:
bucket
];
[
request
setRequestScheme
:
ASIS3RequestSchemeHTTPS
];
[
request
startSynchronous
];
GHAssertNil
([
request
error
],
@"Failed to create a bucket"
);
NSArray
*
ACLs
=
[
NSArray
arrayWithObjects
:
ASIS3AccessPolicyPrivate
,
ASIS3AccessPolicyPublicRead
,
ASIS3AccessPolicyPublicReadWrite
,
ASIS3AccessPolicyAuthenticatedRead
,
ASIS3AccessPolicyBucketOwnerRead
,
ASIS3AccessPolicyBucketOwnerFullControl
,
nil
];
for
(
NSString
*
cannedACL
in
ACLs
)
{
// PUT object
NSString
*
key
=
@"king"
;
request
=
[
ASIS3ObjectRequest
PUTRequestForData
:[
@"fink"
dataUsingEncoding
:
NSUTF8StringEncoding
]
withBucket
:
bucket
key
:
key
];
[
request
setAccessPolicy
:
cannedACL
];
[
request
startSynchronous
];
GHAssertNil
([
request
error
],
@"Failed to PUT some data into S3"
);
// GET object ACL
request
=
[
ASIS3ObjectRequest
requestWithBucket
:
bucket
key
:
key
subResource
:
@"acl"
];
[
request
startSynchronous
];
GHAssertNil
([
request
error
],
@"Failed to fetch the object"
);
}
// DELETE it
request
=
[
ASIS3ObjectRequest
DELETERequestWithBucket
:
bucket
key
:
@"king"
];
[
request
setRequestScheme
:
ASIS3RequestSchemeHTTPS
];
[
request
startSynchronous
];
BOOL
success
=
[[
request
responseString
]
isEqualToString
:
@""
];
GHAssertTrue
(
success
,
@"Failed to DELETE the object from S3"
);
// Delete the bucket
request
=
[
ASIS3BucketRequest
DELETERequestWithBucket
:
bucket
];
...
...
Please
register
or
login
to post a comment