Skip to content

Commit 8cafdd1

Browse files
Stop modifying HttpClient.DefaultRequestHeaders (#2363)
* 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 <noreply@anthropic.com> * 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 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ae6b354 commit 8cafdd1

File tree

4 files changed

+34
-14
lines changed

4 files changed

+34
-14
lines changed

src/RestSharp.Extensions.DependencyInjection/ServiceCollectionExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ public void AddRestClient(
2626

2727
services
2828
.AddHttpClient(name)
29-
.ConfigureHttpClient(client => RestClient.ConfigureHttpClient(client, options))
3029
.ConfigurePrimaryHttpMessageHandler(() => {
3130
var handler = new HttpClientHandler();
3231
RestClient.ConfigureHttpMessageHandler(handler, options);

src/RestSharp/RestClient.Async.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,11 @@ async Task<HttpResponse> ExecuteRequestAsync(RestRequest request, CancellationTo
135135
.AddCookieHeaders(url, Options.CookieContainer);
136136

137137
var message = new HttpRequestMessage(httpMethod, url);
138-
message.Content = initialContent.BuildContent();
139-
message.Headers.Host = Options.BaseHost;
140-
message.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy;
141-
message.Version = request.Version;
138+
message.Content = initialContent.BuildContent();
139+
message.Headers.Host = Options.BaseHost;
140+
message.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy;
141+
message.Headers.ExpectContinue = Options.Expect100Continue;
142+
message.Version = request.Version;
142143
message.AddHeaders(headers);
143144

144145
#pragma warning disable CS0618 // Type or member is obsolete
@@ -272,9 +273,10 @@ HttpRequestMessage CreateRedirectMessage(
272273
bool verbChangedToGet
273274
) {
274275
var redirectMessage = new HttpRequestMessage(httpMethod, url);
275-
redirectMessage.Version = request.Version;
276-
redirectMessage.Headers.Host = Options.BaseHost;
277-
redirectMessage.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy;
276+
redirectMessage.Version = request.Version;
277+
redirectMessage.Headers.Host = Options.BaseHost;
278+
redirectMessage.Headers.CacheControl = request.CachePolicy ?? Options.CachePolicy;
279+
redirectMessage.Headers.ExpectContinue = Options.Expect100Continue;
278280

279281
if (!verbChangedToGet && redirectOptions.ForwardBody) {
280282
var redirectContent = new RequestContent(this, request);

src/RestSharp/RestClient.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ HttpClient GetClient() {
9393
ConfigureHttpMessageHandler(handler, options);
9494
var finalHandler = options.ConfigureMessageHandler?.Invoke(handler) ?? handler;
9595
var httpClient = new HttpClient(finalHandler);
96-
ConfigureHttpClient(httpClient, options);
9796

9897
// We will use Options.Timeout in ExecuteAsInternalAsync method
9998
httpClient.Timeout = Timeout.InfiniteTimeSpan;
@@ -188,7 +187,6 @@ public RestClient(
188187
DefaultParameters = new(Options);
189188

190189
if (options != null) {
191-
ConfigureHttpClient(httpClient, options);
192190
ConfigureDefaultParameters(options);
193191
}
194192
}
@@ -224,10 +222,6 @@ public RestClient(
224222
)
225223
: this(new HttpClient(handler, disposeHandler), true, configureRestClient, configureSerialization) { }
226224

227-
internal static void ConfigureHttpClient(HttpClient httpClient, RestClientOptions options) {
228-
if (options.Expect100Continue != null) httpClient.DefaultRequestHeaders.ExpectContinue = options.Expect100Continue;
229-
}
230-
231225
// ReSharper disable once CognitiveComplexity
232226
internal static void ConfigureHttpMessageHandler(HttpClientHandler handler, RestClientOptions options) {
233227
#if NET

test/RestSharp.Tests/RestClientTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,29 @@ public void ConfigureDefaultParameters_sets_user_agent_given_httpClient_instance
123123

124124
Assert.Empty(httpClient.DefaultRequestHeaders.UserAgent);
125125
}
126+
127+
[Fact]
128+
public void Should_not_set_expect_continue_on_shared_http_client_default_headers() {
129+
// arrange
130+
var httpClient = new HttpClient();
131+
var options = new RestClientOptions { Expect100Continue = true };
132+
133+
// act
134+
using var restClient = new RestClient(httpClient, options);
135+
136+
// assert — the shared HttpClient's DefaultRequestHeaders must not be modified
137+
httpClient.DefaultRequestHeaders.ExpectContinue.Should().BeNull();
138+
}
139+
140+
[Fact]
141+
public void Should_not_set_expect_continue_on_new_http_client_default_headers() {
142+
// arrange
143+
var options = new RestClientOptions { Expect100Continue = false };
144+
145+
// act
146+
using var restClient = new RestClient(options);
147+
148+
// assert
149+
restClient.HttpClient.DefaultRequestHeaders.ExpectContinue.Should().BeNull();
150+
}
126151
}

0 commit comments

Comments
 (0)