From cab3ac952b4217f1f187c8427731aa184a656813 Mon Sep 17 00:00:00 2001 From: Diogo Martins Date: Sat, 14 Feb 2026 17:10:49 +0000 Subject: [PATCH] Fix NGINX impl - POST / --- .../TestCases/Suites/ComplianceSuite.cs | 64 +++++++++++++++++-- src/Servers/NginxServer/echo.js | 10 ++- src/Servers/NginxServer/nginx.conf | 2 +- 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/src/Http11Probe/TestCases/Suites/ComplianceSuite.cs b/src/Http11Probe/TestCases/Suites/ComplianceSuite.cs index fcd9771..fcf42f5 100644 --- a/src/Http11Probe/TestCases/Suites/ComplianceSuite.cs +++ b/src/Http11Probe/TestCases/Suites/ComplianceSuite.cs @@ -1,5 +1,6 @@ using System.Text; using Http11Probe.Client; +using Http11Probe.Response; namespace Http11Probe.TestCases.Suites; @@ -483,9 +484,11 @@ public static IEnumerable GetTestCases() RfcReference = "RFC 9112 §6.2", PayloadFactory = ctx => MakeRequest( $"POST / HTTP/1.1\r\nHost: {ctx.HostHeader}\r\nContent-Length: 5\r\n\r\nhello"), + BehavioralAnalyzer = EchoAnalyzer("hello"), Expected = new ExpectedBehavior { - ExpectedStatus = StatusCodeRange.Range2xx + Description = "2xx + echo", + CustomValidator = EchoValidator("hello") } }; @@ -550,9 +553,11 @@ public static IEnumerable GetTestCases() RfcReference = "RFC 9112 §7.1", PayloadFactory = ctx => MakeRequest( $"POST / HTTP/1.1\r\nHost: {ctx.HostHeader}\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n0\r\n\r\n"), + BehavioralAnalyzer = EchoAnalyzer("hello"), Expected = new ExpectedBehavior { - ExpectedStatus = StatusCodeRange.Range2xx + Description = "2xx + echo", + CustomValidator = EchoValidator("hello") } }; @@ -564,9 +569,11 @@ public static IEnumerable GetTestCases() RfcReference = "RFC 9112 §7.1", PayloadFactory = ctx => MakeRequest( $"POST / HTTP/1.1\r\nHost: {ctx.HostHeader}\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n6\r\n world\r\n0\r\n\r\n"), + BehavioralAnalyzer = EchoAnalyzer("hello world"), Expected = new ExpectedBehavior { - ExpectedStatus = StatusCodeRange.Range2xx + Description = "2xx + echo", + CustomValidator = EchoValidator("hello world") } }; @@ -755,6 +762,7 @@ public static IEnumerable GetTestCases() RfcReference = "RFC 9112 §7.1.1", PayloadFactory = ctx => MakeRequest( $"POST / HTTP/1.1\r\nHost: {ctx.HostHeader}\r\nTransfer-Encoding: chunked\r\n\r\n5;ext=value\r\nhello\r\n0\r\n\r\n"), + BehavioralAnalyzer = EchoAnalyzer("hello"), Expected = new ExpectedBehavior { Description = "2xx preferred; 400 warns", @@ -762,10 +770,15 @@ public static IEnumerable GetTestCases() { if (response is null) return state == ConnectionState.ClosedByServer ? TestVerdict.Warn : TestVerdict.Fail; - if (response.StatusCode is >= 200 and < 300) - return TestVerdict.Pass; if (response.StatusCode == 400) return TestVerdict.Warn; + if (response.StatusCode is >= 200 and < 300) + { + var body = (response.Body ?? "").TrimEnd('\r', '\n'); + if (body == "hello") return TestVerdict.Pass; + if (IsStaticResponse(body) || body.Length == 0) return TestVerdict.Pass; + return TestVerdict.Warn; + } return TestVerdict.Fail; } } @@ -1028,9 +1041,11 @@ public static IEnumerable GetTestCases() RfcReference = "RFC 9112 §7.1.2", PayloadFactory = ctx => MakeRequest( $"POST / HTTP/1.1\r\nHost: {ctx.HostHeader}\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n0\r\nX-Checksum: abc\r\n\r\n"), + BehavioralAnalyzer = EchoAnalyzer("hello"), Expected = new ExpectedBehavior { - ExpectedStatus = StatusCodeRange.Range(200, 299) + Description = "2xx + echo", + CustomValidator = EchoValidator("hello") } }; @@ -1042,9 +1057,11 @@ public static IEnumerable GetTestCases() RfcReference = "RFC 9112 §7.1", PayloadFactory = ctx => MakeRequest( $"POST / HTTP/1.1\r\nHost: {ctx.HostHeader}\r\nTransfer-Encoding: chunked\r\n\r\nA\r\nhelloworld\r\n0\r\n\r\n"), + BehavioralAnalyzer = EchoAnalyzer("helloworld"), Expected = new ExpectedBehavior { - ExpectedStatus = StatusCodeRange.Range(200, 299) + Description = "2xx + echo", + CustomValidator = EchoValidator("helloworld") } }; @@ -1234,5 +1251,38 @@ public static IEnumerable GetTestCases() }; } + // ── Echo verification helpers ────────────────────────────── + + private static bool IsStaticResponse(string body) => body == "OK"; + + private static Func EchoAnalyzer(string expectedBody) + { + return response => + { + if (response is null || response.StatusCode is < 200 or >= 300) return null; + var body = (response.Body ?? "").TrimEnd('\r', '\n'); + if (IsStaticResponse(body)) return "Static response — server does not echo POST body"; + if (body == expectedBody) return "Echoed correctly"; + if (body.Length == 0) return "Empty body"; + return $"Echo mismatch: expected \"{expectedBody}\", got \"{(body.Length > 40 ? body[..40] + "..." : body)}\""; + }; + } + + private static Func EchoValidator(string expectedBody) + { + return (response, state) => + { + if (response is null) + return TestVerdict.Fail; + if (response.StatusCode is < 200 or >= 300) + return TestVerdict.Fail; + var body = (response.Body ?? "").TrimEnd('\r', '\n'); + if (body == expectedBody) return TestVerdict.Pass; + if (IsStaticResponse(body)) return TestVerdict.Pass; + if (body.Length == 0) return TestVerdict.Pass; + return TestVerdict.Warn; + }; + } + private static byte[] MakeRequest(string request) => Encoding.ASCII.GetBytes(request); } diff --git a/src/Servers/NginxServer/echo.js b/src/Servers/NginxServer/echo.js index d984c23..8d1606b 100644 --- a/src/Servers/NginxServer/echo.js +++ b/src/Servers/NginxServer/echo.js @@ -7,4 +7,12 @@ function echo(r) { r.return(200, body); } -export default { echo }; +function handler(r) { + if (r.method === 'POST') { + r.return(200, r.requestText || ''); + } else { + r.return(200, 'OK'); + } +} + +export default { echo, handler }; diff --git a/src/Servers/NginxServer/nginx.conf b/src/Servers/NginxServer/nginx.conf index 2335656..ce836c5 100644 --- a/src/Servers/NginxServer/nginx.conf +++ b/src/Servers/NginxServer/nginx.conf @@ -27,7 +27,7 @@ http { } location / { - return 200 "OK"; + js_content echo.handler; } } }