package dispatcher import ( "testing" ) func TestClassify(t *testing.T) { tests := []struct { name string data []byte want Protocol }{ {"empty", nil, ProtoUnknown}, {"empty slice", []byte{}, ProtoUnknown}, {"GET request", []byte("GET / HTTP/1.1\r\n"), ProtoHTTP1}, {"POST request", []byte("POST /api HTTP/1.1\r\n"), ProtoHTTP1}, {"PUT request", []byte("PUT /resource HTTP/1.1\r\n"), ProtoHTTP1}, {"DELETE request", []byte("DELETE /item HTTP/1.1\r\n"), ProtoHTTP1}, {"HEAD request", []byte("HEAD / HTTP/1.1\r\n"), ProtoHTTP1}, {"OPTIONS request", []byte("OPTIONS * HTTP/1.1\r\n"), ProtoHTTP1}, {"PATCH request", []byte("PATCH /data HTTP/1.1\r\n"), ProtoHTTP1}, {"CONNECT request", []byte("CONNECT host:443 HTTP/1.1\r\n"), ProtoHTTP1}, {"TRACE request", []byte("TRACE / HTTP/1.1\r\n"), ProtoHTTP1}, {"HTTP/2 preface", []byte("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"), ProtoHTTP2}, {"HTTP/2 with frames", append([]byte("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"), []byte{0, 0, 0, 4, 0, 0, 0, 0, 0}...), ProtoHTTP2}, {"partial H2 preface", []byte("PRI * HTTP"), ProtoHTTP2}, {"garbage", []byte{0x15, 0x03, 0x01, 0x00}, ProtoUnknown}, {"TLS record", []byte{0x16, 0x03, 0x01, 0x00, 0x80}, ProtoUnknown}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := Classify(tt.data) if got != tt.want { t.Errorf("Classify(%q) = %v, want %v", tt.data[:min(len(tt.data), 30)], got, tt.want) } }) } } func TestClassify_PartialH2Preface(t *testing.T) { // A fragment that is a prefix of the H2 magic but shorter fragment := []byte("PRI * HTTP/2.0\r\n\r\nS") got := Classify(fragment) if got != ProtoHTTP2 { t.Errorf("Classify(partial H2 preface) = %v, want ProtoHTTP2", got) } } func TestMinInt(t *testing.T) { tests := []struct { a, b, want int }{ {1, 2, 1}, {5, 3, 3}, {0, 0, 0}, {-1, 1, -1}, } for _, tt := range tests { got := minInt(tt.a, tt.b) if got != tt.want { t.Errorf("minInt(%d, %d) = %d, want %d", tt.a, tt.b, got, tt.want) } } }