diff --git a/NewLife.Core/Http/HttpCodec.cs b/NewLife.Core/Http/HttpCodec.cs index f01842a886..c7856c986a 100644 --- a/NewLife.Core/Http/HttpCodec.cs +++ b/NewLife.Core/Http/HttpCodec.cs @@ -138,6 +138,12 @@ public class HttpMessage : IMessage /// 负载数据 public Packet Payload { get; set; } + /// 请求方法 + public String Method { get; set; } + + /// 请求资源 + public String Uri { get; set; } + /// 内容长度 public Int32 ContentLength { get; set; } = -1; @@ -181,11 +187,20 @@ public virtual Boolean ParseHeaders() var pk = Header; if (pk == null || pk.Total == 0) return false; + // 请求方法 GET / HTTP/1.1 var dic = new Dictionary(StringComparer.OrdinalIgnoreCase); var ss = pk.ToStr().Split(Environment.NewLine); - foreach (var item in ss) { - var kv = item.Split(":"); + var kv = ss[0].Split(" "); + if (kv != null && kv.Length >= 3) + { + Method = kv[0].Trim(); + Uri = kv[1].Trim(); + } + } + for (var i = 1; i < ss.Length; i++) + { + var kv = ss[i].Split(":"); if (kv != null && kv.Length >= 2) { dic[kv[0].Trim()] = kv[1].Trim(); @@ -196,8 +211,6 @@ public virtual Boolean ParseHeaders() // 内容长度 if (dic.TryGetValue("Content-Length", out var str)) ContentLength = str.ToInt(); - else - ContentLength = 0; return true; } diff --git a/XUnitTest.Core/Http/HttpCodecTests.cs b/XUnitTest.Core/Http/HttpCodecTests.cs new file mode 100644 index 0000000000..f28d857d02 --- /dev/null +++ b/XUnitTest.Core/Http/HttpCodecTests.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NewLife.Data; +using NewLife.Http; +using Xunit; + +namespace XUnitTest.Http +{ + public class HttpCodecTests + { + [Theory(DisplayName = "读取GET")] + [InlineData("GET /123.html HTTP/1.1\r\nHost: www.newlifex.com\r\n\r\n")] + [InlineData("GET /123.html HTTP/1.1\r\nHost: www.newlifex.com\r\nContent-Length:0\r\n\r\n")] + //[InlineData("GET /123.html\r\nHost: www.newlifex.com\r\n")] + //[InlineData("GET /123.html\r\nHost: www.newlifex.com")] + public void ReadGetMessge(String http) + { + var msg = new HttpMessage(); + var rs = msg.Read(http.GetBytes()); + Assert.True(rs); + + rs = msg.ParseHeaders(); + Assert.True(rs); + + Assert.Equal("GET", msg.Method); + Assert.Equal("/123.html", msg.Uri); + Assert.Equal("www.newlifex.com", msg.Headers["host"]); + } + + [Theory(DisplayName = "读取POST")] + [InlineData("POST /123.ashx HTTP/1.1\r\nHost: www.newlifex.com\r\nContent-Length:9\r\n\r\ncode=abcd")] + [InlineData("POST /123.ashx HTTP/1.1\r\nHost: www.newlifex.com\r\nContent-Length:0\r\n\r\n")] + [InlineData("POST /123.ashx HTTP/1.1\r\nHost: www.newlifex.com\r\n\r\n")] + public void ReadPostMessage(String http) + { + var msg = new HttpMessage(); + var rs = msg.Read(http.GetBytes()); + Assert.True(rs); + + rs = msg.ParseHeaders(); + Assert.True(rs); + + Assert.Equal("POST", msg.Method); + Assert.Equal("/123.ashx", msg.Uri); + Assert.Equal("www.newlifex.com", msg.Headers["host"]); + + var body = msg.Payload; + Assert.NotNull(body); + if (body.Total == 9) + { + var str = body.ToStr(); + Assert.Equal("code=abcd", str); + + Assert.Equal(body.Total, msg.ContentLength); + } + else + { + if (msg.Headers.ContainsKey("Content-Length")) + Assert.Equal(body.Total, msg.ContentLength); + else + Assert.Equal(-1, msg.ContentLength); + } + } + + [Theory(DisplayName = "写入编码")] + [InlineData("GET /123.html HTTP/1.1\r\nHost: www.newlifex.com\r\n\r\n")] + [InlineData("POST /123.ashx HTTP/1.1\r\nHost: www.newlifex.com\r\nContent-Length:9\r\n\r\ncode=abcd")] + public void WriteCodec(String http) + { + var pk = http.GetBytes(); + var msg = new HttpMessage(); + var rs = msg.Read(pk); + Assert.True(rs); + + var codec = new HttpCodec(); + var rm = codec.Write(null, msg) as Packet; + Assert.NotNull(rm); + Assert.Equal(http, rm.ToStr()); + } + } +}