Skip to content

Commit d5392a7

Browse files
committed
chore: implement coderabbit suggestions
1 parent 32f6a2a commit d5392a7

1 file changed

Lines changed: 27 additions & 5 deletions

File tree

config/clients/dotnet/template/Client_ApiClient.mustache

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,24 +167,46 @@ public class ApiClient : IDisposable {
167167
}
168168

169169
/// <summary>
170-
/// Builds the complete headers dictionary by merging OAuth token and per-request headers
170+
/// Builds the complete headers dictionary by merging OAuth token and per-request headers.
171+
/// Validates per-request headers and performs case-insensitive merging.
171172
/// </summary>
172173
/// <param name="oauthToken">OAuth access token if available</param>
173174
/// <param name="perRequestHeaders">Per-request custom headers</param>
174175
/// <returns>Merged headers dictionary or null if no headers to add</returns>
176+
/// <exception cref="ArgumentException">Thrown when header key is null, empty, or whitespace</exception>
177+
/// <exception cref="ArgumentNullException">Thrown when header value is null</exception>
175178
private static IDictionary<string, string>? BuildHeaders(string? oauthToken, IDictionary<string, string>? perRequestHeaders) {
176-
if (string.IsNullOrEmpty(oauthToken) && perRequestHeaders == null) {
179+
// Validate per-request headers at the client boundary
180+
if (perRequestHeaders != null) {
181+
foreach (var header in perRequestHeaders) {
182+
if (string.IsNullOrWhiteSpace(header.Key)) {
183+
throw new ArgumentException(
184+
"Header name cannot be null, empty, or whitespace.",
185+
nameof(perRequestHeaders));
186+
}
187+
188+
if (header.Value == null) {
189+
throw new ArgumentNullException(
190+
nameof(perRequestHeaders),
191+
$"Header '{header.Key}' has a null value. Header values cannot be null.");
192+
}
193+
}
194+
}
195+
196+
// Return null if no headers to add
197+
if (string.IsNullOrEmpty(oauthToken) && (perRequestHeaders == null || perRequestHeaders.Count == 0)) {
177198
return null;
178199
}
179200

180-
var headers = new Dictionary<string, string>();
201+
// Use case-insensitive dictionary for proper header merging
202+
var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
181203

182-
// Add OAuth token header if present
204+
// Add OAuth token header first
183205
if (!string.IsNullOrEmpty(oauthToken)) {
184206
headers["Authorization"] = $"Bearer {oauthToken}";
185207
}
186208

187-
// Merge per-request headers (these take precedence)
209+
// Overlay per-request headers (these take precedence regardless of casing)
188210
if (perRequestHeaders != null) {
189211
foreach (var header in perRequestHeaders) {
190212
headers[header.Key] = header.Value;

0 commit comments

Comments
 (0)