Azure / azure-functions-host

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

php azure function can't set content type #1554

Open soohoon90 opened 7 years ago

soohoon90 commented 7 years ago

Please provide a succinct description of the issue.

Repro steps

Provide the steps required to reproduce the problem

  1. create a simple php-gd script that generates an image
  2. use file_put_contents(getenv('res'), "content-type:image/png".$imagedata);

Expected behavior

content-type is set and content is parsed proproply

Actual behavior

parsed as json

Known workarounds

none i could find

Related information

Provide any related information

paulbatum commented 7 years ago

@fabiocav can you provide info on using the IsRaw flag? That might help here.

soohoon90 commented 7 years ago

I am not aware of how i would set isRaw flag for php. documented way of writing to response in php was file_put_contents(getenv('res'), $what_to_write); Could you point me to documentation where i can set isRaw flag for php?

source code:

<?php

    $fontName = "ARLRDBD.ttf";
    imagesavealpha($hImage,true);
    imagealphablending($hImage,false);
    $hImage = imagecreatetruecolor(500, 500);
    $colorBlank = imagecolorallocatealpha($hImage, 0, 0, 0, 127);
    $colorText = imagecolorallocatealpha($hImage, 0, 0, 0, 0);
    imagettftext($hImage, 15, 0, 0, 50, $colorText, $fontName, $text);

    imagefill($hImage, 0, 0, $colorBlank);
    //echo "hello world";
    //$input = file_get_contents('php://input');
    //file_put_contents(getenv('res'), $input);
    //file_put_contents(getenv('res'), "test");

    //header("content-type: image/png");
    //imagepng($hImage);

    ob_start();
    imagepng($hImage);
    $image_data = ob_get_contents();
    ob_end_clean();

    file_put_contents(getenv('res'), 'Content-Type: image/png');    
    file_put_contents(getenv('res'), $image_data);
soohoon90 commented 7 years ago

instead of image, this is what i would get as result: "�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0001�\u0000\u0000\u0001�\b\u0006\u0000\u0000\u0000��ߊ\u0000\u0000\u0003�IDATx���\u0001\u0001\u0000\u0000\u0000� ��nH@\u0001\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000�bE\u0015\u0000\u0001\u0019��\u0000\u0000\u0000\u0000IEND�B�"`

alexkarcher-msft commented 7 years ago

I was able to replicate this, but used HTTP input and Blob Storage output for simplicity. I use the following function code to test:

<? php file.copy(getenv('req'), getenv('outputBlob')); ?>

function.json { "bindings": [ { "type": "httpTrigger", "direction": "in", "name": "req", "authLevel": "anonymous" }, { "type": "blob", "name": "outputBlob", "path": "outcontainer/{rand-guid}.jpg", "connection": "function8f483d4693cc_STORAGE", "direction": "out" } ], "disabled": false }

and tested with CURL curl -X POST -H "Content-Type: image/jpg" -T .\small.jpg https://FunctionName.azurewebsites.net/api/HttpGET-CRUD-PHP1

Interesting findings, my images come out about double the size, but every text file I pass through this function comes out totally untouched. No headers or extra bytes are attached.

soohoon90 commented 7 years ago

Scenario here isn't copying files.

Scenario is on demand image generation I want to return an image file to the http request.

Get Outlook for Androidhttps://aka.ms/ghei36


From: Alex Karcher notifications@github.com Sent: Thursday, June 1, 2017 10:50:19 AM To: Azure/azure-webjobs-sdk-script Cc: Hoon Cho; Author Subject: Re: [Azure/azure-webjobs-sdk-script] php azure function can't set content type (#1554)

I was able to replicate this, but used HTTP input and Blob Storage output for simplicity. I use the following function code to test:

<? php file.copy(getenv('req'), getenv('outputBlob')); ?>

function.json { "bindings": [ { "type": "httpTrigger", "direction": "in", "name": "req", "authLevel": "anonymous" }, { "type": "blob", "name": "outputBlob", "path": "outcontainer/{rand-guid}.jpg", "connection": "function8f483d4693cc_STORAGE", "direction": "out" } ], "disabled": false }

and tested with CURL curl -X POST -H "Content-Type: image/jpg" -T .\small.jpg https://FunctionName.azurewebsites.net/api/HttpGET-CRUD-PHP1

Interesting findings, my images come out about double the size, but every text file I pass through this function comes out totally untouched. No headers or extra bytes are attached.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/Azure/azure-webjobs-sdk-script/issues/1554#issuecomment-305569219, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AAjgHkVW3qe2_yH3C2uzVPT6WWuVSgfIks5r_vnbgaJpZM4NqzWT.

mamaso commented 7 years ago

This is a known issue - the isRaw flag only applies to node at present. It can only be set in script languages if you serialize to a json string, which turns any bytes into base64 strings (defeating the purpose of isRaw). I'll have a think on how to indicate a raw response from script languages.

Unfortunately there is not a workaround, unless if you can use C#, F#, or node.

fabiocav commented 7 years ago

@mamaso the same response format should be supported in those cases. I thought we had plumbed this through at some point.

ge33ek commented 7 years ago

@mamaso @fabiocav Wondering if there is any progress on this? I too would find it valuable.

Trying to output some XML but is getting wrapped in quotations, same doesn't occur if the content is JSON. Which would ordinarily be fine, except the use case calls for a XML response.

Gaweph commented 6 years ago

@alexkarcher-msft Do you have any further information on setting the php content type? It seems that if nothing is specified then it is always "application/xml", and if json_encode is specified it is "application/json". Any information appreciated.

As a workaround for retrieving an image, would your solution of using a "type: blob" allow for an image to be sent back to the browser?