mirror of https://github.com/XTLS/Xray-core
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
1.6 KiB
94 lines
1.6 KiB
package http |
|
|
|
import ( |
|
"bytes" |
|
"errors" |
|
"strings" |
|
|
|
"github.com/xtls/xray-core/common" |
|
"github.com/xtls/xray-core/common/net" |
|
) |
|
|
|
type version byte |
|
|
|
const ( |
|
HTTP1 version = iota |
|
HTTP2 |
|
) |
|
|
|
type SniffHeader struct { |
|
version version |
|
host string |
|
} |
|
|
|
func (h *SniffHeader) Protocol() string { |
|
switch h.version { |
|
case HTTP1: |
|
return "http1" |
|
case HTTP2: |
|
return "http2" |
|
default: |
|
return "unknown" |
|
} |
|
} |
|
|
|
func (h *SniffHeader) Domain() string { |
|
return h.host |
|
} |
|
|
|
var ( |
|
methods = [...]string{"get", "post", "head", "put", "delete", "options", "connect"} |
|
|
|
errNotHTTPMethod = errors.New("not an HTTP method") |
|
) |
|
|
|
func beginWithHTTPMethod(b []byte) error { |
|
for _, m := range &methods { |
|
if len(b) >= len(m) && strings.EqualFold(string(b[:len(m)]), m) { |
|
return nil |
|
} |
|
|
|
if len(b) < len(m) { |
|
return common.ErrNoClue |
|
} |
|
} |
|
|
|
return errNotHTTPMethod |
|
} |
|
|
|
func SniffHTTP(b []byte) (*SniffHeader, error) { |
|
if err := beginWithHTTPMethod(b); err != nil { |
|
return nil, err |
|
} |
|
|
|
sh := &SniffHeader{ |
|
version: HTTP1, |
|
} |
|
|
|
headers := bytes.Split(b, []byte{'\n'}) |
|
for i := 1; i < len(headers); i++ { |
|
header := headers[i] |
|
if len(header) == 0 { |
|
break |
|
} |
|
parts := bytes.SplitN(header, []byte{':'}, 2) |
|
if len(parts) != 2 { |
|
continue |
|
} |
|
key := strings.ToLower(string(parts[0])) |
|
if key == "host" { |
|
rawHost := strings.ToLower(string(bytes.TrimSpace(parts[1]))) |
|
dest, err := ParseHost(rawHost, net.Port(80)) |
|
if err != nil { |
|
return nil, err |
|
} |
|
sh.host = dest.Address.String() |
|
} |
|
} |
|
|
|
if len(sh.host) > 0 { |
|
return sh, nil |
|
} |
|
|
|
return nil, common.ErrNoClue |
|
}
|
|
|