4

I'm trying to implement the equivalent of the following cURL command in Spring, to call an API (Twilio) to upload a media :

curl --header 'Authorization: Basic <VALID_BASIC_AUTH_TOKEN>' --data-binary "@test.png" https://mcs.us1.twilio.com/v1/Services/<ACCOUNT_ID>/Media -v

This request works perfectly, and the headers generated are :

> Accept: */*
> Authorization: Basic <VALID_BASIC_AUTH_TOKEN>
> Content-Length: 385884
> Content-Type: application/x-www-form-urlencoded

My code in java is :

@Repository
public class TwilioMediaRepository {

    private RestTemplate client;

    @Value("${twilio.chat.sid}")
    private String chatSid;

    @Value("${twilio.media.api.endpoint}")
    private String endpoint;

    @Value("${twilio.all.accountsid}")
    private String accountSid;

    @Value("${twilio.all.authtoken}")
    private String accountSecret;

    @Autowired
    public TwilioMediaRepository(RestTemplate client) {
        this.client = client;
    }

    public Media postMedia(byte[] file) {
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.ALL));
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        client.getInterceptors().add(new RequestResponseLoggingInterceptor());
        client.getInterceptors().add(new BasicAuthorizationInterceptor(accountSid, accountSecret));

        HttpEntity<byte[]> entity = new HttpEntity<>(file, headers);

        ResponseEntity<Media> media = this.client.postForEntity(generateUrl(), entity, Media.class);
        return media.getBody();
    }

    private String generateUrl() {
        return String.format(endpoint, chatSid);
    }
}

The log of the request show that the headers are exactly the same as the cURL request :

URI         : https://mcs.us1.twilio.com/v1/Services/<ACCOUNT_ID>/Media
Method      : POST
Headers     : {Accept=[*/*], Content-Type=[application/x-www-form-urlencoded], Content-Length=[385884], Authorization=[Basic <VALID_BASIC_AUTH_TOKEN>]}
Request body: <bunch of unreadable bytes>

But the log of the response shows that my request is not valid for Twilio :

Status code  : 400
Status text  : Bad Request
Headers      : {Content-Type=[text/html], Date=[Wed, 08 Aug 2018 15:32:50 GMT], Server=[nginx], X-Shenanigans=[none], Content-Length=[166], Connection=[keep-alive]}
Response body: <html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

How are we supposed to send a binary file to comply with the --data-binary property of cURL in Spring ? I tried to send HttpEntity<ByteArrayResource>, HttpEntity<byte[]>, HttpEntity<FileSystemResource>, HttpEntity<ClassPathResource> but without any success. Note : This API doesn't support multipart file upload.

1 Answer 1

3

Problem solved. Contrarily to what the cURL log show, the API I use doesn't want a application/x-www-form-urlencoded content-type.

Using the file content-type solve the issue (in my case image/png)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.