diff --git a/dialer.go b/dialer.go index e3d7d91..4c17b32 100644 --- a/dialer.go +++ b/dialer.go @@ -43,7 +43,7 @@ func DialerFromURL(s string, cDialer Dialer) (Dialer, error) { switch u.Scheme { case "http": - return NewHTTP(addr, user, pass, cDialer, nil) + return NewHTTP(addr, user, pass, "", cDialer, nil) case "socks5": return NewSOCKS5(addr, user, pass, cDialer, nil) case "ss": diff --git a/http.go b/http.go index 54e984a..a129c16 100644 --- a/http.go +++ b/http.go @@ -24,15 +24,27 @@ type HTTP struct { user string password string + xff bool + + selfip string } // NewHTTP returns a http proxy. -func NewHTTP(addr, user, pass string, cDialer Dialer, sDialer Dialer) (*HTTP, error) { +func NewHTTP(addr, user, pass, rawQuery string, cDialer Dialer, sDialer Dialer) (*HTTP, error) { s := &HTTP{ Forwarder: NewForwarder(addr, cDialer), sDialer: sDialer, user: user, password: pass, + xff: false, + selfip: OutboundIP().String(), + } + + p, _ := url.ParseQuery(rawQuery) + if v, ok := p["xff"]; ok { + if v[0] == "true" { + s.xff = true + } } return s, nil @@ -89,6 +101,16 @@ func (s *HTTP) Serve(c net.Conn) { // tell the remote server not to keep alive reqHeader.Set("Connection", "close") + // X-Forwarded-For + if s.xff { + if reqHeader.Get("") != "" { + reqHeader.Add("X-Forwarded-For", ",") + } + reqHeader.Add("X-Forwarded-For", c.RemoteAddr().(*net.TCPAddr).IP.String()) + reqHeader.Add("X-Forwarded-For", ",") + reqHeader.Add("X-Forwarded-For", s.selfip) + } + url, err := url.ParseRequestURI(requestURI) if err != nil { logf("parse request url error: %s", err) @@ -211,12 +233,12 @@ func (s *HTTP) Dial(network, addr string) (net.Conn, error) { logf("proxy-http 'CONNECT' method not allowed by proxy %s", s.addr) } - return nil, errors.New("cound not connect remote address: " + addr + ". error code: " + code) + return nil, errors.New("proxy-http cound not connect remote address: " + addr + ". error code: " + code) } // DialUDP . func (s *HTTP) DialUDP(network, addr string) (net.PacketConn, error) { - return nil, errors.New("udp not supported by http proxy now") + return nil, errors.New("proxy-http udp not supported by http proxy now") } // parseFirstLine parses "GET /foo HTTP/1.1" OR "HTTP/1.1 200 OK" into its three parts. diff --git a/mixed.go b/mixed.go index e952722..93b69df 100644 --- a/mixed.go +++ b/mixed.go @@ -27,13 +27,13 @@ type MixedProxy struct { } // NewMixedProxy returns a mixed proxy. -func NewMixedProxy(addr, user, pass string, sDialer Dialer) (*MixedProxy, error) { +func NewMixedProxy(addr, user, pass, rawQuery string, sDialer Dialer) (*MixedProxy, error) { p := &MixedProxy{ sDialer: sDialer, addr: addr, } - p.http, _ = NewHTTP(addr, user, pass, nil, sDialer) + p.http, _ = NewHTTP(addr, user, pass, rawQuery, nil, sDialer) p.socks5, _ = NewSOCKS5(addr, user, pass, nil, sDialer) return p, nil diff --git a/server.go b/server.go index 248b622..4c1951a 100644 --- a/server.go +++ b/server.go @@ -38,9 +38,9 @@ func ServerFromURL(s string, sDialer Dialer) (Server, error) { switch u.Scheme { case "mixed": - return NewMixedProxy(addr, user, pass, sDialer) + return NewMixedProxy(addr, user, pass, u.RawQuery, sDialer) case "http": - return NewHTTP(addr, user, pass, nil, sDialer) + return NewHTTP(addr, user, pass, u.RawQuery, nil, sDialer) case "socks5": return NewSOCKS5(addr, user, pass, nil, sDialer) case "ss": diff --git a/udptun.go b/udptun.go index 6a766d1..aaeb8a5 100644 --- a/udptun.go +++ b/udptun.go @@ -57,7 +57,7 @@ func (s *UDPTun) ListenAndServe() { // TODO: check here, get the correct sDialer's addr sUDPAddr, err := net.ResolveUDPAddr("udp", s.sDialer.Addr()) if err != nil { - logf("proxy-udptun failed to ResolveUDPAddr %", s.sDialer.Addr()) + logf("proxy-udptun failed to ResolveUDPAddr %s", s.sDialer.Addr()) return }