Skip to content

Transfer-Encoding Chunked does not work in Javascript functions #171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
LwsSt opened this issue Nov 24, 2020 · 7 comments
Closed

Transfer-Encoding Chunked does not work in Javascript functions #171

LwsSt opened this issue Nov 24, 2020 · 7 comments

Comments

@LwsSt
Copy link

LwsSt commented Nov 24, 2020

An HTTP request sent using Transfer-Encoding: Chunked to an Azure Function written in Javascript causes the body to be undefined.

I discovered this issue when a C# client was communicating with a javascript azure function.
I refactored the client to change from StringContent to ObjectContent, and therefore it would stream the request directly to the HTTP request stream, instead of creating an intermediate string.
When sending the request this way, the Content Length isn't known, and so chunked transfer encoding is used.

When experimenting, the issue occurs whenever the Content-Length is not known before the request is sent.

Minimum reproduction:
A javascript azure function:

// index.js
module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    // req.rawBody produces the same result.
    let body = req.body;

    context.log(body);

    let responseString = body.toString();

    context.res = {
        body: responseString
    };
}

// function.json
{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

A console client in C#

// Program.cs
var content = new StringContent(Guid.NewGuid().ToString());
		
// Clear the ContentLength to trigger chunked transfer encoding
content.Headers.ContentLength = null;
		
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:5000/api/HttpTrigger")
{
    Content = content
};

var httpClient = new HttpClient();
var response = await httpClient.SendAsync(request);
Console.WriteLine(response.StatusCode);

In this example, req.body (or req.rawBody) will be set as undefined in the javascript function.
Removing the line content.Headers.ContentLength will set req.body to the expected value.

This issue does not occur if the function is re-written in C#:

public static class ChunkedEncodingFunction
{
    [FunctionName("HttpTrigger")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        // requestBody has the expected request content.
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        log.LogInformation(requestBody);

        return new OkObjectResult(requestBody);
    }
}

Our current workaround is to call HttpContent.LoadIntoBufferAsync();.
The azure function we're calling is a mock for a real service, and the real service supports chunked encoding. So we're having to put in a check to see if the client is communicating with the mock. Obviously, we would rather not require this check.

@Cellus250
Copy link

Running into the same issue now. Have you found a way to parse the payload on the Azure Functions without updating the client code?

@LwsSt
Copy link
Author

LwsSt commented Aug 14, 2021

I couldn't find a way when I last looked at this, and our workaround is sufficient for our needs.
So unfortunately I can't help you. The only way I can find is to update the client code.

@v-anvari v-anvari self-assigned this Aug 31, 2021
@v-anvari
Copy link

Hi @LwsSt , Let us know if you looking for a solution here, we shall transfer the issue to the appropriate team

@LwsSt
Copy link
Author

LwsSt commented Sep 22, 2021

Yes, I believe this is a bug. I'd rather not have to include the workaround in my client code, and it looks like @Cellus250 is also running into the same issue.

Expected behaviour: req.body (or req.rawBody) should be populated correctly when a request is sent using Transfer-Encoding: Chunked i.e. when the Content-Length is not known.

@v-anvari v-anvari transferred this issue from Azure/Azure-Functions Oct 4, 2021
@v-anvari v-anvari removed their assignment Oct 4, 2021
@ejizba ejizba transferred this issue from Azure/azure-functions-java-library Jan 28, 2022
@ejizba
Copy link
Contributor

ejizba commented Jan 28, 2022

Moved this to the node.js repo - I think it was in Java on accident. Unfortunately this work is currently blocked by work in the host first. Related issues here:
Azure/azure-functions-host#4926
Azure/azure-functions-host#7930

@ejizba ejizba added this to the Tracking milestone Jan 28, 2022
@ejizba ejizba transferred this issue from Azure/azure-functions-nodejs-worker Oct 11, 2023
@ejizba ejizba modified the milestones: Tracking, Backlog Candidates Oct 11, 2023
@ejizba
Copy link
Contributor

ejizba commented Oct 11, 2023

Moved to the library repo which is where we're tracking most of our work now. I'm hoping this will be fixed with #97, which we hope to make progress on soon

@ejizba
Copy link
Contributor

ejizba commented Feb 16, 2024

Closing in favor of #97. I confirmed the stream work enables all transfer-encoding chunked requests. Please see that issue for updates on testing/timeline

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants