package protocol import ( "errors" "testing" ) func TestDetectHTTPRequest(t *testing.T) { atomicFormats.Store([]format{{Client, "", detectHTTPRequest}}) // A valid HTTP/1.0 GET request http10Request := []byte("GET /old-page.html HTTP/1.0\r\nUser-Agent: NCSA_Mosaic/1.0\r\n\r\n") // A valid HTTP/1.1 GET request getRequest := []byte("GET /resource/item?id=123 HTTP/1.1\r\nHost: example.com\r\n\r\n") // An invalid HTTP request sshBanner := []byte("SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4\r\n") defer func() { Strict = false }() for _, strict := range []bool{false, true} { Strict = strict name := "loose" if strict { name = "strict" } t.Run(name, func(t *testing.T) { t.Run("HTTP/1.0 GET", func(t *testing.T) { p, c, err := Detect(Client, http10Request, 1234, 80) if err != nil { t.Fatal(err) return } t.Logf("detected %s version %s confidence %g%%", p.Name, p.Version, c*100) if p.Name != ProtocolHTTP { t.Fatalf("expected http protocol, got %s", p.Name) return } }) t.Run("HTTP/1.1 GET", func(t *testing.T) { p, c, err := Detect(Client, getRequest, 1234, 80) if err != nil { t.Fatal(err) return } t.Logf("detected %s version %s confidence %g%%", p.Name, p.Version, c*100) if p.Name != ProtocolHTTP { t.Fatalf("expected http protocol, got %s", p.Name) return } }) t.Run("Invalid SSH", func(t *testing.T) { _, _, err := Detect(Server, sshBanner, 1234, 22) if !errors.Is(err, ErrUnknown) { t.Fatalf("expected unknown format, got error %T: %q", err, err) } else { t.Logf("error %q, as expected", err) } }) }) } } func TestDetectHTTPResponse(t *testing.T) { atomicFormats.Store([]format{{Server, "HTTP/?.? ", detectHTTPResponse}}) // A valid HTTP/1.0 403 Forbidden response http10Response := []byte("HTTP/1.0 403 Forbidden\r\nServer: CERN/3.0\r\n\r\n") // A valid HTTP/1.1 200 OK response responseOK := []byte("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n...") // A valid HTTP/1.1 404 Not Found response responseNotFound := []byte("HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n") // An invalid HTTP GET request getRequest := []byte("GET /resource/item?id=123 HTTP/1.1\r\nHost: example.com\r\n\r\n") // An invalid banner (SSH) sshBanner := []byte("SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.4\r\n") defer func() { Strict = false }() for _, strict := range []bool{false, true} { Strict = strict name := "loose" if strict { name = "strict" } t.Run(name, func(t *testing.T) { t.Run("HTTP/1.0 403", func(t *testing.T) { p, c, err := Detect(Server, http10Response, 80, 1234) if err != nil { t.Fatal(err) return } t.Logf("detected %s version %s confidence %g%%", p.Name, p.Version, c*100) if p.Name != ProtocolHTTP { t.Fatalf("expected http protocol, got %s", p.Name) return } }) t.Run("HTTP/1.1 200", func(t *testing.T) { p, c, err := Detect(Server, responseOK, 80, 1234) if err != nil { t.Fatal(err) return } t.Logf("detected %s version %s confidence %g%%", p.Name, p.Version, c*100) if p.Name != ProtocolHTTP { t.Fatalf("expected http protocol, got %s", p.Name) return } }) t.Run("HTTP/1.1 404", func(t *testing.T) { p, c, err := Detect(Server, responseNotFound, 80, 1234) if err != nil { t.Fatal(err) return } t.Logf("detected %s version %s confidence %g%%", p.Name, p.Version, c*100) if p.Name != ProtocolHTTP { t.Fatalf("expected http protocol, got %s", p.Name) return } }) t.Run("Invalid HTTP/1.1 GET", func(t *testing.T) { _, _, err := Detect(Server, getRequest, 1234, 80) if !errors.Is(err, ErrUnknown) { t.Fatalf("expected unknown format, got error %T: %q", err, err) } else { t.Logf("error %q, as expected", err) } }) t.Run("Invalid SSH", func(t *testing.T) { _, _, err := Detect(Server, sshBanner, 22, 1234) if !errors.Is(err, ErrUnknown) { t.Fatalf("expected unknown format, got error %T: %q", err, err) } else { t.Logf("error %q, as expected", err) } }) }) } }