mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-30 09:18:34 +00:00
v1.0.0
This commit is contained in:
parent
47d23e9972
commit
c7f7c08ead
711 changed files with 82154 additions and 2 deletions
94
common/protocol/http/sniff.go
Normal file
94
common/protocol/http/sniff.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/xtls/xray-core/v1/common"
|
||||
"github.com/xtls/xray-core/v1/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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue