private async Task ParseWebSocketAsync( byte[] b, HttpParserDelegate parserDelegate, HttpCombinedParser parserHandler, IEnumerable <string> subProtocols, IObserver <string> obs) { switch (_dataReceiveState) { case DataReceiveState.IsListeningForHandShake: _handshakeParser.Parse(b, parserDelegate, parserHandler); HandshakeController(parserDelegate, subProtocols); break; case DataReceiveState.IsListening: await _textDataParser.ParseAsync(_tcpStream, b[0], ExcludeZeroApplicationDataInPong); if (_textDataParser.IsCloseReceived) { StopReceivingData(); } if (_textDataParser.HasNewMessage) { obs.OnNext(_textDataParser.NewMessage); } break; } }
internal HttpStreamParser(HttpParserDelegate parserDelegate, params ErrorCorrection[] errorCorrections) { _errorCorrections = errorCorrections; _parserDelegate = parserDelegate; _parser = new HttpCombinedParser(parserDelegate); _last4BytesCircularBuffer = new CircularBuffer <byte>(4); }
internal IHttpRequestReponse Parse(HttpParserDelegate requestHandler, Stream stream, TimeSpan timeout) { using (var parserHandler = new HttpCombinedParser(requestHandler)) { var observeRequstStream = new ObservableHttpData().Create(requestHandler.HttpRequestReponse, stream, timeout); var observerRequestSubscriber = observeRequstStream.Subscribe( bArray => { try { if (parserHandler.Execute(new ArraySegment <byte>(bArray, 0, bArray.Length)) <= 0) { requestHandler.HttpRequestReponse.IsUnableToParseHttp = true; } } catch (Exception) { requestHandler.HttpRequestReponse.IsUnableToParseHttp = true; } }, ex => { if (ex is TimeoutException) { requestHandler = new HttpParserDelegate { HttpRequestReponse = { IsRequestTimedOut = true } }; } else { requestHandler = new HttpParserDelegate { HttpRequestReponse = { IsUnableToParseHttp = true } }; } }, () => { }); observerRequestSubscriber.Dispose(); parserHandler.Execute(default(ArraySegment <byte>)); requestHandler.HttpRequestReponse.MajorVersion = parserHandler.MajorVersion; requestHandler.HttpRequestReponse.MinorVersion = parserHandler.MinorVersion; requestHandler.HttpRequestReponse.ShouldKeepAlive = parserHandler.ShouldKeepAlive; } return(requestHandler.HttpRequestReponse); }
public void OnHeaderName(HttpCombinedParser combinedParser, string name) { // Header Field Names are case-insensitive http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 if (HttpRequestReponse.Headers.ContainsKey(name.ToUpper())) { _headerAlreadyExist = true; } _headerName = name.ToUpper(); }
public HandshakeParser( HttpCombinedParser parserHandler, HandshakeParserDelegate parserDelegate, Action <ConnectionStatus, Exception> connectionStatusAction) { _parserDelegate = parserDelegate; _parserHandler = parserHandler; _connectionStatusAction = connectionStatusAction; }
internal IObservable <string> CreateWebsocketListenerObservable( Stream tcpStream, IEnumerable <string> subProtocols = null) { ParserDelegate = new HttpParserDelegate(); var parserHandler = new HttpCombinedParser(ParserDelegate); _textDataParser.Reinitialize(); _tcpStream = tcpStream; _observerDataReceiveMode.OnNext(DataReceiveState.IsListeningForHandShake); _dataReceiveState = DataReceiveState.IsListeningForHandShake; var listenerObservable = Observable.Create <string>( obs => { var disposableReceiveState = DataReceiveStateObservable.Subscribe(s => { _dataReceiveState = s; }, obs.OnError, () => { Debug.WriteLine("DataReceiveObservable completed"); }); var disposableStreamListener = Observable.While( () => _dataReceiveState == DataReceiveState.IsListeningForHandShake || _dataReceiveState == DataReceiveState.IsListening, Observable.FromAsync(() => ReadOneByteAtTheTimeAsync(tcpStream))) .Select(b => Observable.FromAsync(() => ParseWebSocketAsync(b, ParserDelegate, parserHandler, subProtocols, obs))) .Concat() .Subscribe( _ => { if (_textDataParser.IsCloseReceived) { _observerDataReceiveMode.OnNext(DataReceiveState.Exiting); _observerDataReceiveMode.OnCompleted(); } }, obs.OnError, obs.OnCompleted); return(new CompositeDisposable(disposableReceiveState, disposableStreamListener)); }); return(listenerObservable); }
public void OnHeaderValue(HttpCombinedParser combinedParser, string value) { if (_headerAlreadyExist) { // Join multiple message-header fields into one comma seperated list http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 HttpRequestReponse.Headers[_headerName] = $"{HttpRequestReponse.Headers[_headerName]}, {value}"; _headerAlreadyExist = false; } else { HttpRequestReponse.Headers[_headerName] = value; } }
internal void Parse(byte[] data, HttpParserDelegate parserDelegate, HttpCombinedParser parserHandler) { try { if (parserHandler.Execute(new ArraySegment <byte>(data, 0, data.Length)) <= 0) { parserDelegate.HttpRequestResponse.IsUnableToParseHttp = true; } } catch (Exception) { parserDelegate.HttpRequestResponse.IsUnableToParseHttp = true; } }
internal IObservable <(HandshakeStateKind handshakeState, WebsocketClientLiteException?ex)> Handshake( Uri uri, WebsocketSenderHandler sender, TimeSpan timeout, CancellationToken ct, string?origin = null, IDictionary <string, string>?headers = null, IEnumerable <string>?subprotocols = null) { return(Observable.Create <(HandshakeStateKind handshakeState, WebsocketClientLiteException?ex)>(async obs => { using var parserDelegate = new HandshakeParserDelegate(obs); using var parserHandler = new HttpCombinedParser(parserDelegate); var handshakeParser = new HandshakeParser( parserHandler, parserDelegate, _connectionStatusAction); await SendHandshake(uri, sender, ct, origin, headers); await WaitForHandshake(handshakeParser); obs.OnCompleted(); }) .Timeout(timeout) .Catch < (HandshakeStateKind handshakeState, WebsocketClientLiteException?ex), TimeoutException>( tx => Observable.Return( (HandshakeStateKind.HandshakeTimedOut, new WebsocketClientLiteException("Handshake times out.", tx) ?? null) ) )); async Task WaitForHandshake(HandshakeParser handshakeParser) { bool isHandshakeDone; do { isHandshakeDone = await _tcpConnectionService .BytesObservable() .Select(b => handshakeParser.Parse(b, subprotocols)); } while (!isHandshakeDone); } }
static void Main(string[] args) { var handler = new ParserHandler(); var parser = new HttpCombinedParser(handler); var bArray = Encoding.UTF8.GetBytes(TestReponse()); System.Console.WriteLine(parser.Execute(new ArraySegment <byte>(bArray, 0, bArray.Length)) == bArray.Length ? $"Reponse test succeed. Type identified is; {handler.MessageType}" : $"Response test failed"); bArray = Encoding.UTF8.GetBytes(TestRequest()); System.Console.WriteLine(parser.Execute(new ArraySegment <byte>(bArray, 0, bArray.Length)) == bArray.Length ? $"Request test succeed. Type identified is; {handler.MessageType}" : $"Request test failed"); System.Console.ReadKey(); }
static void Main(string[] args) { byte[] bArray; using (var handler = new ParserHandler()) using (var parser = new HttpCombinedParser(handler)) { bArray = TestReponse(); System.Console.WriteLine(parser.Execute(new ArraySegment <byte>(bArray, 0, bArray.Length)) == bArray.Length ? $"Reponse test succeed. Type identified is; {handler.MessageType}" : $"Response test failed"); handler.HttpRequestReponse.Body.Position = 0; var reader = new StreamReader(handler.HttpRequestReponse.Body); var body = reader.ReadToEnd(); //bArray = Encoding.UTF8.GetBytes(TestRequest()); //System.Console.WriteLine(parser.Execute(new ArraySegment<byte>(bArray, 0, bArray.Length)) == bArray.Length // ? $"Request test succeed. Type identified is; {handler.MessageType}" // : $"Request test failed"); } using (var handler = new ParserHandler()) using (var parser = new HttpCombinedParser(handler)) { bArray = TestChunkedResponse(); System.Console.WriteLine(parser.Execute(new ArraySegment <byte>(bArray, 0, bArray.Length)) == bArray.Length ? $"Chunked Response test succeed. Type identified is; {handler.MessageType}." : $"Chunked Response test failed"); handler.HttpRequestReponse.Body.Position = 0; var reader = new StreamReader(handler.HttpRequestReponse.Body); var body = reader.ReadToEnd(); } System.Console.ReadKey(); }
public void OnFragment(HttpCombinedParser combinedParser, string fragment) { //throw new NotImplementedException(); }
public void OnPath(HttpCombinedParser combinedParser, string path) { //throw new NotImplementedException(); }
public void OnRequestUri(HttpCombinedParser combinedParser, string requestUri) { //throw new NotImplementedException(); }
public void OnMethod(HttpCombinedParser combinedParser, string method) { //throw new NotImplementedException(); }
public void OnRequestUri(HttpCombinedParser parser, string requestUri) { HttpRequestReponse.RequstUri = requestUri; }
public void OnResponseCode(HttpCombinedParser combinedParser, int statusCode, string statusReason) { HttpRequestReponse.StatusCode = statusCode; HttpRequestReponse.ResponseReason = statusReason; }
public void OnQueryString(HttpCombinedParser parser, string queryString) { HttpRequestReponse.QueryString = queryString; }
public void OnBody(HttpCombinedParser parser, ArraySegment <byte> data) { HttpRequestReponse.Body.Write(data.Array, 0, data.Array.Length); }
public void OnMessageEnd(HttpCombinedParser combinedParser) { HttpRequestReponse.IsEndOfMessage = true; }
public void OnChunkReceived(HttpCombinedParser combinedParser) { }
public void OnChunkedLength(HttpCombinedParser combinedParser, int length) { }
public void OnTransferEncodingChunked(HttpCombinedParser combinedParser, bool isChunked) { }
public void OnQueryString(HttpCombinedParser combinedParser, string queryString) { //throw new NotImplementedException(); }
public void OnResponseType(HttpCombinedParser combinedParser) { HttpRequestReponse.MessageType = MessageType.Response; MessageType = MessageType.Response; }
public void OnFragment(HttpCombinedParser parser, string fragment) { HttpRequestReponse.Fragment = fragment; }
public void OnPath(HttpCombinedParser parser, string path) { HttpRequestReponse.Path = path; }
public void OnHeadersEnd(HttpCombinedParser combinedParser) { //throw new NotImplementedException(); }
public void OnMessageBegin(HttpCombinedParser combinedParser) { //throw new NotImplementedException(); }
public void OnBody(HttpCombinedParser combinedParser, ArraySegment <byte> data) { //throw new NotImplementedException(); }