Clash.Meta/listener/http/utils.go

81 lines
2.0 KiB
Go
Raw Normal View History

2021-06-15 17:13:40 +08:00
package http
import (
"encoding/base64"
"errors"
"net"
"net/http"
"strings"
)
// removeHopByHopHeaders remove Proxy-* headers
func removeProxyHeaders(header http.Header) {
header.Del("Proxy-Connection")
header.Del("Proxy-Authenticate")
header.Del("Proxy-Authorization")
}
// removeHopByHopHeaders remove hop-by-hop header
func removeHopByHopHeaders(header http.Header) {
2021-06-15 17:13:40 +08:00
// Strip hop-by-hop header based on RFC:
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
// https://www.mnot.net/blog/2011/07/11/what_proxies_must_do
removeProxyHeaders(header)
2021-06-15 17:13:40 +08:00
header.Del("TE")
header.Del("Trailers")
header.Del("Transfer-Encoding")
header.Del("Upgrade")
connections := header.Get("Connection")
header.Del("Connection")
if len(connections) == 0 {
return
}
for _, h := range strings.Split(connections, ",") {
header.Del(strings.TrimSpace(h))
}
}
// removeExtraHTTPHostPort remove extra host port (example.com:80 --> example.com)
2021-06-15 17:13:40 +08:00
// It resolves the behavior of some HTTP servers that do not handle host:80 (e.g. baidu.com)
func removeExtraHTTPHostPort(req *http.Request) {
2021-06-15 17:13:40 +08:00
host := req.Host
if host == "" {
host = req.URL.Host
}
2022-04-11 06:28:42 +08:00
if pHost, port, err := net.SplitHostPort(host); err == nil && (port == "80" || port == "443") {
2021-06-15 17:13:40 +08:00
host = pHost
}
req.Host = host
req.URL.Host = host
}
// parseBasicProxyAuthorization parse header Proxy-Authorization and return base64-encoded credential
func parseBasicProxyAuthorization(request *http.Request) string {
2021-06-15 17:13:40 +08:00
value := request.Header.Get("Proxy-Authorization")
if !strings.HasPrefix(value, "Basic ") {
return ""
}
return value[6:] // value[len("Basic "):]
}
// decodeBasicProxyAuthorization decode base64-encoded credential
func decodeBasicProxyAuthorization(credential string) (string, string, error) {
2021-06-15 17:13:40 +08:00
plain, err := base64.StdEncoding.DecodeString(credential)
if err != nil {
return "", "", err
}
2022-03-16 12:10:13 +08:00
user, pass, found := strings.Cut(string(plain), ":")
if !found {
2021-06-15 17:13:40 +08:00
return "", "", errors.New("invalid login")
}
2022-03-16 12:10:13 +08:00
return user, pass, nil
2021-06-15 17:13:40 +08:00
}