I'm trying to make a POST request to this specific endpoint from Apex to include what is required; a task Id and a single file. It has been very difficult.

At first, Bad Request responses was all I got, but after fiddling around with things such as \r\n in the construction of the blob, I started getting Internal Server Errors.

My code below is mostly thanks to this post by Enrico Murro, however he only includes a file without any additional parameters (there is a comment on that post by Vinod with a possible solution by Enrico, but I couldn't understand it, maybe someone here can).

Here is how I have constructed the blob. If anyone has any expertise regarding the matter, please please share!

String boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW';
String preheader = '--'+boundary+'\nContent-Disposition: form-data; name="task"\n'+taskId;
String header = '--'+boundary+'\nContent-Disposition: form-data; name="file"; filename="'+file_name+'";\nContent-Type: application/octet-stream';

String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(preheader+header+'\r\n\r\n'));
while (headerEncoded.endsWith('=')) {
    header += ' ';
    headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));}
String bodyEncoded = EncodingUtil.base64Encode(file_body);
Blob bodyBlob = null;
String last4Bytes = bodyEncoded.substring(bodyEncoded.length()-4,bodyEncoded.length());
String footer = '--'+boundary+'--';
if (last4Bytes.endsWith('==')) {
    last4Bytes = last4Bytes.substring(0,2) + '0K';
    bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;
} else if (last4Bytes.endsWith('=')) {
    last4Bytes = last4Bytes.substring(0,3) + 'N';
    bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;
    footer = '\n' + footer;
} else {footer = '\r\n' + footer;}

String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);

HttpRequest req = new HttpRequest();
req.setHeader('Content-Type','multipart/form-data; boundary='+boundary);
for (String key : headerMap.keySet()) System.debug(key + ': ' + headerMap.get(key));
if (headerMap != null) for (String key : headerMap.keySet()) req.setHeader(key, headerMap.get(key));

Http http = new Http();
HTTPResponse res = http.send(req);

After a lot of meddling around, I ended up with the following method of simply prepending the preheader string which is my additional parameter to the headerEncoded string. I've tried the placement of this additional parameter all over and around the body before and after constructing the blob, but to no avail.

  • 1
    Thanks for the link. Maybe it would help someone else encountering this issue. I decided to pivot and try something completely different, so this issue is no longer of concern for my use case. Commented Oct 28, 2020 at 8:49


Browse other questions tagged .