From 1950d37d14eaecc27c5d1fb5edc7ed9a75de8edf Mon Sep 17 00:00:00 2001 From: mzz2017 <2017@duck.com> Date: Sun, 12 Mar 2023 11:32:23 +0800 Subject: [PATCH] optimize: refine http sniffer to adapt to non-standard http request header --- component/sniffing/http.go | 39 ++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/component/sniffing/http.go b/component/sniffing/http.go index 93d0f80..08395fa 100644 --- a/component/sniffing/http.go +++ b/component/sniffing/http.go @@ -6,7 +6,9 @@ package sniffing import ( + "bufio" "bytes" + "strings" "unicode" ) @@ -34,15 +36,32 @@ func (s *Sniffer) SniffHttp() (d string, err error) { // Now we assume it is an HTTP packet. We should not return NotApplicableError after here. // Search Host. - search = s.buf - prefix := []byte("Host: ") - _, afterHostKey, found := bytes.Cut(search, prefix) - if !found { - return "", NotFoundError + scanner := bufio.NewScanner(bytes.NewReader(s.buf)) + // \r\n + scanner.Split(func(data []byte, atEOF bool) (advance int, token []byte, err error) { + if atEOF && len(data) == 0 { + return 0, nil, nil + } + if i := bytes.Index(data, []byte("\r\n")); i >= 0 { + // We have a full newline-terminated line. + return i + 2, data[0:i], nil + } + // If we're at EOF, we have a final, non-terminated line. Return it. + if atEOF { + return len(data), data, nil + } + // Request more data. + return 0, nil, nil + }) + for scanner.Scan() && len(scanner.Bytes()) > 0 { + key, value, found := bytes.Cut(scanner.Bytes(), []byte{':'}) + if !found { + // Bad key value. + continue + } + if strings.EqualFold(string(key), "host") { + return strings.TrimSpace(string(value)), nil + } } - host, _, found := bytes.Cut(afterHostKey, []byte("\r\n")) - if !found { - return "", NotFoundError - } - return string(host), nil + return "", NotFoundError }