public void TestByteBufSkip(string[] asciiBuffers, bool[] continueMatch, bool httpMatched) { var httpMatcher = new HttpMatcher(); httpMatcher.Clear(); SimpleByteBuf byteBuf = null; for (int i = 0; i < asciiBuffers.Length; i++) { byte[] asciiBytes = Encoding.ASCII.GetBytes(asciiBuffers[i]); if (byteBuf == null) { byteBuf = new SimpleByteBuf(asciiBytes); } else { byteBuf = byteBuf.Concat(asciiBytes); } bool continueMatching; httpMatcher.Match(byteBuf, out continueMatching); Assert.True(continueMatching == continueMatch[i]); } Assert.True(httpMatched == GetHttpMatched(httpMatcher.GetMatchingState)); }
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(); } } }