返回首页

帮助与服务

SDK-Android

概述

您可以使用Android SDK管理互盟云对象存储,可从https://github.com/aws/aws-sdk-android 下载Android Source Code

操作

由于android sdk用chunk 方式进行传输,并且把chunk-signature放置在body中,oss不支持这种case;sdk中支持的参数 S3ClientOptions.builder.disableChunkedEncoding在判断的时候并没有采用,因而需要更深层次的hack,需要继承AWSS3V4Signer.java并且覆盖原始的processRequestPayload(计算payload的签名并放在body的开头)和calculateContentHash(长度包含签名部分),代码如下:


package com.amazonaws.demo.s3transferutility;
import com.amazonaws.AmazonClientException;
import com.amazonaws.Request;
import com.amazonaws.services.s3.Headers;
import com.amazonaws.services.s3.internal.AWSS3V4Signer;
import com.amazonaws.util.BinaryUtils;
import java.io.IOException;
import java.io.InputStream;

public class HmAWSS3V4Signerextends AWSS3V4Signer {
    @Override
    protectedvoid processRequestPayload(Request<?> request, HeaderSigningResult headerSigningResult) {
    }

    @Override
    protected String calculateContentHash(Request<?> request) {
        request.addHeader("x-amz-content-sha256", "required");
        final String contentLength =
            request.getHeaders().get(Headers.CONTENT_LENGTH);
        final long originalContentLength;
        if (contentLength !=null) {
            originalContentLength = Long.parseLong(contentLength);
        }else { /**
              * "Content-Length" header could be missing if the caller is
              * uploading a stream without setting Content-Length in
              * ObjectMetadata. Before using sigv4, we rely on HttpClient to
              * add this header by using BufferedHttpEntity when creating the
              * HttpRequest object. But now, we need this information
              * immediately for the signing process, so we have to cache the
              * stream here.
              */
            try {
                originalContentLength = getContentLength(request);
            }catch (IOException e) {
                throw new AmazonClientException( 
                    "Cannot get the content-lenght of the request content.",e);
            }
        }
        request.addHeader("x-amz-decoded-content-length",Long.toString(originalContentLength));
        final InputStream payloadStream = getBinaryRequestPayloadStream(request);
        payloadStream.mark(-1);
        final String contentSha256 = BinaryUtils.toHex(hash(payloadStream));
        try {
            payloadStream.reset();
        }catch (final IOException e) {
            throw new AmazonClientException( 
                "Unable to reset stream after calculating AWS4 signature", e);
        }
        return contentSha256;
    }

    private long getContentLength(Request<?> request) throws IOException {
        InputStream content = request.getContent();
        if (!content.markSupported()) {
            throw new AmazonClientException("Failed to get content length");
        }
        final int DEFAULT_BYTE_LENGTH = 4096;
        long contentLength = 0;
        byte[ ] tmp =new byte[DEFAULT_BYTE_LENGTH];
        int read;
        content.mark(-1);
        while ((read = content.read(tmp)) != -1) {
            contentLength += read;
        }
        content.reset();
        return contentLength;
    }
}

然后利用SignerFactory.registerSigner("HmAWSS3V4Signer", HmAWSS3V4Signer.class)替换标准签名,实现代码如下:

SignerFactory.registerSigner("HmAWSS3V4Signer", HmAWSS3V4Signer.class);
 System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true");
 ClientConfiguration config = new ClientConfiguration();
 config.setProtocol(Protocol.HTTP);
 config.setSignerOverride("HmAWSS3V4Signer");
 sS3Client = new AmazonS3Client(getCredProvider(context.getApplicationContext()), config);
 sS3Client.setEndpoint("https://oss-cn-shenzhen.humengyun.com");
 S3ClientOptions options = S3ClientOptions.builder()
         .disableChunkedEncoding()
         .setPayloadSigningEnabled(true)
         .build();
 sS3Client.setS3ClientOptions(options);
现在注册,即可享受多款产品免费体验
立即注册
故障赔偿 无理由退款 快速备案 专业服务 服务支持