Reputation: 83
I have to connect to a RESTAPI which requires a number of different headers. One of them is causing me a problem because it has it's name within brackets - the header name is "(request-target)".
This is my code but when I hit the line where I'm adding in this value - it says the "The header name format is invalid"
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("(request-target)", "host date");
client.DefaultRequestHeaders.Date = DateTime.Now;
client.DefaultRequestHeaders.Host = "localhost:50414";
int count = client.DefaultRequestHeaders.Count();
I have tried
client.DefaultRequestHeaders.TryAddWithoutValidation("(request-target)", "host date");
It doesn't fail - but my count for the number of headers does not include this header. I've tried this code - it gives me the same error about the "header name format is invalid"
HttpRequestMessage httpreqmsg = new HttpRequestMessage();
httpreqmsg.Headers.Add("(request-target)", "host date");
Can anyone tell me how to get around this before I go mad !
Thanks a mill.
Further Update
They have provided a java code - to extract the header details and the name definitely includes brackets. The headers are used to build a string that is signed with a key from a digital cert.
public String buildStringToBeSigned(HttpServletRequest request, List<String> signatureHeaders) {
Integer counter = 0;
StringBuilder sb = new StringBuilder();
for (String s : signatureHeaders) {
counter++;
if ("(request-target)".equalsIgnoreCase(s)) {
sb.append(s + ": " + request.getMethod().toLowerCase()
+ " " + request.getRequestURI() + (counter < signatureHeaders.size() ? "\n" : ""));
}else{
sb.append(s + ": " + request.getHeader(s) + (counter < signatureHeaders.size() ? "\n" : ""));
}
}
return sb.toString();
}
Upvotes: 3
Views: 2065
Reputation: 8183
So what is happening is that in the HttpHeaders
class when you call DefaultRequestHeaders.Add
it calls a private method called CheckHeaderName
.
Inside that, it does validation against the header key in your case (request-target)
.
First, it checks if it's empty, then it checks something called the TokenLength
. Basically, this check goes through each character of your header key and checks against a bunch of TokenChars
. The following char
s are not allowed:
40
41
60
62
64
44
59
58
92
34
47
91
93
63
61
123
125
And the characters (
and )
both equal 40
and 41
.
So it looks like it's baked into the .Net framework that the header key is not allowed for any of the above characters.
The TokenLength
check is also called when you call TryAddWithoutValidation
. TryAddWithoutValidation
also returns a bool if the header was added to the collection, so you can use that in code to see if it was added.
Note: This was checked against .Net Framework 4.7.2
Update:
Since it's easier to view the .Net Core source I also had a look there to see if anything has changed and it's pretty much the same sort of logic.
You can see the disallowed values here It checks if the header key has its value here which is called from here, since it will return false because it contains invalid characters the exception will get thrown.
Upvotes: 3