I need to do a signed POST request from Angular to AWS API gateway and send multipart/form-data with document and additional parameters.
I create FormData that as follows: 
const formData = new FormData();
formData.append('document', document, document.name);
formData.append('document_metadata', new Blob(
  [JSON.stringify(metaData)],
  {
    type: 'application/json'
  })
);
Now, to do a request to AWS Gateway, I need to sign the request with all attributes being sent as body, meaning I need to somehow pass FormData to signature. The problem is that you can't get values of FormData without them being streamed.
to do that, I used approach mentioned here Get HTTP Body of Form in JavaScript. So I stream the file, decode it's values and combine it. This gives me the string that would be send with the request and with it I can sign the request ( with the help of https://github.com/mar753/aws-signature-v4 ).
async getFormDataStream(formData: FormData) {
    const response = new Response(formData);
    const stream = response.body;
    const reader = stream.getReader();
    const decoder = new TextDecoder('utf-8');
    const parent = this;
    let tempData = '';
    const headers: Headers = response.headers;
    headers.forEach((value, key) => {
      if(key ==='content-type') {
        this.customContentType = value;
      }
    });
    await reader.read()
      .then(function processData(result) {
        tempData = tempData + decoder.decode(result.value);
        if (result.done) {
          parent.customFormData = tempData;
          console.log('stream done');
          return;
        }
        return reader.read().then(processData);
      })
      .catch((err) => {
        console.log('catch stream cancellation:', err);
      });
}
Now I create the headers and request:
const headers = { 
   headers: new HttpHeaders({
      'X-Amz-Date': signature['X-Amz-Date'],
      'X-Amz-Security-Token': user.sessionToken,
      'x-api-access-token': user.getJwtToken(),
      'x-api-id-token': user.getJwtToken(),
      'Content-Type': this.customContentType, // contentType with boundary is generated from stream
      authorization: signature.Authorization
  };
this.http.post(APIGatewayEndpoint, this.customFormData, header); // customFormData is generated with stream
Everything I did so far works, I pass the Authorization without a problem and save the file. But the problem is that everything except for .txt file gets corrupted and I can't open it. I have to guesses what might be wrong:
- Document gets corrupted while decoding it with stream and SpringBoot can't parse it correctly
- SpringBoot isn't parsing raw data correctly?
Any help regarding the above would be appreciated as I'm stuck without options at the moment.
