I need to set the "User-Agent" HTTP header in a ClientWebSocket
object, but it is not possible. Although there is a ClientWebSocket.SetRequestHeader(header,value)
, the method fails if I try to set that header: System.ArgumentException: This header must be modified using the appropriate property or method.
Looking at the ClientWebSocket
source code, it seems that the MS people forgot completely about this:
// System.Net.WebSockets.ClientWebSocket
private HttpWebRequest CreateAndConfigureRequest(Uri uri)
{
HttpWebRequest httpWebRequest = WebRequest.Create(uri) as HttpWebRequest;
if (httpWebRequest == null)
{
throw new InvalidOperationException(SR.GetString("net_WebSockets_InvalidRegistration"));
}
foreach (string name in this.options.RequestHeaders.Keys)
{
httpWebRequest.Headers.Add(name, this.options.RequestHeaders[name]);
}
if (this.options.RequestedSubProtocols.Count > 0)
{
httpWebRequest.Headers.Add("Sec-WebSocket-Protocol", string.Join(", ", this.options.RequestedSubProtocols));
}
if (this.options.UseDefaultCredentials)
{
httpWebRequest.UseDefaultCredentials = true;
}
else
{
if (this.options.Credentials != null)
{
httpWebRequest.Credentials = this.options.Credentials;
}
}
if (this.options.InternalClientCertificates != null)
{
httpWebRequest.ClientCertificates = this.options.InternalClientCertificates;
}
httpWebRequest.Proxy = this.options.Proxy;
httpWebRequest.CookieContainer = this.options.Cookies;
this.cts.Token.Register(new Action<object>(this.AbortRequest), httpWebRequest, false);
return httpWebRequest;
}
So the only way I see is replacing this method with reflection and re-write the code properly (checking for special headers and using the special properties, like httpWebRequest.UserAgent
).
Any other better idea?
There is no way. I have created a fork of the class that allows to set that header: