Skip to content

Commit f3642c1

Browse files
Set UserAgent as a default header parameter (#2157)
* Set UserAgent as a default header parameter instead of modifying the HttpClient instance. * Update usage document --------- Co-authored-by: Peter Breen <[email protected]>
1 parent d99d494 commit f3642c1

File tree

3 files changed

+46
-18
lines changed

3 files changed

+46
-18
lines changed

docs/usage.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ One way of doing it is to use `RestClient` constructors that accept an instance
594594

595595
- `BaseAddress` will be used to set the base address of the `HttpClient` instance if base address is not set there already.
596596
- `MaxTimeout`
597-
- `UserAgent` will be set if the `User-Agent` header is not set on the `HttpClient` instance already.
597+
- `UserAgent` will be added to the `RestClient.DefaultParameters` list as a HTTP header. This will be added to each request made by the `RestClient`, and the `HttpClient` instance will not be modified. This is to allow the `HttpClient` instance to be reused for scenarios where different `User-Agent` headers are required.
598598
- `Expect100Continue`
599599

600600
Another option is to use a simple HTTP client factory as described [above](#simple-factory).

src/RestSharp/RestClient.cs

+15-8
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public RestClient(
7373

7474
ConfigureSerializers(configureSerialization);
7575
Options = new ReadOnlyRestClientOptions(options);
76+
DefaultParameters = new DefaultParameters(Options);
7677

7778
if (useClientFactory) {
7879
_disposeHttpClient = false;
@@ -83,15 +84,14 @@ public RestClient(
8384
HttpClient = GetClient();
8485
}
8586

86-
DefaultParameters = new DefaultParameters(Options);
87-
8887
HttpClient GetClient() {
8988
var handler = new HttpClientHandler();
9089
ConfigureHttpMessageHandler(handler, Options);
9190
var finalHandler = options.ConfigureMessageHandler?.Invoke(handler) ?? handler;
9291

9392
var httpClient = new HttpClient(finalHandler);
9493
ConfigureHttpClient(httpClient, options);
94+
ConfigureDefaultParameters(options);
9595
configureDefaultHeaders?.Invoke(httpClient.DefaultRequestHeaders);
9696
return httpClient;
9797
}
@@ -181,7 +181,10 @@ public RestClient(
181181
Options = new ReadOnlyRestClientOptions(opt);
182182
DefaultParameters = new DefaultParameters(Options);
183183

184-
if (options != null) ConfigureHttpClient(httpClient, options);
184+
if (options != null) {
185+
ConfigureHttpClient(httpClient, options);
186+
ConfigureDefaultParameters(options);
187+
}
185188
}
186189

187190
/// <summary>
@@ -218,11 +221,6 @@ public RestClient(
218221
static void ConfigureHttpClient(HttpClient httpClient, RestClientOptions options) {
219222
if (options.MaxTimeout > 0) httpClient.Timeout = TimeSpan.FromMilliseconds(options.MaxTimeout);
220223

221-
if (options.UserAgent != null &&
222-
httpClient.DefaultRequestHeaders.UserAgent.All(x => $"{x.Product?.Name}/{x.Product?.Version}" != options.UserAgent)) {
223-
httpClient.DefaultRequestHeaders.TryAddWithoutValidation(KnownHeaders.UserAgent, options.UserAgent);
224-
}
225-
226224
if (options.Expect100Continue != null) httpClient.DefaultRequestHeaders.ExpectContinue = options.Expect100Continue;
227225
}
228226

@@ -270,6 +268,15 @@ void ConfigureSerializers(ConfigureSerialization? configureSerialization) {
270268
AcceptedContentTypes = Serializers.GetAcceptedContentTypes();
271269
}
272270

271+
void ConfigureDefaultParameters(RestClientOptions options) {
272+
if (options.UserAgent != null) {
273+
if (!options.AllowMultipleDefaultParametersWithSameName
274+
&& DefaultParameters.Any(parameter => parameter.Type == ParameterType.HttpHeader && parameter.Name == KnownHeaders.UserAgent))
275+
DefaultParameters.RemoveParameter(KnownHeaders.UserAgent, ParameterType.HttpHeader);
276+
DefaultParameters.AddParameter(Parameter.CreateParameter(KnownHeaders.UserAgent, options.UserAgent, ParameterType.HttpHeader));
277+
}
278+
}
279+
273280
readonly bool _disposeHttpClient;
274281

275282
bool _disposed;

test/RestSharp.Tests/RestClientTests.cs

+30-9
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,41 @@ public void Should_use_new_httpClient_instance() {
118118
}
119119

120120
[Fact]
121-
public void ConfigureHttpClient_does_not_duplicate_user_agent_for_same_client() {
121+
public void ConfigureDefaultParameters_sets_user_agent_new_httpClient_instance() {
122+
// arrange
123+
var clientOptions = new RestClientOptions();
124+
125+
// act
126+
var restClient = new RestClient(clientOptions);
127+
128+
//assert
129+
Assert.Single(
130+
restClient.DefaultParameters,
131+
parameter => parameter.Type == ParameterType.HttpHeader &&
132+
parameter.Name == KnownHeaders.UserAgent &&
133+
parameter.Value is string valueAsString &&
134+
valueAsString == clientOptions.UserAgent);
135+
136+
Assert.Empty(restClient.HttpClient.DefaultRequestHeaders.UserAgent);
137+
}
138+
139+
[Fact]
140+
public void ConfigureDefaultParameters_sets_user_agent_given_httpClient_instance() {
122141
// arrange
123142
var httpClient = new HttpClient();
124143
var clientOptions = new RestClientOptions();
125144

126145
// act
127-
var unused = new RestClient(httpClient, clientOptions);
128-
var dummy = new RestClient(httpClient, clientOptions);
146+
var restClient = new RestClient(httpClient, clientOptions);
129147

130-
// assert
131-
Assert.Contains(
132-
httpClient.DefaultRequestHeaders.UserAgent,
133-
agent => $"{agent.Product.Name}/{agent.Product.Version}" == clientOptions.UserAgent
134-
);
135-
Assert.Single(httpClient.DefaultRequestHeaders.UserAgent);
148+
//assert
149+
Assert.Single(
150+
restClient.DefaultParameters,
151+
parameter => parameter.Type == ParameterType.HttpHeader &&
152+
parameter.Name == KnownHeaders.UserAgent &&
153+
parameter.Value is string valueAsString &&
154+
valueAsString == clientOptions.UserAgent);
155+
156+
Assert.Empty(httpClient.DefaultRequestHeaders.UserAgent);
136157
}
137158
}

0 commit comments

Comments
 (0)