问题
I upload my file to aws service from android. I configured it like this:
AwsMetadata awsMetadata = resultData.getParcelable(Params.CommandMessage.EXTRA_MESSAGE);
AWSCredentials awsCredentials = new BasicAWSCredentials(
awsMetadata.getAccountId(),
awsMetadata.getSecretKey()
);
// set up region
TransferManager transferManager = new TransferManager(awsCredentials);
Region region = Region.getRegion(Regions.fromName(awsMetadata.getRegionEndpoint()));
transferManager.getAmazonS3Client().setRegion(region);
final MediaItem mediaItem = datasource.get(0);
Log.d(App.TAG, "File is exists: "
+ mediaItem.getContentUri() + " "
+ new File(mediaItem.getContentUri()).exists());
// prepare file for upload
PutObjectRequest putObjectRequest = new PutObjectRequest(
awsMetadata.getBucketName(),
awsMetadata.getSecretKey(),
new File(mediaItem.getContentUri())
);
Log.d(App.TAG, "Total data: " + mediaItem.getSize());
Upload upload = transferManager.upload(putObjectRequest, new S3ProgressListener() {
private int totalTransfered = 0;
@Override
public void onPersistableTransfer(PersistableTransfer persistableTransfer) {
}
@Override
public void progressChanged(ProgressEvent progressEvent) {
Log.d(App.TAG, "Bytes are transferred: " + progressEvent.getBytesTransferred());
totalTransfered += progressEvent.getBytesTransferred();
long totalSize = mediaItem.getSize();
Log.d(App.TAG, "Total transferred: " + ((totalTransfered / totalSize) * 100) + " percent");
}
});
}
And I got SSLException:
06-01 11:45:00.712 5182-5768/com.home I/AmazonHttpClient﹕ Unable to execute HTTP request: Write error: ssl=0xb4bb3600: I/O error during system call, Connection reset by peer
javax.net.ssl.SSLException: Write error: ssl=0xb4bb3600: I/O error during system call, Connection reset by peer
at com.android.org.conscrypt.NativeCrypto.SSL_write(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:765)
at com.android.okio.Okio$1.write(Okio.java:70)
at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
at com.android.okio.RealBufferedSink.write(RealBufferedSink.java:44)
at com.android.okhttp.internal.http.HttpConnection$FixedLengthSink.write(HttpConnection.java:291)
at com.android.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:116)
at com.android.okio.RealBufferedSink$1.write(RealBufferedSink.java:131)
at com.amazonaws.http.UrlHttpClient.write(UrlHttpClient.java:155)
at com.amazonaws.http.UrlHttpClient.createConnection(UrlHttpClient.java:143)
at com.amazonaws.http.UrlHttpClient.execute(UrlHttpClient.java:60)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:353)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:196)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4234)
at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1644)
at com.amazonaws.mobileconnectors.s3.transfermanager.internal.UploadCallable.uploadInOneChunk(UploadCallable.java:134)
at com.amazonaws.mobileconnectors.s3.transfermanager.internal.UploadCallable.call(UploadCallable.java:126)
at com.amazonaws.mobileconnectors.s3.transfermanager.internal.UploadMonitor.upload(UploadMonitor.java:182)
at com.amazonaws.mobileconnectors.s3.transfermanager.internal.UploadMonitor.call(UploadMonitor.java:140)
at com.amazonaws.mobileconnectors.s3.transfermanager.internal.UploadMonitor.call(UploadMonitor.java:54)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Happens on Android 4.3 and 4.4
com.amazonaws.services.s3.model.AmazonS3Exception: There were headers present in the request which were not signed (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 06CAF94ADEFE242E), S3 Extended Request ID: ouMiu+15fshPnT9uz95T3Drj+Gea3gI1c+Rj34BhcSCzbIH2ypOeK9yvIlNCxbxt
Amazon SDK uses it's own client and it should be configured properly from the box.
What is the reason for this beahaviour?
回答1:
There is a bug in the SDK where certain headers aren't signed. It will affect S3 in some regions, e.g. Frankfurt (eu-central-1) and China (cn-north-1), where sigv4 is required.
AWS SDK for Android v2.2.2 is out http://aws.amazon.com/releasenotes/4067314458888112. This release addresses the sigv4 signing issue with S3. Check it out at http://aws.amazon.com/mobile/sdk/.
回答2:
I was having the same problem on Android when trying to upload directly from the device to S3, and it was related to time difference issues on the devices, as cutiko said. I was using latest SDK version available (2.3.3), so the mentioned SDK fix didn't really solve my problem.
What I did to solve it:
- Call an external service that returns the UTC time of an AWS server
- Calculate the time difference between device time and server time, both in UTC
- Use the s3Client.setTimeOffset() to set the time skew calculated before (in seconds)
Hope it helps.
来源:https://stackoverflow.com/questions/30565422/sslexception-due-uploading-item-for-amazon-service