Загрузка в GCS с использованием SDK Java S3: «MD5, указанный вами в Content-MD5 или x-goog-хэше, не соответствует тому, что мы рассчитали»

# #google-cloud-storage #aws-sdk-java

Вопрос:

Я пытаюсь загрузить в облачное хранилище Google с помощью AWS SDK для Java 1.x. Я включил режим взаимодействия и поместил AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY в среду. Я могу перечислять объекты, но загрузка не работает для меня.

Код, который я использую, это

     AmazonS3 client =
        AmazonS3ClientBuilder.standard()
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(
                    "http://storage.googleapis.com", "auto"))
            .build();

    TransferManager tm = TransferManagerBuilder.standard()
        .withS3Client(client)
        .build();
    Upload upload = tm.upload(bucketName, key, new File(filename));
    upload.waitForCompletion();
 

Но результат, который я получаю, таков:

 com.amazonaws.services.s3.model.AmazonS3Exception: The MD5 you specified in Content-MD5 or x-goog-hash did not match what we computed. (Service: Amazon S3; Status Code: 400; Error Code: BadDigest; Request ID: null; S3 Extended Request ID: null; Proxy: null), S3 Extended Request ID: null
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1819)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1403)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1372)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1145)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
        at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5437)
        at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5384)
 

Тот же код нормально работает с S3 (за вычетом конфигурации конечной точки)

Ответ №1:

В документах GCS говорится:

В XML-API облачного хранилища фрагментированная кодировка передачи и подписи V4 в настоящее время не могут использоваться одновременно. Некоторые инструменты Amazon S3 по умолчанию используют кодировку фрагментированной передачи вместе с подписями; в таких случаях следует отключить кодировку фрагментированной передачи.

Я нашел два способа устранить эту ошибку

  1. Вы можете .withChunkedEncodingDisabled(true) при создании клиента:
      AmazonS3 client =
         AmazonS3ClientBuilder.standard()
             .withChunkedEncodingDisabled(true)  // <<<<<<<
             .withEndpointConfiguration(
                 new AwsClientBuilder.EndpointConfiguration(
                     "http://storage.googleapis.com", "auto"))
             .build();
     
  2. Вы можете переключиться на конечную точку https:
      AmazonS3 client =
         AmazonS3ClientBuilder.standard()
             .withEndpointConfiguration(
                 new AwsClientBuilder.EndpointConfiguration(
                     "https://storage.googleapis.com", "auto"))
             .build();