private static HttpRequestDatagram.ParseInfo Parse(byte[] buffer, int offset, int length) { HttpParser httpParser = new HttpParser(buffer, offset, length); string token; string uri; HttpVersion version; httpParser.Token(out token).Space().RequestUri(out uri).Space().Version(out version).CarriageReturnLineFeed(); HttpRequestDatagram.ParseInfo parseInfo1 = new HttpRequestDatagram.ParseInfo(); parseInfo1.Length = length; parseInfo1.Version = version; parseInfo1.Method = token == null ? (HttpRequestMethod)null : new HttpRequestMethod(token); parseInfo1.Uri = uri; HttpRequestDatagram.ParseInfo parseInfo2 = parseInfo1; if (!httpParser.Success) { return(parseInfo2); } int num1 = httpParser.Offset - offset; int? endOffset; HttpHeader header = new HttpHeader((IEnumerable <KeyValuePair <string, IEnumerable <byte> > >)HttpDatagram.GetHeaderFields(out endOffset, buffer, offset + num1, length - num1)); parseInfo2.Header = header; if (!endOffset.HasValue) { return(parseInfo2); } int num2 = endOffset.Value - offset - num1; Datagram datagram = HttpDatagram.ParseBody(buffer, offset + num1 + num2, length - num1 - num2, HttpRequestDatagram.IsBodyPossible(header), header); parseInfo2.Body = datagram; parseInfo2.Length = num1 + num2 + datagram.Length; return(parseInfo2); }
private static Datagram ParseChunkedBody(byte[] buffer, int offset, int length) { List <Datagram> list = new List <Datagram>(); HttpParser httpParser = new HttpParser(buffer, offset, length); uint? number; while (httpParser.HexadecimalNumber(out number).SkipChunkExtensions().CarriageReturnLineFeed().Success) { uint num1 = number.Value; if ((int)num1 == 0) { int?endOffset; HttpDatagram.GetHeaderFields(out endOffset, buffer, httpParser.Offset, offset + length - httpParser.Offset); if (endOffset.HasValue) { httpParser.Skip(endOffset.Value - httpParser.Offset); break; } break; } int num2 = (int)Math.Min((long)num1, (long)(offset + length - httpParser.Offset)); list.Add(new Datagram(buffer, httpParser.Offset, num2)); httpParser.Skip(num2); httpParser.CarriageReturnLineFeed(); } byte[] buffer1 = new byte[Enumerable.Sum <Datagram>((IEnumerable <Datagram>)list, (Func <Datagram, int>)(datagram => datagram.Length))]; int offset1 = 0; foreach (Datagram datagram in list) { datagram.Write(buffer1, offset1); offset1 += datagram.Length; } return(new Datagram(buffer, offset, httpParser.Offset - offset)); }
private static HttpResponseDatagram.ParseInfo Parse(byte[] buffer, int offset, int length) { HttpParser httpParser = new HttpParser(buffer, offset, length); HttpVersion version; uint? number; Datagram reasonPhrase; httpParser.Version(out version).Space().DecimalNumber(3, out number).Space().SkipSpaces().ReasonPhrase(out reasonPhrase).CarriageReturnLineFeed(); HttpResponseDatagram.ParseInfo parseInfo1 = new HttpResponseDatagram.ParseInfo(); parseInfo1.Length = length; parseInfo1.Version = version; parseInfo1.StatusCode = number; parseInfo1.ReasonPhrase = reasonPhrase; HttpResponseDatagram.ParseInfo parseInfo2 = parseInfo1; if (!httpParser.Success) { return(parseInfo2); } int num1 = httpParser.Offset - offset; int? endOffset; HttpHeader header = new HttpHeader((IEnumerable <KeyValuePair <string, IEnumerable <byte> > >)HttpDatagram.GetHeaderFields(out endOffset, buffer, offset + num1, length - num1)); parseInfo2.Header = header; if (!endOffset.HasValue) { return(parseInfo2); } int num2 = endOffset.Value - offset - num1; Datagram datagram = HttpDatagram.ParseBody(buffer, offset + num1 + num2, length - num1 - num2, HttpResponseDatagram.IsBodyPossible(number.Value), header); parseInfo2.Body = datagram; parseInfo2.Length = num1 + num2 + datagram.Length; return(parseInfo2); }
internal static Datagram ParseBody(byte[] buffer, int offset, int length, bool isBodyPossible, HttpHeader header) { if (!isBodyPossible) { return(Datagram.Empty); } HttpTransferEncodingField transferEncoding = header.TransferEncoding; if (transferEncoding != null && transferEncoding.TransferCodings != null && Enumerable.Any <string>((IEnumerable <string>)transferEncoding.TransferCodings, (Func <string, bool>)(coding => coding != "identity"))) { return(HttpDatagram.ParseChunkedBody(buffer, offset, length)); } HttpContentLengthField contentLength1 = header.ContentLength; if (contentLength1 != null) { uint?contentLength2 = contentLength1.ContentLength; if (contentLength2.HasValue) { return(new Datagram(buffer, offset, Math.Min((int)contentLength2.Value, length))); } } HttpContentTypeField contentType = header.ContentType; if (contentType != null && contentType.MediaType == "multipart" && contentType.MediaSubtype == "byteranges") { string str = contentType.Parameters["boundary"]; if (str != null) { byte[] bytes = Encoding.ASCII.GetBytes(string.Format((IFormatProvider)CultureInfo.InvariantCulture, "\r\n--{0}--", new object[1] { (object)str })); int num = ByteArrayExtensions.Find(buffer, offset, length, bytes) + bytes.Length; return(new Datagram(buffer, offset, Math.Min(num - offset, length))); } } return(new Datagram(buffer, offset, length)); }
private static bool IsBadHttp(HttpDatagram httpDatagram) { if (httpDatagram.IsResponse) { HttpResponseDatagram httpResponseDatagram = (HttpResponseDatagram)httpDatagram; if (httpResponseDatagram.StatusCode == null) { Assert.IsNull(httpResponseDatagram.Header); return true; } } else { HttpRequestDatagram httpRequestDatagram = (HttpRequestDatagram)httpDatagram; if (httpRequestDatagram.Version == null) return true; } return false; }
private static void CompareHttpFirstLine(XElement httpFirstLineElement, HttpDatagram httpDatagram) { foreach (var field in httpFirstLineElement.Fields()) { switch (field.Name()) { case "http.request.method": field.AssertNoFields(); Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest"); field.AssertShow(((HttpRequestDatagram)httpDatagram).Method.Method); break; case "http.request.uri": field.AssertNoFields(); Assert.IsTrue(httpDatagram.IsRequest, field.Name() + " IsRequest"); // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10681 is fixed. // field.AssertShow(((HttpRequestDatagram)httpDatagram).Uri.ToWiresharkLiteral()); break; case "http.request.version": field.AssertNoFields(); if (httpDatagram.Version == null) { if (field.Show() != string.Empty) Assert.IsTrue(field.Show().Contains(" ") || field.Show().Length < 8); } else field.AssertShow(httpDatagram.Version.ToString()); break; case "http.response.code": field.AssertNoFields(); Assert.IsTrue(httpDatagram.IsResponse, field.Name() + " IsResponse"); field.AssertShowDecimal(IsBadHttp(httpDatagram) ? 0 : ((HttpResponseDatagram)httpDatagram).StatusCode.Value); break; case "http.response.phrase": field.AssertNoFields(); Datagram reasonPhrase = ((HttpResponseDatagram)httpDatagram).ReasonPhrase; if (reasonPhrase == null) Assert.IsTrue(IsBadHttp(httpDatagram)); else field.AssertValue(reasonPhrase); break; case "_ws.expert": break; default: throw new InvalidOperationException("Invalid HTTP first line field " + field.Name()); } } }