亚马逊多部分上传 api for mac

Posted

技术标签:

【中文标题】亚马逊多部分上传 api for mac【英文标题】:amazon multipart upload api for mac 【发布时间】:2012-03-01 00:10:37 【问题描述】:

我从过去两天开始在谷歌上搜索关于在我的 mac 可可项目中使用亚马逊分段上传 api 的信息。我已经下载了适用于 ios 的 AWS sdk。但是没有找到如何在可可项目中使用该sdk。谁能给我一些示例代码来实现使用亚马逊 S3 分段上传的分段上传???

编辑: 由于适用于 IOS 的 AWS SDK 与 Cocoa 应用程序不兼容,我正在使用 Rest api 使用 libcurl 上传文件。我正在使用以下代码(参考http://dextercoder.blogspot.in/2012/02/multipart-upload-to-amazon-s3-in-three.html):

- (void)initUpload

    NSDate* now = [NSDate date];
    NSDateFormatter* formatter = [[[NSDateFormatter alloc] init] autorelease];

    [formatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"] autorelease]];
    [formatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
    [formatter setDateFormat:@"eee, dd MMM yyyy HH:mm:ss "];
    NSString *strDate = [NSString stringWithFormat:@"%@GMT", [formatter stringFromDate:now]];
    NSString *strDateString = [NSString stringWithFormat:@"Date: %@", strDate];
    const char *date = [strDateString UTF8String];

    NSString *stringToSign = [NSString stringWithFormat:@"POST\n\n\n%@\n/MY_BUCKET/test.pdf?uploads",strDate];
    NSString *signature = [self base64forData:[self HMACSHA1withKey:MY_SECRET forString:stringToSign]];
    signature = [signature stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];
    signature = [signature stringByReplacingOccurrencesOfString:@"/" withString:@"%2F"];
    signature = [signature stringByReplacingOccurrencesOfString:@"=" withString:@"%3D"];
    NSString *strAuthorization = [NSString stringWithFormat:@"Authorization: AWS MY_ACCESSID:%@", signature];
    const char *sig = [strAuthorization UTF8String];

    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curlHandle = curl_easy_init();
    struct curl_slist *headers=NULL;
    headers = curl_slist_append(headers, date);
    headers = curl_slist_append(headers, sig);
    CURLcode res;


    if (curlHandle) 
        curl_easy_setopt(curlHandle, CURLOPT_URL, "http://MY_BUCKET.s3.amazonaws.com/test.pdf?uploads");
        curl_easy_setopt(curlHandle, CURLOPT_POST, 1);
        curl_easy_setopt(curlHandle, CURLOPT_POSTFIELDS, "");
        curl_easy_setopt(curlHandle, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curlHandle, CURLOPT_VERBOSE,1L);            
        res = curl_easy_perform(curlHandle);

        curl_easy_cleanup(curlHandle);       
    


- (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];


- (NSString *)base64forData:(NSData *)data

    static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    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];

但它的给予回应

SignatureDoesNotMatch我们计算的请求签名与您提供的签名不匹配。请检查您的密钥和签名方法。”

知道我做错了什么吗???

【问题讨论】:

【参考方案1】:

您有一个随 SDK 本身提供的 AWS 服务(如 S3、SDB 等)的基本示例: http://docs.amazonwebservices.com/mobile/sdkforios/gsg/Welcome.html?r=1498

【讨论】:

感谢您的回复。在给定的 SDK 示例中没有分段上传的示例,这就是我问这个的原因。但是我从下面给出的其他地方找到了一些代码,但它给出了下面给出的例外。如果你能帮助我,请检查一下。【参考方案2】:

你可以参考http://dextercoder.blogspot.in/2012/02/multipart-upload-to-amazon-s3-in-three.html的java代码。告诉如何在没有 AWS 的情况下分段上传文件。

【讨论】:

感谢您的回复。如果您能帮助我解决我的问题,请查看编辑我的问题的一部分。 作为回应,您必须得到需要签名的字符串。只需仔细检查您要签名的字符串是否正确。 我改变了 base64 转换方法,现在它给出响应“HTTP/1.0 411 Length Required”。知道我做错了什么吗?? 你在标题中设置“Content-Length”吗? 不,我没有在标题中设置 Content-Length。

以上是关于亚马逊多部分上传 api for mac的主要内容,如果未能解决你的问题,请参考以下文章

亚马逊 MWS API:- 如何使用 PHP 将 xml 产品提要上传到 _POST_PRODUCT_DATA_

亚马逊商城 API

亚马逊 MWS API 中的 RequestThrottling 问题

如何将带有子文件夹的文件夹上传到亚马逊 s3?

在 iOS 上为亚马逊 SES 创建多部分/混合 MIME

亚马逊每日特卖 API