Skip to content

Commit fd470c0

Browse files
authored
Implement "AddOrUpdateHeader(s)" methods (#1576)
Issue #1569
1 parent 56c3098 commit fd470c0

File tree

3 files changed

+179
-17
lines changed

3 files changed

+179
-17
lines changed

src/RestSharp/IRestRequest.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,16 +374,32 @@ public interface IRestRequest
374374
/// </summary>
375375
/// <param name="name">Name of the header to add</param>
376376
/// <param name="value">Value of the header to add</param>
377-
/// <returns></returns>
377+
/// <returns>This request</returns>
378378
IRestRequest AddHeader(string name, string value);
379379

380+
/// <summary>
381+
/// Shortcut to AddOrUpdateParameter(name, value, HttpHeader) overload
382+
/// </summary>
383+
/// <param name="name">Name of the header to add or update</param>
384+
/// <param name="value">Value of the header to add or update</param>
385+
/// <returns>This request</returns>
386+
IRestRequest AddOrUpdateHeader(string name, string value);
387+
380388
/// <summary>
381389
/// Uses AddHeader(name, value) in a convenient way to pass
382390
/// in multiple headers at once.
383391
/// </summary>
384392
/// <param name="headers">Key/Value pairs containing the name: value of the headers</param>
385393
/// <returns>This request</returns>
386394
IRestRequest AddHeaders(ICollection<KeyValuePair<string, string>> headers);
395+
396+
/// <summary>
397+
/// Uses AddOrUpdateHeader(name, value) in a convenient way to pass
398+
/// in multiple headers at once.
399+
/// </summary>
400+
/// <param name="headers">Key/Value pairs containing the name: value of the headers</param>
401+
/// <returns>This request</returns>
402+
IRestRequest AddOrUpdateHeaders(ICollection<KeyValuePair<string, string>> headers);
387403

388404
/// <summary>
389405
/// Shortcut to AddParameter(name, value, Cookie) overload

src/RestSharp/RestRequest.cs

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -384,25 +384,21 @@ public IRestRequest AddOrUpdateParameter(string name, object value, string conte
384384
/// <inheritdoc />
385385
public IRestRequest AddHeader(string name, string value)
386386
{
387-
static bool InvalidHost(string host) => Uri.CheckHostName(PortSplitRegex.Split(host)[0]) == UriHostNameType.Unknown;
388-
389-
if (name == "Host" && InvalidHost(value))
390-
throw new ArgumentException("The specified value is not a valid Host header string.", nameof(value));
391-
387+
CheckAndThrowsForInvalidHost(name, value);
392388
return AddParameter(name, value, ParameterType.HttpHeader);
393389
}
394390

395391
/// <inheritdoc />
396-
public IRestRequest AddHeaders(ICollection<KeyValuePair<string, string>> headers)
392+
public IRestRequest AddOrUpdateHeader(string name, string value)
397393
{
398-
var duplicateKeys = headers
399-
.GroupBy(pair => pair.Key.ToUpperInvariant())
400-
.Where(group => group.Count() > 1)
401-
.Select(group => group.Key)
402-
.ToList();
394+
CheckAndThrowsForInvalidHost(name, value);
395+
return AddOrUpdateParameter(name, value, ParameterType.HttpHeader);
396+
}
403397

404-
if (duplicateKeys.Any())
405-
throw new ArgumentException($"Duplicate header names exist: {string.Join(", ", duplicateKeys)}");
398+
/// <inheritdoc />
399+
public IRestRequest AddHeaders(ICollection<KeyValuePair<string, string>> headers)
400+
{
401+
CheckAndThrowsDuplicateKeys(headers);
406402

407403
foreach (var pair in headers)
408404
{
@@ -412,6 +408,19 @@ public IRestRequest AddHeaders(ICollection<KeyValuePair<string, string>> headers
412408
return this;
413409
}
414410

411+
/// <inheritdoc />
412+
public IRestRequest AddOrUpdateHeaders(ICollection<KeyValuePair<string, string>> headers)
413+
{
414+
CheckAndThrowsDuplicateKeys(headers);
415+
416+
foreach (var pair in headers)
417+
{
418+
AddOrUpdateHeader(pair.Key, pair.Value);
419+
}
420+
421+
return this;
422+
}
423+
415424
/// <inheritdoc />
416425
public IRestRequest AddCookie(string name, string value) => AddParameter(name, value, ParameterType.Cookie);
417426

@@ -486,5 +495,25 @@ public IRestRequest AddDecompressionMethod(DecompressionMethods decompressionMet
486495
public IRestRequest AddUrlSegment(string name, object value) => AddParameter(name, value, ParameterType.UrlSegment);
487496

488497
IRestRequest AddFile(FileParameter file) => this.With(x => x.Files.Add(file));
498+
499+
private static void CheckAndThrowsForInvalidHost(string name, string value)
500+
{
501+
static bool InvalidHost(string host) => Uri.CheckHostName(PortSplitRegex.Split(host)[0]) == UriHostNameType.Unknown;
502+
503+
if (name == "Host" && InvalidHost(value))
504+
throw new ArgumentException("The specified value is not a valid Host header string.", nameof(value));
505+
}
506+
507+
private static void CheckAndThrowsDuplicateKeys(ICollection<KeyValuePair<string, string>> headers)
508+
{
509+
var duplicateKeys = headers
510+
.GroupBy(pair => pair.Key.ToUpperInvariant())
511+
.Where(group => group.Count() > 1)
512+
.Select(group => group.Key)
513+
.ToList();
514+
515+
if (duplicateKeys.Any())
516+
throw new ArgumentException($"Duplicate header names exist: {string.Join(", ", duplicateKeys)}");
517+
}
489518
}
490519
}

test/RestSharp.Tests/RequestHeaderTests.cs

Lines changed: 120 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public void AddHeaders_SameCaseDuplicatesExist_ThrowsException()
2929
[Test]
3030
public void AddHeaders_DifferentCaseDuplicatesExist_ThrowsException()
3131
{
32-
var headers = new List<KeyValuePair<string, string>>()
32+
var headers = new List<KeyValuePair<string, string>>
3333
{
3434
new KeyValuePair<string, string>("Accept", "application/json"),
3535
new KeyValuePair<string, string>("Accept-Language", "en-us,en;q=0.5"),
@@ -46,7 +46,7 @@ public void AddHeaders_DifferentCaseDuplicatesExist_ThrowsException()
4646
[Test]
4747
public void AddHeaders_NoDuplicatesExist_Has3Headers()
4848
{
49-
var headers = new List<KeyValuePair<string, string>>()
49+
var headers = new List<KeyValuePair<string, string>>
5050
{
5151
new KeyValuePair<string, string>("Accept", "application/json"),
5252
new KeyValuePair<string, string>("Accept-Language", "en-us,en;q=0.5"),
@@ -64,7 +64,7 @@ public void AddHeaders_NoDuplicatesExist_Has3Headers()
6464
[Test]
6565
public void AddHeaders_NoDuplicatesExistUsingDictionary_Has3Headers()
6666
{
67-
var headers = new Dictionary<string, string>()
67+
var headers = new Dictionary<string, string>
6868
{
6969
{ "Accept", "application/json" },
7070
{ "Accept-Language", "en-us,en;q=0.5" },
@@ -78,5 +78,122 @@ public void AddHeaders_NoDuplicatesExistUsingDictionary_Has3Headers()
7878

7979
Assert.AreEqual(3, httpParameters.Count());
8080
}
81+
82+
[Test]
83+
public void AddOrUpdateHeader_ShouldUpdateExistingHeader_WhenHeaderExist()
84+
{
85+
// Arrange
86+
var request = new RestRequest();
87+
request.AddHeader("Accept", "application/xml");
88+
89+
// Act
90+
request.AddOrUpdateHeader("Accept", "application/json");
91+
92+
// Assert
93+
var headers = request.Parameters.Where(parameter => parameter.Type == ParameterType.HttpHeader).ToArray();
94+
95+
Assert.AreEqual("application/json", headers.First(parameter => parameter.Name == "Accept").Value);
96+
Assert.AreEqual(1, headers.Length);
97+
}
98+
99+
[Test]
100+
public void AddOrUpdateHeader_ShouldUpdateExistingHeader_WhenHeaderDoesNotExist()
101+
{
102+
// Arrange
103+
var request = new RestRequest();
104+
105+
// Act
106+
request.AddOrUpdateHeader("Accept", "application/json");
107+
108+
// Assert
109+
var headers = request.Parameters.Where(parameter => parameter.Type == ParameterType.HttpHeader).ToArray();
110+
111+
Assert.AreEqual("application/json", headers.First(parameter => parameter.Name == "Accept").Value);
112+
Assert.AreEqual(1, headers.Length);
113+
}
114+
115+
[Test]
116+
public void AddOrUpdateHeaders_ShouldAddHeaders_WhenNoneExists()
117+
{
118+
// Arrange
119+
var headers = new Dictionary<string, string>
120+
{
121+
{ "Accept", "application/json" },
122+
{ "Accept-Language", "en-us,en;q=0.5" },
123+
{ "Keep-Alive", "300" }
124+
};
125+
126+
var request = new RestRequest();
127+
128+
// Act
129+
request.AddOrUpdateHeaders(headers);
130+
131+
// Assert
132+
var requestHeaders = request.Parameters.Where(parameter => parameter.Type == ParameterType.HttpHeader).ToArray();
133+
134+
Assert.AreEqual("application/json", requestHeaders.First(parameter => parameter.Name == "Accept").Value);
135+
Assert.AreEqual("en-us,en;q=0.5", requestHeaders.First(parameter => parameter.Name == "Accept-Language").Value);
136+
Assert.AreEqual("300", requestHeaders.First(parameter => parameter.Name == "Keep-Alive").Value);
137+
Assert.AreEqual(3, requestHeaders.Length);
138+
}
139+
140+
[Test]
141+
public void AddOrUpdateHeaders_ShouldUpdateHeaders_WhenAllExists()
142+
{
143+
// Arrange
144+
var headers = new Dictionary<string, string>
145+
{
146+
{ "Accept", "application/json" },
147+
{ "Keep-Alive", "300" }
148+
};
149+
var updatedHeaders = new Dictionary<string, string>
150+
{
151+
{ "Accept", "application/xml" },
152+
{ "Keep-Alive", "400" }
153+
};
154+
155+
var request = new RestRequest();
156+
request.AddHeaders(headers);
157+
158+
// Act
159+
request.AddOrUpdateHeaders(updatedHeaders);
160+
161+
// Assert
162+
var requestHeaders = request.Parameters.Where(parameter => parameter.Type == ParameterType.HttpHeader).ToArray();
163+
164+
Assert.AreEqual("application/xml", requestHeaders.First(parameter => parameter.Name == "Accept").Value);
165+
Assert.AreEqual("400", requestHeaders.First(parameter => parameter.Name == "Keep-Alive").Value);
166+
Assert.AreEqual(2, requestHeaders.Length);
167+
}
168+
169+
[Test]
170+
public void AddOrUpdateHeaders_ShouldAddAndUpdateHeaders_WhenSomeExists()
171+
{
172+
// Arrange
173+
var headers = new Dictionary<string, string>
174+
{
175+
{ "Accept", "application/json" },
176+
{ "Keep-Alive", "300" }
177+
};
178+
var updatedHeaders = new Dictionary<string, string>
179+
{
180+
{ "Accept", "application/xml" },
181+
{ "Accept-Language", "en-us,en;q=0.5" }
182+
};
183+
184+
var request = new RestRequest();
185+
request.AddHeaders(headers);
186+
187+
// Act
188+
request.AddOrUpdateHeaders(updatedHeaders);
189+
190+
// Assert
191+
var requestHeaders = request.Parameters.Where(parameter => parameter.Type == ParameterType.HttpHeader).ToArray();
192+
193+
Assert.AreEqual("application/xml", requestHeaders.First(parameter => parameter.Name == "Accept").Value);
194+
Assert.AreEqual("en-us,en;q=0.5", requestHeaders.First(parameter => parameter.Name == "Accept-Language").Value);
195+
Assert.AreEqual("300", requestHeaders.First(parameter => parameter.Name == "Keep-Alive").Value);
196+
Assert.AreEqual(3, requestHeaders.Length);
197+
}
81198
}
82199
}

0 commit comments

Comments
 (0)