private static byte[] BuildRequestHeader(Uri uri, ClientWebSocketOptions options, string secKey)
{
StringBuilder builder = t_cachedStringBuilder ?? (t_cachedStringBuilder = new StringBuilder());
Debug.Assert(builder.Length == 0, $"Expected builder to be empty, got one of length {builder.Length}");
try
{
builder.Append("GET ").Append(uri.PathAndQuery).Append(" HTTP/1.1\r\n");
// Add all of the required headers
builder.Append("Host: ").Append(uri.IdnHost).Append(":").Append(uri.Port).Append("\r\n");
builder.Append("Connection: Upgrade\r\n");
builder.Append("Upgrade: websocket\r\n");
builder.Append("Sec-WebSocket-Version: 13\r\n");
builder.Append("Sec-WebSocket-Key: ").Append(secKey).Append("\r\n");
// Add all of the additionally requested headers
foreach (string key in options.RequestHeaders.AllKeys)
{
builder.Append(key).Append(": ").Append(options.RequestHeaders[key]).Append("\r\n");
}
// Add the optional subprotocols header
if (options.RequestedSubProtocols.Count > 0)
{
builder.Append(HttpKnownHeaderNames.SecWebSocketProtocol).Append(": ");
builder.Append(options.RequestedSubProtocols[0]);
for (int i = 1; i < options.RequestedSubProtocols.Count; i++)
{
builder.Append(", ").Append(options.RequestedSubProtocols[i]);
}
builder.Append("\r\n");
}
// Add an optional cookies header
if (options.Cookies != null)
{
string header = options.Cookies.GetCookieHeader(uri);
if (!string.IsNullOrWhiteSpace(header))
{
builder.Append(HttpKnownHeaderNames.Cookie).Append(": ").Append(header).Append("\r\n");
}
}
// End the headers
builder.Append("\r\n");
// Return the bytes for the built up header
return s_defaultHttpEncoding.GetBytes(builder.ToString());
}
finally
{
// Make sure we clear the builder
builder.Clear();
}
}