Question

Given the following System.Net.Http.HttpClient Portable Class Library throws an exception:

var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Authorization", "aaaa,bbbb");

The exception is: Invalid Format

at System.Net.Http.Headers.HttpHeaders.AddInternal (System.String name, IEnumerable1 values, System.Net.Http.Headers.HeaderInfo headerInfo, Boolean ignoreInvalid) [0x0004c] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs:195 at System.Net.Http.Headers.HttpHeaders.Add (System.String name, IEnumerable1 values) [0x00011] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs:170 at System.Net.Http.Headers.HttpHeaders.Add (System.String name, System.String value) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders < ... snip ...>

Now this only happens under the following

Header key = Authorization. If you change that to anything else, it's ok. Value = has to have a comma, in it.

Now, this previous SO question suggests that a comma is the correct way to stick multiple values in the header.

Can anyone explain what is going on?

NOTE: This is on Xamarin, so I guess it's mono. Not sure if that's important.

UPDATE:

here's a pic of it.

enter image description here

Was it helpful?

Solution

According to this links spec rfc2617 separating with a comma does seem valid.

"It uses an extensible, case-insensitive token to identify the authentication scheme, followed by a comma-separated list of attribute-value pairs which carry the parameters necessary for achieving authentication via that scheme."

But therein it suggests you are quite possible setting them incorrectly, they must be of the form "attribute-value pairs":

auth-param     = token "=" ( token | quoted-string )

How exactly are you setting them?

httpClient.DefaultRequestHeaders.Add("Authorization", "aaaa,bbbb");

The above is seemingly invalid, they are not attribute pairs "aaaa,bbbb". There is no = sign for either attribute you are attempting to set.

Try the following as a test:

httpClient.DefaultRequestHeaders.Add("Authorization", "aaaa=1234,bbbb=45678");

OTHER TIPS

There was a bug in the mono implementation that did not allow valid characters in headers, i.e. [ and ] - this has been fixed, but for Xamarin Android it has not reached stable branch yet (it will come with Xamarin Android 5)

It is possible to circumvent this, if you cannot wait, you need to ship now, and you NEED to have special characters in the header, there is a way (I have now disclaimered away)

Before adding the headers you can add the characters as allowed tokens in headers. This is undocumented, illegal (from a proper coding perspective) and done via reflection, but it works:

var assembly = typeof(System.Net.Http.Headers.HttpContentHeaders).Assembly;
var lexer = assembly.GetType("System.Net.Http.Headers.Lexer");
var field = lexer.GetField("token_chars", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
var tokens = ( bool[])field.GetValue(null);
tokens[91] = true;
tokens[93] = true;
field.SetValue(null, tokens);

In the sample above we allow character 91 and 93 [ and ] respectively.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top