2017-03-21 61 views
1

誰かが同じ問題に遭遇した場合に備えて、私はこのバグを見つけるために長い間検索してきました。 私はS3にデータをアップロードするために次のコードスニペットを実装しました:AWS S3にアップロードするときのSignatureDoesNotMatch

public class S3FileUploadHandler { 
    private static final String USER_META_DATA_KEY_MODIFIED = "last-modified"; 
    private static final SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy"); 
    private final AmazonS3Client s3; 
    private final TransferManager tm; 
    private final String bucketName = "myTestBucket"; 
    ... 

    public void run() { 
     File file = ... // retrieve file to upload 
     FileInputStream fis = null; 
     try { 
      fis = new FileInputStream(file); 
      final String key = ... // some path on S3 
      final ObjectMetadata objectMetadata = buildObjectMetadata(file); 
      final PutObjectRequest req = new PutObjectRequest(bucketName, key, fis, objectMetadata); 
      final Upload upload = tm.upload(req); 
      upload.addProgressListener(new MyProgressListener(upload)); 
      upload.waitForCompletion(); 
     } catch (final AmazonServiceExceptionase) { 
      logger.debug("Couldn't put file {}. AmazonServiceException {}", file, ase); 
      logger.error("Couldn't put file {}. AmazonServiceException Error Message: {}", file, ase.getMessage()); 
      logger.error("HTTP Status Code: " + ase.getStatusCode()); 
      logger.error("AWS Error Code: " + ase.getErrorCode()); 
      logger.error("Error Type:  " + ase.getErrorType()); 
      logger.error("Request ID:  " + ase.getRequestId()); 
     } catch (final Exception e) { 
      ... 
     } finally { 
      if (fis != null) { 
       fis.close(); 
      } 
     } 
    } 

    private ObjectMetadata buildObjectMetadata(final File file) { 
     final ObjectMetadata metadata = new ObjectMetadata(); 
     metadata.setContentLength(file.length()); 
     final Date lastModifiedDate = new Date(file.lastModified()); 
     final String dateStr = sdf.format(lastModifiedDate); 
     metadata.addUserMetadata(USER_META_DATA_KEY_MODIFIED, dateStr); 
     return metadata; 
    } 
} 

コードはAWS S3にアップロードファイルを切り取ると、ファイルの最終更新タイムスタンプを保持するために、私は、ユーザメタデータとして、この情報を設定します。

は、以下の例外を除いて、時々アップロード休憩、上記のコードは動作しますSomtimes:

Couldn't put file C:\Temp\xyz.txt. AmazonServiceException Error Message: The request signature we calculated does not match the signature you provided. Check your key and signing method. (Service: Amazon S3; Status Code: 403; Error Code: SignatureDoesNotMatch; Request ID: B8BC3251B9C1A3F5) 
HTTP Status Code: 403 
AWS Error Code: SignatureDoesNotMatch 
Error Type:  Client 
Request ID:  B8BC3251B9C1A3F5 

答えて

1

上記のコードにバグがSimpleDateFormatのが潜在的に非ASCII文字が含まれていること、です。

など。ドイツ語ロケールの最終更新日時は

ユーザー定義のメタデータは、キーと値のペアのセットであることを

Di Mär 21 10:29:00 MEZ 2017 

AWS documentation状態かもしれません。 Amazon S3は、ユーザ定義のメタデータ・キーを小文字で格納します。 POSTを使用してSOAPまたはブラウザベースのアップロードを使用する場合、RESTおよびUTF-8を使用する場合、各キーと値のペアはUS-ASCIIに準拠する必要があります。

AWSは本当にここより良い例外テキストに取り組むことができますが、上記の情報を修正は簡単です

private static final SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); 

...(常に)その結果は、メタデータ列を受け入れ

Tue Mar 21 10:29:00 CET 2017 
+0

感謝の意を表します。残念なことに、詳細な例外が返されますが、SDKはそれを隠します。驚いたことに、例外(私は自分自身のライブラリを書いたので発見した、SDKを使用しない)はS3の問題を明らかにしています。リクエストに署名するときに '? 'を付けます。 (!?)意図的に間違った署名を生成すると、実際にはutf8メタデータを格納することができます。オブジェクトのメタデータを見ると、コンソールは例外をスローしますが、ダウンロード時にはそこにあります。 –

関連する問題