Files
flora-kit/flora/http.go
0x1024 fcf771e160 v0.2.5
- windows 透明代理
2017-07-02 19:21:59 +08:00

80 lines
1.8 KiB
Go

package flora
import (
"net"
"io"
"net/http"
"bufio"
"bytes"
"net/http/httputil"
)
// local socks server connect
func httpProxyConnect(conn net.Conn, first byte) (addr string, hostType int, raw []byte, err error) {
var (
HTTP_200 = []byte("HTTP/1.1 200 Connection Established\r\n\r\n")
host string
port string
)
buf := make([]byte, 4096)
buf[0] = first
io.ReadAtLeast(conn, buf[1:], 1)
req, err := http.ReadRequest(bufio.NewReader(bytes.NewReader(buf)))
if nil != err {
return
}
host, port, err = net.SplitHostPort(req.Host)
if nil != err {
host = req.Host
port = req.URL.Port()
}
scheme := req.URL.Scheme
if "" == port {
if scheme == "http" {
port = "80"
} else {
port = "443"
}
}
addr = net.JoinHostPort(host, port)
method := req.Method
hostType = getRequestType(addr)
switch method {
case http.MethodConnect:
_, err = conn.Write(HTTP_200)
default:
removeHeaders(req)
raw, err = httputil.DumpRequest(req, true)
}
return
}
func getRequestType(addr string) int {
host,_,_ := net.SplitHostPort(addr)
ip := net.ParseIP(host)
if nil != ip {
return typeIPv4
}
return typeDm
}
func removeHeaders(req *http.Request) {
req.RequestURI = ""
req.Header.Del("Accept-Encoding")
// curl can add that, see
// https://jdebp.eu./FGA/web-proxy-connection-header.html
req.Header.Del("Proxy-Connection")
req.Header.Del("Proxy-Authenticate")
req.Header.Del("Proxy-Authorization")
//req.Header.Del("Referer")
// Connection, Authenticate and Authorization are single hop Header:
// http://www.w3.org/Protocols/rfc2616/rfc2616.txt
// 14.10 Connection
// The Connection general-header field allows the sender to specify
// options that are desired for that particular connection and MUST NOT
// be communicated by proxies over further connections.
req.Header.Del("Connection")
}