question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Refit 6.0.x: Content-Length not set for PATCH requests

See original GitHub issue

Hi

It seems like the following issue is related to a slightly old issue i.e. #885 and probably #372

Description

I am consuming a third-party REST API using .NET 5/C# 9.0 and Refit version 6.0.24. The third-party system doesn’t support chunked encoding. When making a PATCH call the Transfer-Encoding: chunked header is getting added, and the API returns with 400 status code.

The interface method looks like below:

[Patch("/states/{Id}"), Headers("Content-Type: application/json")]
Task<ApiResponse<State>> ChangeState([Body] StateControl stateControl, string id);

I have tried changing the [Body] attribute to all possible documented values without any success

- [Body]
- [Body(true)]
- [Body(BodySerializationMethod.Default, true)]
- [Body(BodySerializationMethod.Serialized)]
- [Body(BodySerializationMethod.Serialized, true)]

Following is the request and response captured by Fiddler

Request

PATCH http://thidparty.api.com:5000/states/0 HTTP/1.1
Host: thidparty.api.com:5000
X-Correlation-ID: 3edcc52b-aec1-4a8c-b725-c646fc269e95
traceparent: 00-4f869cf85a015f4fae43466700c2a395-5effe2f12308e444-00
Transfer-Encoding: chunked
Content-Type: application/json

1C
{"state":"new","force":true}
0

Response

HTTP/1.1 400 BAD REQUEST
server: gunicorn/19.4.5
date: Mon, 01 Mar 2021 23:29:51 GMT
content-type: application/json
content-length: 92
x-sentry-id: 3b2b0bad862a4eed9d62e8e76c96a7f0

{"message": "The browser (or proxy) sent a request that this server could not understand."}

Expected behavior The expected behavior should be how it was in the version prior to 6.0.x. i.e. Content-Length header should be set. It works fine in version 5.2.4, without changing the [Body] attribute. Following is the request and response captured by Fiddler when using Refit version 5.2.4

Request

PATCH http://thidparty.api.com:5000/states/0 HTTP/1.1
Host: thidparty.api.com:5000
X-Correlation-ID: 3edcc52b-aec1-4a8c-b725-c646fc269e95
traceparent: 00-1b3b2ddae1c35c4f9ae2b6c6e7c72093-ce1d3605b1a6b241-00
Content-Length: 28
Content-Type: application/json

{"state":"new","force":true}

Response

Please note that 408 is the expected status code for this request 😃

HTTP/1.1 408 REQUEST TIMEOUT
server: gunicorn/19.4.5
date: Mon, 01 Mar 2021 18:01:03 GMT
content-type: application/json
content-length: 35
x-sentry-id: 1b4b324faff9412e831aeff453efbeb2

{"message": "State didn't change"}

Environment

  • OS: Windows 10 Professional
  • Version: Refit 6.0.x
  • Working Version: Refit 5.2.4

Additional context I am using a workaround mentioned at #372 in a delegating handler before the request is sent like below and it works fine. However, it would be great if this issue can be fixed. I am happy to contribute if I can get some direction. It would probably be my first contribution ever 😃

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    if (request.Method == HttpMethod.Patch && request.Content != null)
    {
        var content = await request.Content.ReadAsStringAsync(cancellationToken);
        request.Content = new StringContent(content, Encoding.UTF8, "application/json");
    }

    return await base.SendAsync(request, cancellationToken);
}

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:18 (6 by maintainers)

github_iconTop GitHub Comments

3reactions
simlawstucommented, Mar 17, 2022

This was helpful.

Just been struggling with Azure API Management cutting out the JSON content of my post body. Turns out that it was ignoring the content because the content-length header wasn’t being sent. Set buffered to true in the body attribute and it started working. [Body(BodySerializationMethod.Serialized, true)]

1reaction
softmatterscommented, Feb 1, 2022

We noticed this as well with void return methods, which may be what you are seeing too. PR #1293 will fix that code path.

@lotz Thanks for the fix. I presume that it would work with the methods that return Task<<T>> as I mentioned in this bug. I’ll give it a go and will let you know.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Content-Length header is not getting set for PATCH ...
Content-Length header is not getting set for PATCH requests with empty/nil payload - GoLang. This is reproducible even in the latest go version ......
Read more >
Using JSON Patch in Spring REST APIs
Learn how to use the HTTP PATCH method along with the JSON Patch document format to apply partial updates to RESTful resources.
Read more >
Usage | RestSharp
Essentially, RestSharp is a wrapper around HttpClient that allows you to do the following: Add default parameters of any kind (not just headers) ......
Read more >
HttpHeaders (Spring Framework 6.0.11 API)
A data structure representing HTTP request or response headers, mapping String header names to a list of String values, also offering accessors for...
Read more >
Make HTTP requests with the HttpClient - .NET
Learn how to make HTTP requests and handle responses with the HttpClient in .NET.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found