0

I write an Azure Function with TypeScript to process some binary data. While my first approach by reading the binary data from the filesystem succeeded, passing the binary data as body via a POST request fails.

curl -v \
 -X POST \
 --data-binary @resources/example.pdf \
 $function_url 

# > Content-Length: 2505058

I use the follwing code to read the data from the request body.

const dataFromFs = new Uint8Array(readFileSync('resources/example.pdf'));
context.log(`Read PDF file from filesystem with length ${dataFromFs.length}`);
// Read PDF file from filesystem with length 2505058

const dataFromReq = new Uint8Array(Buffer.from(req.body));
context.log(`Read PDF file from request body with length ${dataFromReq.length}`);
// Read PDF file from request body with length 4365547

Since the content length of read request body differs from the HTTP request and the filesystem solution, I guess, the problem is caused by new Uint8Array(Buffer.from(req.body)).

Any suggestions?

sschmeck
  • 7,233
  • 4
  • 40
  • 67
  • 1
    Make sure your binding is configured as binary. The language worker is unable to infer this from the request, thus the configuration parameter - https://learn.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2-v3-v4-export%2Cv2-v3-v4-done%2Cv2%2Cv2-log-custom-telemetry%2Cv2-accessing-request-and-response%2Cwindows-setting-the-node-version#bindings-data-type – evilSnobu Aug 02 '22 at 07:45
  • @evilSnobu, thanks for the hint, wasn't aware of the `"dataType": "binary"` configuration in the `function.json`. – sschmeck Aug 02 '22 at 07:48
  • While the `Content-Length` is 2505058, the length of the `res.body` is 2388973. There seems some pre-processing of the runtime? BTW: When using `Buffer.from(req.body, 'binary')`, I also get a length of 2388973. Setting `"dataType": "binary"` seems to have no effect. – sschmeck Aug 02 '22 at 10:01
  • There exists some open issue [Azure Functions (node) doesn't process binary data properly](https://github.com/Azure/azure-functions-nodejs-worker/issues/294) in _Azure/azure-functions-nodejs-worker_ repository. – sschmeck Aug 02 '22 at 10:12
  • 1
    You need to send application/octet-stream as Content-type header, then req.body will become a Buffer type. – evilSnobu Aug 02 '22 at 12:52

1 Answers1

2

The GitHub issue Azure Functions (node) doesn't process binary data properly describes the problem and suggests to set the Content-Type header to application/octet-stream.

curl -v \
 -X POST \
 -H 'Content-Type: application/octet-stream'
 --data-binary @resources/example.pdf \
 $function_url

# > Content-Length: 2505058

The Azure Function reads the request body with Buffer.from(req.body, 'binary').

const dataFromReq = new Uint8Array(Buffer.from(req.body, 'binary'));
context.log(`Read PDF file from request body with length ${dataFromReq.length}`);
// Read PDF file from request body with length 2505058
sschmeck
  • 7,233
  • 4
  • 40
  • 67