node.jsazure-functionsazure-functions-runtime

Read binary data from request body of an HTTP trigger


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?


Solution

  • 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