Description
I am trying to serve an image from a function app running on node. At the moment we are doing this successfully using the context.res
binding, however we are migrating our function apps to use the $return
output name/binding (as is the recommendation in the docs for functions with a single output).
However, there seems to be inconsistent behaviour with named output bindings and the $return
output binding. It appears that the isRaw
flag is being ignored or not acted on in the same way when using the $return
binding compared to a named binding.
Investigative information
Please provide the following:
- Timestamp: 10/21/2019, 2:57:25.913 PM
- Function App version (1.0 or 2.0): 2.0
- Function App name: -
- Function name(s) (as appropriate): -
- Invocation ID: f40d7cbb-c5d1-435f-ae4c-058d4f9fe647
- Region: West Europe
Repro steps
Create a function like so:
function.json:
{
"disabled": false,
"tracing": {
"consoleLevel": "verbose"
},
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"route": "image",
"methods": ["GET"],
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
index.js:
module.exports = async () => {
return {
status: 200,
headers: { 'content-type': 'image/jpeg' },
body: Buffer.from([255, 216, 255, ...]), // this is the opening byte sequence for a jpg
isRaw: true,
};
}
Expected behavior
The response should be sent to the browser without being mangled (the isRaw
flag is set to true) and the Buffer should be output as binary
$ curl [function host]/image
Date: Mon, 21 Oct 2019 15:22:45 GMT
Content-Type: image/jpeg
Content-Length: 38
���
Actual behavior
The response is a json-encoded Buffer and sent to the browser (with ; charset=utf-8
appended to the content type)
$ curl [function host]/image
Date: Mon, 21 Oct 2019 15:22:45 GMT
Content-Type: image/jpeg; charset=utf-8
Content-Length: 38
{"type":"Buffer","data":[255,216,255]}
Known workarounds
Use a named output binding:
function.json:
{
"disabled": false,
"tracing": {
"consoleLevel": "verbose"
},
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"route": "image",
"methods": ["GET"],
"name": "req"
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
index.js:
module.exports = async (context) => {
context.res = {
status: 200,
headers: { 'content-type': 'image/jpeg' },
body: Buffer.from([255, 216, 255, ...]), // this is the opening byte sequence for a jpg
isRaw: true,
};
}
Related information
This is a duplicate of Azure/azure-functions-host#3892 but hopefully provides some greater detail