Skip to content

Commit 9c51787

Browse files
committed
Improve Cli
1 parent ff167a6 commit 9c51787

3 files changed

Lines changed: 133 additions & 4 deletions

File tree

.github/workflows/pages.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ on:
1010

1111
concurrency:
1212
group: pages
13-
cancel-in-progress: false
13+
cancel-in-progress: true
1414

1515
jobs:
1616
build:

src/Http11Probe.Cli/Reporting/ConsoleReporter.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ public static class ConsoleReporter
88
public static void PrintHeader()
99
{
1010
Console.WriteLine();
11-
Console.WriteLine(" {0,-35} {1,-10} {2,-6} {3}", "Test ID", "Verdict", "Status", "Details");
12-
Console.WriteLine(" " + new string('─', 80));
11+
Console.WriteLine(" {0,-35} {1,-10} {2,-14} {3,-6} {4}", "Test ID", "Verdict", "Expected", "Status", "Details");
12+
Console.WriteLine(" " + new string('─', 95));
1313
}
1414

1515
public static void PrintRow(TestResult result)
@@ -37,11 +37,26 @@ public static void PrintRow(TestResult result)
3737
if (detail.Length > 30)
3838
detail = detail[..30] + "...";
3939

40+
var expected = result.TestCase.Expected.GetDescription();
41+
if (expected.Length > 14)
42+
expected = expected[..14];
43+
44+
var docsUrl = DocsUrlMap.GetUrl(result.TestCase.Id);
45+
4046
var prev = Console.ForegroundColor;
4147
Console.ForegroundColor = color;
4248
Console.Write(" {0,-35} {1,-10}", result.TestCase.Id, symbol);
4349
Console.ForegroundColor = prev;
44-
Console.WriteLine(" {0,-6} {1}", statusStr, detail);
50+
Console.Write(" {0,-14} {1,-6} {2}", expected, statusStr, detail);
51+
52+
if (docsUrl is not null)
53+
{
54+
Console.ForegroundColor = ConsoleColor.DarkGray;
55+
Console.Write($" {docsUrl}");
56+
Console.ForegroundColor = prev;
57+
}
58+
59+
Console.WriteLine();
4560
}
4661

4762
public static void PrintSummary(TestRunReport report)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
namespace Http11Probe.Cli.Reporting;
2+
3+
internal static class DocsUrlMap
4+
{
5+
private const string BaseUrl = "https://mda2av.github.io/Http11Probe/docs/";
6+
7+
private static readonly Dictionary<string, string> ComplianceSlugs = new(StringComparer.OrdinalIgnoreCase)
8+
{
9+
// body
10+
["COMP-CHUNKED-BODY"] = "body/chunked-body",
11+
["COMP-CHUNKED-EMPTY"] = "body/chunked-empty",
12+
["COMP-CHUNKED-EXTENSION"] = "body/chunked-extension",
13+
["COMP-CHUNKED-HEX-UPPERCASE"] = "body/chunked-hex-uppercase",
14+
["COMP-CHUNKED-MULTI"] = "body/chunked-multi",
15+
["COMP-CHUNKED-NO-FINAL"] = "body/chunked-no-final",
16+
["COMP-CHUNKED-TRAILER-VALID"] = "body/chunked-trailer-valid",
17+
["COMP-GET-WITH-CL-BODY"] = "body/get-with-cl-body",
18+
["COMP-POST-CL-BODY"] = "body/post-cl-body",
19+
["COMP-POST-CL-UNDERSEND"] = "body/post-cl-undersend",
20+
["COMP-POST-CL-ZERO"] = "body/post-cl-zero",
21+
["COMP-POST-NO-CL-NO-TE"] = "body/post-no-cl-no-te",
22+
23+
// content-length
24+
["RFC9112-6.1-CL-NON-NUMERIC"] = "content-length/cl-non-numeric",
25+
["RFC9112-6.1-CL-PLUS-SIGN"] = "content-length/cl-plus-sign",
26+
27+
// headers
28+
["COMP-CONNECTION-CLOSE"] = "headers/connection-close",
29+
["RFC9112-5-EMPTY-HEADER-NAME"] = "headers/empty-header-name",
30+
["COMP-EXPECT-UNKNOWN"] = "headers/expect-unknown",
31+
["RFC9112-5-HEADER-NO-COLON"] = "headers/header-no-colon",
32+
["COMP-HTTP10-DEFAULT-CLOSE"] = "headers/http10-default-close",
33+
["RFC9112-5-INVALID-HEADER-NAME"] = "headers/invalid-header-name",
34+
["RFC9112-5.1-OBS-FOLD"] = "headers/obs-fold",
35+
["RFC9110-5.6.2-SP-BEFORE-COLON"] = "headers/sp-before-colon",
36+
["COMP-WHITESPACE-BEFORE-HEADERS"] = "headers/whitespace-before-headers",
37+
38+
// host-header
39+
["RFC9110-5.4-DUPLICATE-HOST"] = "host-header/duplicate-host",
40+
["COMP-DUPLICATE-HOST-SAME"] = "host-header/duplicate-host-same",
41+
["COMP-HOST-EMPTY-VALUE"] = "host-header/host-empty-value",
42+
["COMP-HOST-WITH-PATH"] = "host-header/host-with-path",
43+
["COMP-HOST-WITH-USERINFO"] = "host-header/host-with-userinfo",
44+
["COMP-HTTP10-NO-HOST"] = "host-header/http10-no-host",
45+
["RFC9112-7.1-MISSING-HOST"] = "host-header/missing-host",
46+
47+
// line-endings
48+
["RFC9112-2.2-BARE-LF-HEADER"] = "line-endings/bare-lf-header",
49+
["RFC9112-2.2-BARE-LF-REQUEST-LINE"] = "line-endings/bare-lf-request-line",
50+
["RFC9112-3-CR-ONLY-LINE-ENDING"] = "line-endings/cr-only-line-ending",
51+
["COMP-LEADING-CRLF"] = "line-endings/leading-crlf",
52+
53+
// request-line
54+
["COMP-ABSOLUTE-FORM"] = "request-line/absolute-form",
55+
["COMP-ASTERISK-WITH-GET"] = "request-line/asterisk-with-get",
56+
["COMP-CONNECT-EMPTY-PORT"] = "request-line/connect-empty-port",
57+
["COMP-CONNECT-ORIGIN-FORM"] = "request-line/connect-origin-form",
58+
["RFC9112-3.2-FRAGMENT-IN-TARGET"] = "request-line/fragment-in-target",
59+
["RFC9112-2.3-HTTP09-REQUEST"] = "request-line/http09-request",
60+
["COMP-HTTP12-VERSION"] = "request-line/http12-version",
61+
["RFC9112-2.3-INVALID-VERSION"] = "request-line/invalid-version",
62+
["COMP-METHOD-CASE"] = "request-line/method-case",
63+
["COMP-METHOD-CONNECT"] = "request-line/method-connect",
64+
["COMP-METHOD-CONNECT-NO-PORT"] = "request-line/method-connect-no-port",
65+
["COMP-METHOD-TRACE"] = "request-line/method-trace",
66+
["RFC9112-3-MISSING-TARGET"] = "request-line/missing-target",
67+
["RFC9112-3-MULTI-SP-REQUEST-LINE"] = "request-line/multi-sp-request-line",
68+
["COMP-OPTIONS-STAR"] = "request-line/options-star",
69+
["COMP-REQUEST-LINE-TAB"] = "request-line/request-line-tab",
70+
["COMP-TRACE-WITH-BODY"] = "request-line/trace-with-body",
71+
["COMP-UNKNOWN-TE-501"] = "request-line/unknown-te-501",
72+
["COMP-VERSION-LEADING-ZEROS"] = "request-line/version-leading-zeros",
73+
["COMP-VERSION-MISSING-MINOR"] = "request-line/version-missing-minor",
74+
["COMP-VERSION-WHITESPACE"] = "request-line/version-whitespace",
75+
76+
// upgrade
77+
["COMP-UPGRADE-INVALID-VER"] = "upgrade/upgrade-invalid-ver",
78+
["COMP-UPGRADE-MISSING-CONN"] = "upgrade/upgrade-missing-conn",
79+
["COMP-UPGRADE-POST"] = "upgrade/upgrade-post",
80+
["COMP-UPGRADE-UNKNOWN"] = "upgrade/upgrade-unknown",
81+
};
82+
83+
// Special cases where the doc filename doesn't match the ID suffix
84+
private static readonly Dictionary<string, string> SpecialSlugs = new(StringComparer.OrdinalIgnoreCase)
85+
{
86+
["MAL-CHUNK-EXT-64K"] = "malformed-input/chunk-extension-long",
87+
["SMUG-TRANSFER_ENCODING"] = "smuggling/transfer-encoding-underscore",
88+
};
89+
90+
public static string? GetUrl(string testId)
91+
{
92+
if (SpecialSlugs.TryGetValue(testId, out var special))
93+
return BaseUrl + special;
94+
95+
if (ComplianceSlugs.TryGetValue(testId, out var slug))
96+
return BaseUrl + slug;
97+
98+
// SMUG-* → smuggling/{suffix}
99+
if (testId.StartsWith("SMUG-", StringComparison.OrdinalIgnoreCase))
100+
{
101+
var suffix = testId[5..].ToLowerInvariant();
102+
return BaseUrl + "smuggling/" + suffix;
103+
}
104+
105+
// MAL-* → malformed-input/{suffix}
106+
if (testId.StartsWith("MAL-", StringComparison.OrdinalIgnoreCase))
107+
{
108+
var suffix = testId[4..].ToLowerInvariant();
109+
return BaseUrl + "malformed-input/" + suffix;
110+
}
111+
112+
return null;
113+
}
114+
}

0 commit comments

Comments
 (0)