Azure / azure-functions-host

The host/runtime that powers Azure Functions
https://functions.azure.com
MIT License
1.93k stars 441 forks source link

How to Provide Blob Output Binding Binary Data in Custom Handlers? #6091

Open lafernando opened 4 years ago

lafernando commented 4 years ago

Is your question related to a specific version? If so, please specify:

v2.0.

What language does your question apply to? (e.g. C#, JavaScript, Java, All)

Custom Handler (Ballerina)

Question

While implementing a custom handler for the Ballerina language, based on the documentation here, it doesn't mention how to provide a binary value to the JSON response we return in custom handlers. In a blob input handler, it does return a base64 encoded text where we can decode to get the binary data. But in the output case, it simply considers all the content given in the output JSON as simple text (not like base64 encoded data). Is there any special attribute or something we need to set in the output in order to provide a binary (base64 maybe) value?

lafernando commented 3 years ago

@anthonychu @pragnagopa any update on this issue?

pragnagopa commented 3 years ago

Conversion of output binding data here handled here: https://github.com/Azure/azure-functions-host/blob/dev/src/WebJobs.Script/Workers/Http/HttpScriptInvocationResultExtensions.cs#L60-L78

Setting "dataType": "binary" in function.json for your output binding should work. Please give it a try and let us know.

lafernando commented 3 years ago

Hi @pragnagopa,

It seems, there is a bug in the code you mentioned. In its logic, if the type is given as "binary", it directly returns the text content without doing a base64 decode on it. But in the else branch there (e.g. type="string"), it tries to do a base64 decode, if it's successful, that binary content is returned, or else, it simply ignores the decoding error and returns the string content.

The above behavior is confirmed from my custom handler implementation as well. Earlier, I actually had "dataType": "binary" always in my function.json, and with that, it always considered my content as simply a string value, and this is stored in the blob value. And then, if when I manually changed this to "dataType":"string", and then if the payload has a base64 encoded payload, it will store this binary content in the blob, or else, If it's not a valid base64 encoded payload, it directly stores that string content.

Hope my above analysis is correct.

Cheers, Anjana.

lafernando commented 3 years ago

Also, it will be great if we can properly document these properties at https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-output.

pragnagopa commented 3 years ago

In its logic, if the type is given as "binary", it directly returns the text content without doing a base64 decode on it.

Setting dataType: binary indicates payload is of type byte[]

else branch there (e.g. type="string"), it tries to do a base64 decode,

Default dataType is string - we expect users to send binary data as base64 encoded string

Yes, we will look into updating docs with more code samples

lafernando commented 3 years ago

In our custom handler JSON payload, the only way to send data is using a string value (either base64 encoded or not). In that case, what's the use of dataType:binary?

And yes, it's better to clear this up in the documentation.