Dưới đây là một ví dụ cơ bản sử dụng PUT. Rõ ràng bạn nên sử dụng một hàng đợi chứ không phải là một yêu cầu đồng bộ trong thực tế thế giới.
Nếu bạn thay đổi các tiêu đề AMZ, đừng quên cập nhật 'canonicalizedAmzHeaders' theo hướng dẫn của Amazon.
#import "ASIHTTPRequest.h"
#import <CommonCrypto/CommonHMAC.h>
...
- (void)testS3
{
NSString *filePath = @"/path/to/file";
NSString *contentType = @"text/plain";
NSString *bucket = @"mybucket";
NSString *path = @"test";
NSString *secretAccessKey = @"my-secret-access-key";
NSString *accessKey = @"my-access-key";
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss zzzz"];
NSString *date = [dateFormatter stringFromDate:[NSDate date]];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@.s3.amazonaws.com/%@",bucket,path]]] autorelease];
[request setPostBodyFilePath:filePath];
[request setShouldStreamPostDataFromDisk:YES];
[request setRequestMethod:@"PUT"];
[request addRequestHeader:@"x-amz-acl" value:@"private"];
[request addRequestHeader:@"Content-Type" value:contentType];
[request addRequestHeader:@"Date" value:date];
NSString *canonicalizedAmzHeaders = @"x-amz-acl:private";
NSString *canonicalizedResource = [NSString stringWithFormat:@"/%@/%@",bucket,path];
NSString *stringToSign = [NSString stringWithFormat:@"PUT\n\n%@\n%@\n%@\n%@",contentType,date,canonicalizedAmzHeaders,canonicalizedResource];
NSString *signature = [self base64forData:[self HMACSHA1withKey:secretAccessKey forString:stringToSign]];
NSString *auth = [NSString stringWithFormat:@"AWS %@:%@",accessKey,signature];
[request addRequestHeader:@"Authorization" value:auth];
[request start];
NSLog(@"%@",[request responseString]);
}
// Source: http://stackoverflow.com/questions/476455/is-there-a-library-for-iphone-to-work-with-hmac-sha-1-encoding
- (NSData *)HMACSHA1withKey:(NSString *)key forString:(NSString *)string
{
NSData *clearTextData = [string dataUsingEncoding:NSUTF8StringEncoding];
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0};
CCHmacContext hmacContext;
CCHmacInit(&hmacContext, kCCHmacAlgSHA1, keyData.bytes, keyData.length);
CCHmacUpdate(&hmacContext, clearTextData.bytes, clearTextData.length);
CCHmacFinal(&hmacContext, digest);
return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
}
//Source http://www.cocoadev.com/index.pl?BaseSixtyFour
- (NSString *)base64forData:(NSData *)data
{
static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/";
if ([data length] == 0)
return @"";
char *characters = malloc((([data length] + 2)/3) * 4);
if (characters == NULL)
return nil;
NSUInteger length = 0;
NSUInteger i = 0;
while (i < [data length])
{
char buffer[3] = {0,0,0};
short bufferLength = 0;
while (bufferLength < 3 && i < [data length])
buffer[bufferLength++] = ((char *)[data bytes])[i++];
// Encode the bytes in the buffer to four characters, including padding "=" characters if necessary.
characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2];
characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
if (bufferLength > 1)
characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
else characters[length++] = '=';
if (bufferLength > 2)
characters[length++] = encodingTable[buffer[2] & 0x3F];
else characters[length++] = '=';
}
return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease];
}
Hmmmm - khá khó để giúp đỡ mà không có bất kỳ chi tiết nào ngoài 'nó không hoạt động'. Điều gì đặc biệt? Không theo cách nào? Mã? Bạn đã thử cái gì? – Hunter