I'm using reactive spring and trying to upload a ".csv" file into AWS S3 using a presigned URL.
I spring webclient for this and my code snippet as below
Webclient bean
@Bean
public WebClient webClient(WebClient.Builder webClientBuilder) {
ConnectionProvider provider = ConnectionProvider
.builder("customFixedConnectionPool").maxConnections(maxConnections).pendingAcquireTimeout(
Duration.ofMillis(acquireTimeout)).build();
HttpClient httpClient = HttpClient.create(provider).resolver(DefaultAddressResolverGroup.INSTANCE);
return webClientBuilder
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build(); }
FileUploadClient.java
Note: in below, BodyInserters.fromResource(resource)
returns BodyInserter<Resource, ReactiveHttpOutputMessage>
@Component
public class FileUploadClient implements FileUploadClientInterface {
public FileUploadClient(WebClient webClient) {
this.webClient = webClient.mutate()
.build();
}
private final WebClient webClient;
@Override
public Mono<FileUploadResponse> uploadFIle(String preSignedUrl, String filePath) {
Resource resource = new PathResource(filePath);
return webClient.put()
.uri(preSignedUrl)
.body(BodyInserters.fromResource(resource))
.exchangeToMono(response -> {
if (response.statusCode().equals(HttpStatus.NO_CONTENT)) {
fileUploadResponse.setCode(HttpStatus.NO_CONTENT.value());
fileUploadResponse.setMessage("FILE_UPLOAD_SUCCESS");
return Mono.just(fileUploadResponse);
} else {
return response.bodyToMono(String.class)
.flatMap(responseBodyString -> {
fileUploadResponse.setCode(response.statusCode().value());
fileUploadResponse.setMessage(responseBodyString);
return Mono.just(fileUploadResponse);
});
}
}).onErrorResume(throwable -> {
fileUploadResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
fileUploadResponse.setMessage(throwable.getMessage());
System.out.println("uploadLog Error: "+ throwable.getMessage());
return Mono.just(fileUploadResponse);
});
}
}
`
When executing, I receive below error:
<?xml version="1.0" encoding="UTF-8"?> <Error><Code>AuthorizationQueryParametersError</Code><Message>Error parsing the X-Amz-Credential parameter; the Credential is mal-formed; expecting "<YOUR-AKID>/YYYYMMDD/REGION/SERVICE/aws4_request".</Message><RequestId>xxxxxx</RequestId><HostId>xxxxxx</HostId></Error>
Presigned URL i use has below like format:
https://xxx-xx-xxx-xx.s3.ap-southeast-1.amazonaws.com/PG00009912/PENDING/REQ_PG00009912_11112022.csv?X-Amz-Security-Token=dzEIz%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDLAplr5Vvi%2F0mZqIMSLABMetINeSCoOWcMxBPkBQN44hB1gyNBFfSPoAOLe0FY8lhBgsBis%2F7oRp3WU8H6qDUpI%2BsxCZEIFMWTkoP%2FIZP%2FAUG5ib8qAIx3gCuVtFLLx77kxdclqm8PhC6OlkYZ5fBrlUl7hHvY9w8hdFAWvRByaqsNKGWiiwwhaMvWZNI65O%2BoWZ84ESwBQCZxbp3e4TdWvUEuB%2FnVpyoMbUfugGxVK2rG58rgJpUKK5E9rv8ZTzIkUqjH7Ql5ZL%2FCt0%2FTa%2Fbj98617MKMk2bPu7dcLZpurNJ75J4AIH2a5%2Bql5tk7FB2f8uwIad3ZskiV5rtz%2FmyoqxFxc5eaaC6YbXDC06eHcMirg81U15XXqFgM2Qi%2FFjx3yutm0E59aPHSEz1K0ucfe2%2FUYLYbB57V%2FgFD8MO8pwHKmLDC0hXVFhXny8nnpPq5PBkqzZomk%2BBOiwBnkP5H98tRXRshwhqnmIMh80xyEy6%2FfCLBRSmJEMrzTpQqDpi%2B1%2Fg7wnOK8Gpv2iyLIU%2FBTD1%2FwgQ716qVsDjH8eTyPga513G6uZ94Kp4pKr1M1E1wsh2IbuvfMlPQ%2FOnL7zA07jZtNxWe%2B538Gs5%2FMwtz9fM%2FoEkeNolx96k3cgDCyQCiD8HU%2FKJk8UYUttSv8CBwkI3PwAW1Sdty0O2L0dGGyFFwwtu6wql8%2BJYxkAZOdZCxDDg2YoaeayVrjYq9mp9yZ%2BxJR1OsVuwmfRkQZcgkUPj7MnCGdgKN1KJAiNk6uVs%2FpSRxEWtSeJlhU806%2FACCiznbObBjIrEwg1WuV%2BkReFAoD86rDec%2BE%2BKmhjb2ahFqHqtY9V4YAYF82RtEzUQld6MQ%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20221110T101307Z&X-Amz-SignedHeaders=host&X-Amz-Expires=26212&X-Amz-Credential=H2DP6FQ%2F20221110%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Signature=787c80356d749c9e0e1231ceb75d64df77f1cf40830146dfa
I'm using Java 1.8 on Windows platform and I don't set any headers in my webclient .
Update (Solution)
Issue was due to webclient has further encoded my presigned url which is unnecessary. Fixed by using .uri(URI.create(preSignedUrl))
instead of just .uri(preSignedUrl)
.