protected override void Matched(bool crlf, ref HttpMatchState state, out IHttpMatchStep newStep) { state.ConnectionHeaderValueMatched = true; newStep = crlf ? _crLfStep : _skipToCrLfStep; }
public void Test4() { string asciiHttpRequest = "Connection: upgrade, keep-alive\r\nSome-header: 123ghtyry\r\nUpgrade: WebSocketes"; var byteBuf = new SimpleByteBuf(Encoding.ASCII.GetBytes(asciiHttpRequest)); HttpMatchState state = default(HttpMatchState); IHttpMatchStep nextStep; _httpHeaderNameMatchStep.Match(byteBuf, ref state, out nextStep); Assert.True(state.ConnectionHeaderMatched); Assert.True(nextStep == _connectionHeaderValueMatchStep); nextStep.Match(byteBuf, ref state, out nextStep); Assert.True(state.ConnectionHeaderValueMatched); Assert.True(nextStep == _skipToCrLfMatchStep); // ***** nextStep.Match(byteBuf, ref state, out nextStep); Assert.True(nextStep == _crLfMatchStep); nextStep.Match(byteBuf, ref state, out nextStep); Assert.True(nextStep == _httpHeaderNameMatchStep); _httpHeaderNameMatchStep.Clear(); nextStep.Match(byteBuf, ref state, out nextStep); Assert.True(nextStep == _skipToCrLfMatchStep); nextStep.Match(byteBuf, ref state, out nextStep); Assert.True(nextStep == _crLfMatchStep); nextStep.Match(byteBuf, ref state, out nextStep); _httpHeaderNameMatchStep.Clear(); Assert.True(nextStep == _httpHeaderNameMatchStep); nextStep.Match(byteBuf, ref state, out nextStep); Assert.True(state.UpgradeHeaderMatched); Assert.True(nextStep == _upgradeHeaderValueMatchStep); nextStep.Match(byteBuf, ref state, out nextStep); Assert.False(state.UpgradeHeaderValueMatched); Assert.True(nextStep == null); }
private bool HandshakeMatched(HttpMatchState state) { return (state.ConnectionHeaderMatched & state.ConnectionHeaderValueMatched & state.UpgradeHeaderMatched & state.UpgradeHeaderValueMatched & state.SecWebSocketVersionHeaderMatched & state.SecWebSocketVersionHeaderValueMatched & state.SecWebSocketKeyHeaderMatched & state.SecWebSocketKeyHeaderValueMatched); }
public void Test1() { string asciiHttpRequest = "Connection: Upgrade"; var byteBuf = new SimpleByteBuf(Encoding.ASCII.GetBytes(asciiHttpRequest)); HttpMatchState state = default(HttpMatchState); IHttpMatchStep nextStep; _httpHeaderNameMatchStep.Match(byteBuf, ref state, out nextStep); Assert.True(state.ConnectionHeaderMatched); Assert.True(nextStep == _connectionHeaderValueMatchStep); }
protected override void NotMatched(bool crlf, ref HttpMatchState state, out IHttpMatchStep newStep) { state.ConnectionHeaderValueMatched = false; newStep = _finishStep; }
protected override void Read(IChannelHandlerContext ctx, ByteBuf byteBuf) { if (byteBuf.ReadableBytes() > 0) { if (_httpMatcher == null) { _httpMatcher = new HttpMatcher(); } bool continueMatching; _httpMatcher.Match(byteBuf, out continueMatching); if (continueMatching) { // Как минимум мы можем освободить прочитанную часть. byteBuf.ReleaseReaded(); return; } // TODO: если будет реализован проброс, то буфер освобождать нельзя, а надо будет просто сделать возврат в начало чтения. // Освобождаем буфер, т.к. больше матчить не будем. byteBuf.Release(); HttpMatchState state = _httpMatcher.GetMatchingState; bool handshake = HandshakeMatched(state); if (handshake) { ByteBuf outByteBuf = SwitchingProtocolResponse.Get(ctx, state.SecWebSocketKey, state.SecWebSocketKeyLen); _httpMatcher.Clear(); // TODO: !!!! временное решение !!!! Task writeTask = Task.Factory.StartNew( () => { ctx.Write(outByteBuf); } ); Task transformationTask = writeTask.ContinueWith( (writeTaskArg) => { if (writeTask.IsCompleted) { ctx.Pipeline.AddBefore( ctx.Name, _webSocketsMiddlewareName + "Encoder", _webSocket13EncoderProvider ); ctx.Pipeline.Replace( ctx.Name, _webSocketsMiddlewareName + "Decoder", _webSocket13DecoderProvider ); } } ); transformationTask.Wait(); } else { // TODO: проброс или bad response _httpMatcher.Clear(); } } }