protected internal override IFullHttpRequest NewHandshakeRequest() { Uri wsUrl = Uri; // Get 16 bit nonce and base 64 encode it byte[] nonce = WebSocketUtil.RandomBytes(16); string key = WebSocketUtil.Base64String(nonce); string acceptSeed = key + MagicGuid; byte[] sha1 = WebSocketUtil.Sha1(Encoding.ASCII.GetBytes(acceptSeed)); _expectedChallengeResponseString = new AsciiString(WebSocketUtil.Base64String(sha1)); #if DEBUG if (Logger.DebugEnabled) { Logger.WebSocketVersion07ClientHandshakeKey(key, _expectedChallengeResponseString); } #endif // Format request var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, UpgradeUrl(wsUrl), Unpooled.Empty); HttpHeaders headers = request.Headers; if (CustomHeaders is object) { _ = headers.Add(CustomHeaders); if (!headers.Contains(HttpHeaderNames.Host)) { // Only add HOST header if customHeaders did not contain it. // // See https://github.com/netty/netty/issues/10101 _ = headers.Set(HttpHeaderNames.Host, WebsocketHostValue(wsUrl)); } } else { _ = headers.Set(HttpHeaderNames.Host, WebsocketHostValue(wsUrl)); } _ = headers.Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket) .Set(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade) .Set(HttpHeaderNames.SecWebsocketKey, key); if (!headers.Contains(HttpHeaderNames.SecWebsocketOrigin)) { _ = headers.Set(HttpHeaderNames.SecWebsocketOrigin, WebsocketOriginValue(wsUrl)); } string expectedSubprotocol = ExpectedSubprotocol; if (!string.IsNullOrEmpty(expectedSubprotocol)) { _ = headers.Set(HttpHeaderNames.SecWebsocketProtocol, expectedSubprotocol); } _ = headers.Set(HttpHeaderNames.SecWebsocketVersion, Version.ToString()); return(request); }
/// <summary> /// Handle the web socket handshake for the web socket specification <a href= /// "http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-07">HyBi version 7</a>. /// /// <para> /// Browser request to the server: /// </para> /// /// <![CDATA[ /// GET /chat HTTP/1.1 /// Host: server.example.com /// Upgrade: websocket /// Connection: Upgrade /// Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== /// Sec-WebSocket-Origin: http://example.com /// Sec-WebSocket-Protocol: chat, superchat /// Sec-WebSocket-Version: 7 /// ]]> /// /// <para> /// Server response: /// </para> /// /// <![CDATA[ /// HTTP/1.1 101 Switching Protocols /// Upgrade: websocket /// Connection: Upgrade /// Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= /// Sec-WebSocket-Protocol: chat /// ]]> /// </summary> protected internal override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, HttpHeaders headers) { if (!req.Headers.TryGet(HttpHeaderNames.SecWebsocketKey, out ICharSequence key) || key is null) { ThrowHelper.ThrowWebSocketHandshakeException_MissingKey(); } var res = new DefaultFullHttpResponse(HttpVersion.Http11, HttpResponseStatus.SwitchingProtocols, req.Content.Allocator.Buffer(0)); if (headers is object) { _ = res.Headers.Add(headers); } string acceptSeed = key + Websocket07AcceptGuid; byte[] sha1 = WebSocketUtil.Sha1(Encoding.ASCII.GetBytes(acceptSeed)); string accept = WebSocketUtil.Base64String(sha1); #if DEBUG if (Logger.DebugEnabled) { Logger.WebSocketVersion07ServerHandshakeKey(key, accept); } #endif _ = res.Headers.Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket) .Set(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade) .Set(HttpHeaderNames.SecWebsocketAccept, accept); if (req.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out ICharSequence subprotocols) && subprotocols is object) { string selectedSubprotocol = this.SelectSubprotocol(subprotocols.ToString()); if (selectedSubprotocol is null) { #if DEBUG if (Logger.DebugEnabled) { Logger.RequestedSubprotocolNotSupported(subprotocols); } #endif } else { _ = res.Headers.Add(HttpHeaderNames.SecWebsocketProtocol, selectedSubprotocol); } } return(res); }
protected override IFullHttpResponse NewHandshakeResponse(IFullHttpRequest req, HttpHeaders headers) { var res = new DefaultFullHttpResponse(HttpVersion.Http11, HttpResponseStatus.SwitchingProtocols); if (headers != null) { res.Headers.Add(headers); } if (!req.Headers.TryGet(HttpHeaderNames.SecWebsocketKey, out ICharSequence key) || key == null) { throw new WebSocketHandshakeException("not a WebSocket request: missing key"); } string acceptSeed = key + Websocket07AcceptGuid; byte[] sha1 = WebSocketUtil.Sha1(Encoding.ASCII.GetBytes(acceptSeed)); string accept = WebSocketUtil.Base64String(sha1); if (Logger.DebugEnabled) { Logger.Debug("WebSocket version 07 server handshake key: {}, response: {}.", key, accept); } res.Headers.Add(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket); res.Headers.Add(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade); res.Headers.Add(HttpHeaderNames.SecWebsocketAccept, accept); if (req.Headers.TryGet(HttpHeaderNames.SecWebsocketProtocol, out ICharSequence subprotocols) && subprotocols != null) { string selectedSubprotocol = this.SelectSubprotocol(subprotocols.ToString()); if (selectedSubprotocol == null) { if (Logger.DebugEnabled) { Logger.Debug("Requested subprotocol(s) not supported: {}", subprotocols); } } else { res.Headers.Add(HttpHeaderNames.SecWebsocketProtocol, selectedSubprotocol); } } return(res); }
protected override IFullHttpRequest NewHandshakeRequest() { // Get path Uri wsUrl = this.Uri; string path = RawPath(wsUrl); // Get 16 bit nonce and base 64 encode it byte[] nonce = WebSocketUtil.RandomBytes(16); string key = WebSocketUtil.Base64String(nonce); string acceptSeed = key + MagicGuid; byte[] sha1 = WebSocketUtil.Sha1(Encoding.ASCII.GetBytes(acceptSeed)); this.expectedChallengeResponseString = new AsciiString(WebSocketUtil.Base64String(sha1)); if (Logger.DebugEnabled) { Logger.Debug("WebSocket version 07 client handshake key: {}, expected response: {}", key, this.expectedChallengeResponseString); } // Format request var request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, path); HttpHeaders headers = request.Headers; headers.Add(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket) .Add(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade) .Add(HttpHeaderNames.SecWebsocketKey, key) .Add(HttpHeaderNames.Host, WebsocketHostValue(wsUrl)) .Add(HttpHeaderNames.SecWebsocketOrigin, WebsocketOriginValue(wsUrl)); string expectedSubprotocol = this.ExpectedSubprotocol; if (string.IsNullOrEmpty(expectedSubprotocol)) { headers.Add(HttpHeaderNames.SecWebsocketProtocol, expectedSubprotocol); } headers.Add(HttpHeaderNames.SecWebsocketVersion, "7"); if (this.CustomHeaders != null) { headers.Add(this.CustomHeaders); } return(request); }