Как создать правильное использование RestTemplate из curl? - PullRequest
2 голосов
/ 07 января 2020

У меня есть рабочая команда curl, приведенная ниже:

curl -v  -H "Content-Type:application/octet-stream" \
         -H "x-amz-server-side-encryption:aws:kms" \
         -H "x-amz-server-side-encryption-aws-kms-key-id:abcdef81-abcd-4c85-b1d8-ee540d0a5f5d" \
         --upload-file /Users/fd/Downloads/video.mp4 \
         'https://video-uploads-prod.s3-accelerate.amazonaws.com/ABCDEAQGZHEhM55fvvA/ads-aws_userUploadedVideo?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200106T165718Z&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-server-side-encryption%3Bx-amz-server-side-encryption-aws-kms-key-id&X-Amz-Expires=86400&X-Amz-Credential=ABCDEFHLWTCWZ2MUPPBQ%2F20200106%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=037949abcd1234b063c75d3d505dd9120dd3fa9250c1ababa152e91fee123ca0'

Curl работает правильно:

* We are completely uploaded and fine
< HTTP/1.1 200 OK

Однако, когда я пытаюсь использовать RestTemplate (я использую весенняя загрузка 1.5.6) Я не могу заставить его работать. Я использую код:

byte[] media = //video in mp4//;
String uploadUrl = "https://video-uploads-prod.s3-accelerate.amazonaws.com/ABCDEAQGZHEhM55fvvA/ads-aws_userUploadedVideo?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200106T165718Z&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-server-side-encryption%3Bx-amz-server-side-encryption-aws-kms-key-id&X-Amz-Expires=86400&X-Amz-Credential=ABCDEFHLWTCWZ2MUPPBQ%2F20200106%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=037949abcd1234b063c75d3d505dd9120dd3fa9250c1ababa152e91fee123ca0";

RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.set("x-amz-server-side-encryption", encryption);
headers.set("x-amz-server-side-encryption-aws-kms-key-id", awsKmsKeyId);

HttpEntity entity = new HttpEntity<>(media, headers);

ResponseEntity<String> respEntity = restTemplate.exchange(uploadUrl, HttpMethod.POST, entity, String.class);

Я получаю от AWS ошибку:

<Error>
   <Code>AuthorizationQueryParametersError</Code>
   <Message>Error parsing the X-Amz-Credential parameter; the Credential is mal-formed; expecting "&lt;YOUR-AKID&gt;/YYYYMMDD/REGION/SERVICE/aws4_request".</Message>
   <RequestId>51FF099744C43804</RequestId>
   <HostId>FOlLws+txYMP0hKEg7aDjQeeARdn7bJN+lw7q/aGA48hRnr1YEsJrVmRi6oEz+mkpHlTIax5MkI=</HostId>
</Error>

Я подозреваю, что RestTemplate меняет кодировку URL. Есть ли в любом случае повторить точно так же, как curl с RestTemplate?

Ответы [ 2 ]

0 голосов
/ 07 января 2020

Я мог бы заставить его работать после того, как много боролся с этим. Код довольно уродливый, но заставил работать. Опубликовать для других, если вам это нужно. В любом случае, это не отвечает на мой вопрос. Я хочу получить точную конфигурацию RestTemplate из команды curl .

Мне пришлось вручную декодировать каждый параметр запроса с помощью URLDecoder.decode, а затем создать URI с UriComponentsBuilder.fromHttpUrl и добавленными ранее декодированными параметрами

byte[] media = //video in mp4//;
String uploadUrl = "https://video-uploads-prod.s3-accelerate.amazonaws.com/ABCDEAQGZHEhM55fvvA/ads-aws_userUploadedVideo?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20200106T165718Z&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-server-side-encryption%3Bx-amz-server-side-encryption-aws-kms-key-id&X-Amz-Expires=86400&X-Amz-Credential=ABCDEFHLWTCWZ2MUPPBQ%2F20200106%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=037949abcd1234b063c75d3d505dd9120dd3fa9250c1ababa152e91fee123ca0";

RestTemplate restTemplate = new RestTemplate();

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.set("x-amz-server-side-encryption", encryption);
headers.set("x-amz-server-side-encryption-aws-kms-key-id", awsKmsKeyId);

HttpEntity entity = new HttpEntity<>(media, headers);

String url = uploadUrl.split("\\?")[0];
String[] urlParams = uploadUrl.split("\\?")[1].split("&");

MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();

for (String p : urlParams) {
    String key = p.split("=")[0];
    String value = URLDecoder.decode(p.split("=")[1], StandardCharsets.UTF_8.toString());
    params.put(key, Collections.singletonList(value));
}

String uri = UriComponentsBuilder.fromHttpUrl(url)
        .queryParams(params)
        .build()
        .toUriString();

ResponseEntity<String> respEntity = restTemplate.exchange(uri, HttpMethod.PUT, entity, String.class);
0 голосов
/ 07 января 2020

Я не тестировал следующий подход, но что если вы передадите расширенный URL-адрес экземпляру restTemplate?

String uploadUrl = "...{your_params_in_placeholders}";
URI expanded = new UriTemplate(url).expand(uploadUrl, <param_values>);
url = URLDecoder.decode(expanded.toString(), "UTF-8");
restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

Если он не работает, вы можете попытаться обратить внимание на закодированные значения в вашем URL (я имею в виду "% 2F" и т. д.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...