public void TestDuplicateHandshakeResponseHeaders() { WebSocketServerHandshaker serverHandshaker = NewHandshaker("ws://example.com/chat", "chat", WebSocketDecoderConfig.Default); IFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.Http11, HttpMethod.Get, "/chat"); request.Headers .Set(HttpHeaderNames.Host, "example.com") .Set(HttpHeaderNames.Origin, "example.com") .Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket) .Set(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade) .Set(HttpHeaderNames.SecWebsocketKey, "dGhlIHNhbXBsZSBub25jZQ==") .Set(HttpHeaderNames.SecWebsocketOrigin, "http://example.com") .Set(HttpHeaderNames.SecWebsocketProtocol, "chat, superchat") .Set(HttpHeaderNames.SecWebsocketVersion, WebSocketVersion().ToHttpHeaderValue()); HttpHeaders customResponseHeaders = new DefaultHttpHeaders(); // set duplicate required headers and one custom customResponseHeaders .Set(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade) .Set(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket) .Set(AsciiString.Of("custom"), AsciiString.Of("header")); if (WebSocketVersion() != Http.WebSockets.WebSocketVersion.V00) { customResponseHeaders.Set(HttpHeaderNames.SecWebsocketAccept, "12345"); } IFullHttpResponse response = null; try { response = serverHandshaker.NewHandshakeResponse(request, customResponseHeaders); HttpHeaders responseHeaders = response.Headers; Assert.Equal(1, responseHeaders.GetAll(HttpHeaderNames.Connection).Count); Assert.Equal(1, responseHeaders.GetAll(HttpHeaderNames.Upgrade).Count); Assert.True(responseHeaders.ContainsValue(AsciiString.Of("custom"), AsciiString.Of("header"), true)); if (WebSocketVersion() != Http.WebSockets.WebSocketVersion.V00) { Assert.False(responseHeaders.ContainsValue(HttpHeaderNames.SecWebsocketAccept, AsciiString.Of("12345"), false)); } } finally { request.Release(); if (response != null) { response.Release(); } } }
protected override void Verify(IFullHttpResponse response) { HttpResponseStatus status = HttpResponseStatus.SwitchingProtocols; HttpHeaders headers = response.Headers; if (!response.Status.Equals(status)) { throw new WebSocketHandshakeException($"Invalid handshake response getStatus: {response.Status}"); } if (headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) || !HttpHeaderValues.Websocket.ContentEqualsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException($"Invalid handshake response upgrade: {upgrade}"); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { headers.TryGet(HttpHeaderNames.Connection, out upgrade); throw new WebSocketHandshakeException($"Invalid handshake response connection: {upgrade}"); } if (headers.TryGet(HttpHeaderNames.SecWebsocketAccept, out ICharSequence accept) || !accept.Equals(this.expectedChallengeResponseString)) { throw new WebSocketHandshakeException($"Invalid challenge. Actual: {accept}. Expected: {this.expectedChallengeResponseString}"); } }
protected override void Verify(IFullHttpResponse response) { if (!response.Status.Equals(HttpResponseStatus.SwitchingProtocols)) { throw new WebSocketHandshakeException($"Invalid handshake response getStatus: {response.Status}"); } HttpHeaders headers = response.Headers; if (!headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) || !Websocket.ContentEqualsIgnoreCase(upgrade)) { throw new WebSocketHandshakeException($"Invalid handshake response upgrade: {upgrade}"); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { headers.TryGet(HttpHeaderNames.Connection, out upgrade); throw new WebSocketHandshakeException($"Invalid handshake response connection: {upgrade}"); } IByteBuffer challenge = response.Content; if (!challenge.Equals(this.expectedChallengeResponseBytes)) { throw new WebSocketHandshakeException("Invalid challenge"); } }
/// <summary> /// Process server response: /// <![CDATA[ /// HTTP/1.1 101 Switching Protocols /// Upgrade: websocket /// Connection: Upgrade /// Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= /// Sec-WebSocket-Protocol: chat /// ]]> /// </summary> /// <param name="response">HTTP response returned from the server for the request sent by beginOpeningHandshake00().</param> /// <exception cref="WebSocketHandshakeException">if handshake response is invalid.</exception> protected override void Verify(IFullHttpResponse response) { HttpResponseStatus status = HttpResponseStatus.SwitchingProtocols; HttpHeaders headers = response.Headers; if (!response.Status.Equals(status)) { ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseGS(response); } if (!headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) || !HttpHeaderValues.Websocket.ContentEqualsIgnoreCase(upgrade)) { ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseU(upgrade); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { _ = headers.TryGet(HttpHeaderNames.Connection, out upgrade); ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseConn(upgrade); } if (!headers.TryGet(HttpHeaderNames.SecWebsocketAccept, out ICharSequence accept) || !accept.Equals(_expectedChallengeResponseString)) { ThrowHelper.ThrowWebSocketHandshakeException_InvalidChallenge(accept, _expectedChallengeResponseString); } }
protected override void Verify(IFullHttpResponse response) { if (!response.Status.Equals(HttpResponseStatus.SwitchingProtocols)) { ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseGS(response); } HttpHeaders headers = response.Headers; if (!headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgrade) || !Websocket.ContentEqualsIgnoreCase(upgrade)) { ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseU(upgrade); } if (!headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true)) { _ = headers.TryGet(HttpHeaderNames.Connection, out upgrade); ThrowHelper.ThrowWebSocketHandshakeException_InvalidHandshakeResponseConn(upgrade); } IByteBuffer challenge = response.Content; if (!challenge.Equals(_expectedChallengeResponseBytes)) { ThrowHelper.ThrowWebSocketHandshakeException_InvalidChallenge(); } }
internal static bool IsWebsocketUpgrade(HttpHeaders headers) => headers.ContainsValue(HttpHeaderNames.Connection, HttpHeaderValues.Upgrade, true) && headers.Contains(HttpHeaderNames.Upgrade, HttpHeaderValues.Websocket, true);