/// <summary> /// Push new data into the parser /// </summary> /// <param name="s"></param> public void Receive(IDataStream s) { lock (contentLock) { while (s.Length > 0) { while (!readingPayload && s.Length > 0) { missing = parser.ParseHeader(s); if (missing <= 0) { var inner = s; if (missing < 0) { var split = s.Length + missing; inner = new StreamSegment(s, 0, split); s = new StreamSegment(s, split); } else { s = EmptyData.Instance; } var ret = parser.Close(inner); parser = new WebSocketMessage.Parser(); onMessageParsed(ret); } else { readingPayload = true; dataBuilder.Append(s); return; } } if (readingPayload) { if (s.Length < missing) { dataBuilder.Append(s); missing -= s.Length; return; } else { dataBuilder.Append(new StreamSegment(s, 0, missing)); s = new StreamSegment(s, missing); missing = 0; readingPayload = false; var bin = dataBuilder.Close(); dataBuilder = new ThresholdedDataBuilder(logger); var msg = parser.Close(bin); parser = new WebSocketMessage.Parser(); onMessageParsed(msg); } } } } }
public HttpData Receive(IDataStream s) { lock (contentLock) { if (useContentData) { contentData.Add(s); } dataBuilder.Append(s); if (state == ParsingState.Header) { try { if (parser.Parse(contentData, isResponse)) { state = ParsingState.Body; try { var code = parser.StatusCode; // header parsing is finished if (LastRequestMethod == HttpRequestMethod.HEAD) { info = new HttpBodyLengthInfo((long)0); } else if (LastRequestMethod == HttpRequestMethod.CONNECT && code > 199 && code < 300) { info = new HttpBodyLengthInfo((long)0); } else { info = parser.GetBodyLengthInfo(!isResponse); } useContentData = info.Type == HttpBodyLengthInfo.LengthType.Chunked; headerLength = parser.HeaderLength; if (contentData.Length - parser.HeaderLength > 0) { var tmpList = new StreamList(); var contentStart = new ByteArray(contentData, parser.HeaderLength); tmpList.Add(contentStart); contentData = tmpList; } else { contentData = new StreamList(); } } catch (BadRequestException) { throw new HttpInvalidMessageException(); } } } catch (HttpHeaderParserException) { throw new HttpInvalidMessageException(); } } if (state == ParsingState.Body) { if (info.Type == HttpBodyLengthInfo.LengthType.Exact && info.Length <= dataBuilder.Length - headerLength) { var resStream = dataBuilder.Close(); return(parser.Create(new StreamSegment(resStream, 0, headerLength), new StreamSegment(resStream, headerLength, info.Length), resStream)); } else if (info.Type == HttpBodyLengthInfo.LengthType.Chunked) { parseChunkedBody(); } } } if (state == ParsingState.CheckingChunedTrailer) { if (contentData.Length >= 2) { // check CRLF bool chunkedEnd = contentData.ReadByte(0) == 13 && contentData.ReadByte(1) == 10; if (chunkedEnd) { contentData = new StreamList(); var resStream = dataBuilder.Close(); return(parser.Create(new StreamSegment(resStream, 0, headerLength), new StreamSegment(resStream, headerLength), resStream)); } else { parser.ParseChunkedTrailer(); state = ParsingState.ParsingChunkedTrailer; } } } if (state == ParsingState.ParsingChunkedTrailer) { if (parser.Parse(contentData, isResponse)) { contentData = new StreamList(); var resStream = dataBuilder.Close(); return(parser.Create(new StreamSegment(resStream, 0, headerLength), new StreamSegment(resStream, headerLength), resStream)); } } return(null); }