public void TestValidPartialValueResponse() { var header1 = "HTTP/1.1 200 OK\r\n" + "Date: Mon, 27 Jul 2009 12:28:53 GMT\r\n" + "Server: Apache\r\n" + "Last-Modified: Wed, 22 Jul 2"; var header2 = header1 + "009 19:15:56 GMT\r\n" + "ETag: \"34aa387-d-1568eb00\"\r\n" + "Accept-Ranges: bytes\r\n" + "Content-Length: 0\r\n" + "Vary: Accept-Encoding\r\n" + "Content-Type: text/plain\r\n\r\n"; var parser = new HttpHeaderParser(); var stream = new ByteArray(ASCIIEncoding.ASCII.GetBytes(header1)); parser.Parse(stream, true); Assert.Equal("Mon, 27 Jul 2009 12:28:53 GMT", parser.GetHeader("Date")); Assert.Equal("Apache", parser.GetHeader("Server")); Assert.Null(parser.GetHeader("Last-Modi")); Assert.Null(parser.GetHeader("Last-Modified")); stream = new ByteArray(ASCIIEncoding.ASCII.GetBytes(header2)); parser.Parse(stream, true); Assert.Equal("Apache", parser.GetHeader("Server")); Assert.Equal("Wed, 22 Jul 2009 19:15:56 GMT", parser.GetHeader("Last-Modified")); Assert.Equal("\"34aa387-d-1568eb00\"", parser.GetHeader("ETag")); var data = parser.Create(stream, EmptyData.Instance); }
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); }