Skip to content

Conversation

@iamyojimbo
Copy link
Contributor

The httpc client was unconditionally setting the TE header to an empty string on all HTTP/1.1 requests when no TE header was explicitly provided. This behavior violated RFC 2616 and caused compatibility issues with some proxy servers that would drop requests containing empty TE headers.

RFC 2616 does not require a TE header to be present, and when absent, no transfer encoding expectations should be assumed. This change removes the automatic addition of empty TE headers, allowing httpc to send cleaner HTTP requests that better comply with the standard.

Fixes GH-10065

@CLAassistant
Copy link

CLAassistant commented Aug 19, 2025

CLA assistant check
All committers have signed the CLA.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 19, 2025

CT Test Results

  2 files   22 suites   10m 4s ⏱️
360 tests 353 ✅  7 💤 0 ❌
647 runs  587 ✅ 60 💤 0 ❌

Results for commit 2fab8cc.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@iamyojimbo iamyojimbo force-pushed the httpc/te-header branch 3 times, most recently from ab6adfa to f314280 Compare August 19, 2025 15:57
@IngelaAndin IngelaAndin added the team:PS Assigned to OTP team PS label Aug 20, 2025
@Whaileee Whaileee added the testing currently being tested, tag is used by OTP internal CI label Aug 20, 2025
@Whaileee Whaileee requested a review from Copilot August 21, 2025 08:02
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR removes the automatic addition of empty TE (Transfer-Encoding) headers from HTTP/1.1 requests to improve RFC 2616 compliance and resolve compatibility issues with proxy servers that drop requests containing empty TE headers.

Key changes:

  • Removes automatic empty TE header injection for HTTP/1.1 requests
  • Adds proper TE header handling that modifies the Connection header when TE is explicitly provided
  • Implements comprehensive test coverage for various TE header scenarios

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
lib/inets/test/httpc_SUITE.erl Adds extensive test cases for TE header behavior and Connection header modifications
lib/inets/src/http_lib/http_util.erl Adds utility function to parse Connection header tokens
lib/inets/src/http_client/httpc_request.erl Updates connection closing logic to properly parse Connection header tokens
lib/inets/src/http_client/httpc_handler.erl Removes automatic empty TE header from TLS tunnel requests
lib/inets/src/http_client/httpc.erl Replaces automatic TE header injection with proper TE/Connection header coordination

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@Whaileee
Copy link
Contributor

Thanks for the contribution. Change looks good to me. Please replace the strip with trim, and I think it's good to go

@Whaileee
Copy link
Contributor

Hi, there seems to be an error in all of the added testcases, when run in group sim_http_ipv6. All tests fail with connection header "close".
Did you run ipv6 tests? Are you able to reproduce that?
Best regards,
Konrad

@iamyojimbo
Copy link
Contributor Author

Hi, there seems to be an error in all of the added testcases, when run in group sim_http_ipv6. All tests fail with connection header "close". Did you run ipv6 tests? Are you able to reproduce that? Best regards, Konrad

I have not: I need to figure out how to get those running. They were skipping for me locally. I'd assumed those would be unrelated to my change, but if they were breaking, would be caught in CI.

Just so I understand: CI has passed all tests. Are the ipv6 tests not run there?

@Whaileee
Copy link
Contributor

Ipv6 tests are also skipped in GH actions. Other machines; not visible here have these tests running and all of them, are failing there.

@iamyojimbo
Copy link
Contributor Author

Got it - I will resolve. Thanks for the review!

@Whaileee Whaileee added testing currently being tested, tag is used by OTP internal CI and removed testing currently being tested, tag is used by OTP internal CI labels Aug 26, 2025
@Whaileee
Copy link
Contributor

Thanks for the fix. Could you rebase your changes since there is a merge conflict in httpc_SUITE?
Best regards,
Konrad

@iamyojimbo
Copy link
Contributor Author

@Whaileee - please take another look - tests passing on my side. I changed ipv6 to not send per-request connection options (socket_opts), because that cases httpc to override all request connection headers with connection: close. Looks like there's some emotional baggage around that in the code:

%% Simple socket options handling (ERL-441).
%%
%% TODO: Refactor httpc to enable sending socket options in requests
%% using persistent connections. This workaround opens a new
%% connection for each request with non-empty socket_opts.
handle_request(Request0 = #request{socket_opts = SocketOpts},
State0 = #state{options = Options0})
when is_list(SocketOpts) andalso length(SocketOpts) > 0 ->
Request = handle_cookies(generate_request_id(Request0), State0),
Options = convert_options(SocketOpts, Options0),
State = State0#state{options = Options},
Headers =
(Request#request.headers)#http_request_h{connection
= "close"},
%% Reset socket_opts to avoid setopts failure.
start_handler(Request#request{headers = Headers, socket_opts = []}, State),
%% Do not change the state
{reply, {ok, Request#request.id}, State0};

Rather than change httpc_manager: handle_request to preserve tokens of the existing connection header, I just split out sim_http_ipv6 group to use httpc_options instead of socket_opts and left http_ipv6 as-is.

Let me know if these test pass now.

@Whaileee
Copy link
Contributor

Whoops my bad, there wasn't a conflict (yet). Sorry!

@Whaileee Whaileee removed the testing currently being tested, tag is used by OTP internal CI label Aug 28, 2025
@Whaileee
Copy link
Contributor

Thanks! The internal tests are ran overnight so we need to wait a day for them. Change looks good to me. If the tests pass, then we are merging!

@Whaileee Whaileee added the testing currently being tested, tag is used by OTP internal CI label Aug 29, 2025
@iamyojimbo
Copy link
Contributor Author

@Whaileee How'd the tests go?

@Whaileee
Copy link
Contributor

Well, they definitely would have ran better with the testing label on 😅. I forgot to reapply that yesterday

@iamyojimbo
Copy link
Contributor Author

@Whaileee Any luck?

@Whaileee
Copy link
Contributor

Whaileee commented Sep 1, 2025

For some reason the branch was still commented out of testing. I've now added it manually, so if it's not in testing now I'll start breaking stuff (just kidding). Therefore I ask for another day of patience.

@iamyojimbo
Copy link
Contributor Author

No problem! 🙏

@iamyojimbo
Copy link
Contributor Author

Is today the day? 🙏 I have a good feeling 😄

@Whaileee
Copy link
Contributor

Whaileee commented Sep 2, 2025

We will see. The tests on the machines with ipv6 are still running. Should be done in a few hours

@Whaileee
Copy link
Contributor

Whaileee commented Sep 2, 2025

2 out of 3 passed, I suspect in an hour we will see the rest also finish

@Whaileee
Copy link
Contributor

Whaileee commented Sep 2, 2025

3 out of 3. It's ready to be sent to the wild!
You can leave the rest for me.
Thanks for the contribution.
Best regards,
Konrad

Whaileee
Whaileee previously approved these changes Sep 2, 2025
@Whaileee
Copy link
Contributor

Whaileee commented Sep 2, 2025

I rebased it to patch-base-26 so it can be easliy backported, and removed dangling whitespaces.

Whaileee
Whaileee previously approved these changes Sep 2, 2025
@Whaileee Whaileee force-pushed the httpc/te-header branch 3 times, most recently from ad43f78 to 4ee1e2d Compare September 2, 2025 15:50
The httpc client was unconditionally setting the TE header to an empty
string on all HTTP/1.1 requests when no TE header was explicitly
provided. This behavior violated RFC 2616 and caused compatibility
issues with some proxy servers that would drop requests containing empty
TE headers.

RFC 2616 does not require a TE header to be present, and when absent, no
transfer encoding expectations should be assumed. This change removes
the automatic addition of empty TE headers, allowing httpc to send
cleaner HTTP requests that better comply with the standard.

Fixes erlangGH-10065
@Whaileee Whaileee merged commit b0e61aa into erlang:maint Sep 2, 2025
23 checks passed
@iamyojimbo
Copy link
Contributor Author

Great! Thank you! So in the next minor patch of OTP 26, 27 or 28, this will be pulled in?

@Whaileee
Copy link
Contributor

Whaileee commented Sep 3, 2025

That is true for 26 and 27, but for 28 it will be in 28.1

@iamyojimbo
Copy link
Contributor Author

🙏

@iamyojimbo
Copy link
Contributor Author

iamyojimbo commented Sep 3, 2025

Just to clarify: by minor patch, do we mean ~quarterly minor patches?

@Whaileee
Copy link
Contributor

Whaileee commented Sep 3, 2025

This branch will be released with OTP 27.3.4.3 and OTP 26.2.5.15 which are planned to be released soon, as well as OTP 28.1 which will be also released soon-ish.
There are no minor patches for 26 and 27, only emergency ones which contain bugfixes for currently supported versions (last number in version)

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

Labels

team:PS Assigned to OTP team PS testing currently being tested, tag is used by OTP internal CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants