From dd38cc2263d0319b235e0bf0e179e7ebb21f8e1f Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Sun, 1 Mar 2026 17:05:56 +0100 Subject: [PATCH 1/2] Stop modifying HttpClient.DefaultRequestHeaders (#2156) Move Expect100Continue from HttpClient.DefaultRequestHeaders to per-request HttpRequestMessage.Headers so that shared HttpClient instances are not mutated by RestClient configuration. Co-Authored-By: Claude Opus 4.6 --- .../ServiceCollectionExtensions.cs | 1 - src/RestSharp/RestClient.Async.cs | 9 ++++--- src/RestSharp/RestClient.cs | 6 ----- test/RestSharp.Tests/RestClientTests.cs | 25 +++++++++++++++++++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/RestSharp.Extensions.DependencyInjection/ServiceCollectionExtensions.cs b/src/RestSharp.Extensions.DependencyInjection/ServiceCollectionExtensions.cs index d1f13c36d..4b74607ba 100644 --- a/src/RestSharp.Extensions.DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/RestSharp.Extensions.DependencyInjection/ServiceCollectionExtensions.cs @@ -26,7 +26,6 @@ public void AddRestClient( services .AddHttpClient(name) - .ConfigureHttpClient(client => RestClient.ConfigureHttpClient(client, options)) .ConfigurePrimaryHttpMessageHandler(() => { var handler = new HttpClientHandler(); RestClient.ConfigureHttpMessageHandler(handler, options); diff --git a/src/RestSharp/RestClient.Async.cs b/src/RestSharp/RestClient.Async.cs index 73ed0410b..280a0b0e1 100644 --- a/src/RestSharp/RestClient.Async.cs +++ b/src/RestSharp/RestClient.Async.cs @@ -135,10 +135,11 @@ async Task ExecuteRequestAsync(RestRequest request, CancellationTo .AddCookieHeaders(url, Options.CookieContainer); var message = new HttpRequestMessage(httpMethod, url); - message.Content = initialContent.BuildContent(); - message.Headers.Host = Options.BaseHost; - message.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy; - message.Version = request.Version; + message.Content = initialContent.BuildContent(); + message.Headers.Host = Options.BaseHost; + message.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy; + message.Headers.ExpectContinue = Options.Expect100Continue; + message.Version = request.Version; message.AddHeaders(headers); #pragma warning disable CS0618 // Type or member is obsolete diff --git a/src/RestSharp/RestClient.cs b/src/RestSharp/RestClient.cs index d67a6fb7f..9ab456975 100644 --- a/src/RestSharp/RestClient.cs +++ b/src/RestSharp/RestClient.cs @@ -93,7 +93,6 @@ HttpClient GetClient() { ConfigureHttpMessageHandler(handler, options); var finalHandler = options.ConfigureMessageHandler?.Invoke(handler) ?? handler; var httpClient = new HttpClient(finalHandler); - ConfigureHttpClient(httpClient, options); // We will use Options.Timeout in ExecuteAsInternalAsync method httpClient.Timeout = Timeout.InfiniteTimeSpan; @@ -188,7 +187,6 @@ public RestClient( DefaultParameters = new(Options); if (options != null) { - ConfigureHttpClient(httpClient, options); ConfigureDefaultParameters(options); } } @@ -224,10 +222,6 @@ public RestClient( ) : this(new HttpClient(handler, disposeHandler), true, configureRestClient, configureSerialization) { } - internal static void ConfigureHttpClient(HttpClient httpClient, RestClientOptions options) { - if (options.Expect100Continue != null) httpClient.DefaultRequestHeaders.ExpectContinue = options.Expect100Continue; - } - // ReSharper disable once CognitiveComplexity internal static void ConfigureHttpMessageHandler(HttpClientHandler handler, RestClientOptions options) { #if NET diff --git a/test/RestSharp.Tests/RestClientTests.cs b/test/RestSharp.Tests/RestClientTests.cs index 0bb54b328..2c82278f1 100644 --- a/test/RestSharp.Tests/RestClientTests.cs +++ b/test/RestSharp.Tests/RestClientTests.cs @@ -123,4 +123,29 @@ public void ConfigureDefaultParameters_sets_user_agent_given_httpClient_instance Assert.Empty(httpClient.DefaultRequestHeaders.UserAgent); } + + [Fact] + public void Should_not_set_expect_continue_on_shared_http_client_default_headers() { + // arrange + var httpClient = new HttpClient(); + var options = new RestClientOptions { Expect100Continue = true }; + + // act + using var restClient = new RestClient(httpClient, options); + + // assert — the shared HttpClient's DefaultRequestHeaders must not be modified + httpClient.DefaultRequestHeaders.ExpectContinue.Should().BeNull(); + } + + [Fact] + public void Should_not_set_expect_continue_on_new_http_client_default_headers() { + // arrange + var options = new RestClientOptions { Expect100Continue = false }; + + // act + using var restClient = new RestClient(options); + + // assert + restClient.HttpClient.DefaultRequestHeaders.ExpectContinue.Should().BeNull(); + } } \ No newline at end of file From d310886aed9edc09db79e7b4dfebd6dbbcc3d3db Mon Sep 17 00:00:00 2001 From: Alexey Zimarev Date: Sun, 1 Mar 2026 17:17:38 +0100 Subject: [PATCH 2/2] Set ExpectContinue on redirect messages too Apply Options.Expect100Continue to HttpRequestMessages created during redirect handling, matching the behavior of the initial request. Co-Authored-By: Claude Opus 4.6 --- src/RestSharp/RestClient.Async.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/RestSharp/RestClient.Async.cs b/src/RestSharp/RestClient.Async.cs index 280a0b0e1..269a680de 100644 --- a/src/RestSharp/RestClient.Async.cs +++ b/src/RestSharp/RestClient.Async.cs @@ -273,9 +273,10 @@ HttpRequestMessage CreateRedirectMessage( bool verbChangedToGet ) { var redirectMessage = new HttpRequestMessage(httpMethod, url); - redirectMessage.Version = request.Version; - redirectMessage.Headers.Host = Options.BaseHost; - redirectMessage.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy; + redirectMessage.Version = request.Version; + redirectMessage.Headers.Host = Options.BaseHost; + redirectMessage.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy; + redirectMessage.Headers.ExpectContinue = Options.Expect100Continue; if (!verbChangedToGet && redirectOptions.ForwardBody) { var redirectContent = new RequestContent(this, request);