How can I set User-Agent and Referer headers when using ClientWebSocket in .net 4.5?

笑着哭i 提交于 2019-12-19 08:50:26

问题


The obvious answer of using ClientWebSocket.SetHeader throws an exception because it's a protected header:

System.ArgumentException occurred
  Message=The 'User-Agent' header must be modified using the appropriate property or method.
Parameter name: name
  ParamName=name
  StackTrace:
       at System.Net.WebHeaderCollection.ThrowOnRestrictedHeader(String headerName)

The exception string suggests using a property/method on the ClientWebSocket itself but I can't find any such property/method. It seems this exception was designed for the HttpWebRequest class, which actually has such property.

The code, which doesn't work:

ClientWebSocket socket = new ClientWebSocket();
// Will throw
socket.Options.SetRequestHeader("User-Agent", "SomeUserAgentString");
// Will throw
socket.Options.SetRequestHeader("Referer", "SomeReferer"]);

回答1:


It doesn't look like you'll be able to set those properties, at least not right now. You might be able to do it via reflection.

If you look closely at your stack trace, you'll see that the throwing method is System.Net.WebHeaderCollection.ThrowOnRestrictedHeader. System.Net.WebHeaderCollection is a specialized name value collection designed to deal with HTTP headers. If you look at the remarks section, you'll see the following:

Some common headers are considered restricted and are either exposed directly by the API (such as Content-Type) or protected by the system and cannot be changed.

The list has both the User-Agent and Referer properties listed as protected headers and cannot be set since the ClientWebSocket does not expose it.

All that being said, though, if you absolutely need to set those headers, you'll need to find the private reference WebHeaderCollection of your ClientWebSocketOptions (exposed as the Options property on your ClientWebSocket) and call the protected AddWithoutValidate method to set the headers.




回答2:


Looks like this is a bug in .NET Framework:

https://github.com/dotnet/corefx/issues/26627#issuecomment-391472613

And unfortunately, it seems that even the reflection hack suggested by Joshua won't work, as the validation is performed again as part of the HTTP exchange when the websocket connection is established:

https://github.com/dotnet/corefx/issues/26627#issuecomment-361234413




回答3:


You can use reflection to change static Hashtable with HeaderInfo (all internal classes used by WebHeaderCollection).

More details in my answer here: Cannot set some HTTP headers when using System.Net.WebRequest

Edit: It has been confirmed that this fix the ClientWebSocket issue and allows you to set User-Agent and Referer.




回答4:


I think i have found a "easy" solution

If you build with ".NET Core 2.2" (on windows 10) instead then:

"socket.Options.SetRequestHeader("User-Agent", "SomeUserAgentString");"

Will not throw. Same with all the other restricted headers.

So either it works, or it just fails silently. I haven't been able to test and verify that it works, as I don't know how to log or view the request headers. (Anyone know?)




回答5:


very simple:

The referrer header should be written like so:

HttpWebRequest objRequest()... objRequest.Referer = "http://microsoft.com/simpleApp/



来源:https://stackoverflow.com/questions/15894844/how-can-i-set-user-agent-and-referer-headers-when-using-clientwebsocket-in-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!