1

I just encountered this strange behavior, which I can reproduce with the following code:

var request = new HttpRequestMessage(new HttpMethod("POST"), "/api/mymethod");
request.Headers.Add("Cookie", "mycookie");
request.Headers.Add("Cookie2", "mycookie");
request.Content = new StringContent("<foo></foo>", Encoding.UTF8, "application/xml");
return httpClient.SendAsync(request);

I then log the request with necat and I see that Cookie2 is present, but Cookie is not!

POST /api/mymethod HTTP/1.1
Cookie2: mycookie
Content-Type: application/xml; charset=utf-8
Host: localhost:7777
Content-Length: 11
Expect: 100-continue
Connection: Keep-Alive

<foo></foo>

It seems as if HttpRequestMessage goes out of its way to ignore the Cookie header, and I am wondering why it behaves like that.

And is there any way to force-add the Cookie? I suppose maybe they do it to enforce good coding practices, but right now I'm making a short throwaway script to automate a manual task (even the cookie is hardcoded in my code) and I was surprised at this behavior.

Found answer:

From https://stackoverflow.com/a/13287224/492336, you can set an HttpClientHandler with UseCookies set to false, then it works:

HttpClient httpClient = new HttpClient(new HttpClientHandler { UseCookies = false }) { BaseAddress = new Uri(ConfigurationManager.AppSettings["server"]) };

Anyway, you should probably not use this for non-throwaway code.

sashoalm
  • 75,001
  • 122
  • 434
  • 781
  • You need a `CookieContainer`. See https://stackoverflow.com/questions/11164275 – Robert Harvey May 03 '18 at 16:47
  • That would seem to be so. But I still wonder why `request.Headers.Add()` doesn't work - in general, code should behave in unexpected ways, and if I write `request.Headers.Add("Cookie")`, I certainly don't expect it to NOT ADD the cookie :) – sashoalm May 03 '18 at 16:51
  • Because that's the way Microsoft designed it. Usually, when you create a new class like CookieCollection and then require people to use it, it means that 1. You want a finer degree of control than a mere string will provide. This is the basis for SQL parameters to avoid SQL injection, for example. And, 2. To provide additional functionality that a string alone won't provide. – Robert Harvey May 03 '18 at 16:55
  • Haha, yes. Anyway, the second answer in https://stackoverflow.com/questions/12373738/how-do-i-set-a-cookie-on-httpclients-httprequestmessage says I can put UseCookies=false in HttpHandler and then I can add it request.Headers.Add. Thanks! – sashoalm May 03 '18 at 16:57
  • The source code for CookieContainer is [here](https://referencesource.microsoft.com/#System/net/System/Net/cookiecontainer.cs), if you're so inclined. Among other things, it supports the expiration of cookies, first-class URI objects, a hashtable for performance, cookie validation, thread safety and a number of other features. It's about 1000 lines of code. – Robert Harvey May 03 '18 at 17:02

0 Answers0