@@ -49,9 +49,23 @@ func appendHostToXForwardHeader(header http.Header, host string) {
4949 header .Set ("X-Forwarded-For" , host )
5050}
5151
52+ func isLocalAddress (addr string ) bool {
53+ host , _ , err := net .SplitHostPort (addr )
54+ if err != nil {
55+ host = addr
56+ }
57+ ip := net .ParseIP (host )
58+ if ip != nil {
59+ return ip .IsLoopback ()
60+ }
61+ host = strings .ToLower (host )
62+ return strings .HasSuffix (host , ".local" ) || host == "localhost"
63+ }
64+
5265type app struct {
5366 hs * http.Server
5467 sc * http.Client
68+ hc * http.Client
5569 dialer proxy.Dialer
5670 logger * zerolog.Logger
5771}
@@ -69,36 +83,67 @@ func (app *app) handleForward(w http.ResponseWriter, r *http.Request) {
6983 if clientIP , _ , err := net .SplitHostPort (req .RemoteAddr ); err == nil {
7084 appendHostToXForwardHeader (req .Header , clientIP )
7185 }
72- resp , err := app .sc .Do (req )
73- if err != nil {
74- app .logger .Error ().Err (err ).Msg ("Connection to SOCKS5 server closed" )
75- w .WriteHeader (http .StatusInternalServerError )
76- return
77- }
78- if resp == nil {
79- app .logger .Error ().Err (err ).Msg ("Connection to SOCKS5 server closed" )
80- w .WriteHeader (http .StatusInternalServerError )
81- return
86+ var resp * http.Response
87+ if isLocalAddress (r .Host ) {
88+ resp , err = app .hc .Do (req )
89+ if err != nil {
90+ app .logger .Error ().Err (err ).Msg ("Connection failed" )
91+ w .WriteHeader (http .StatusServiceUnavailable )
92+ return
93+ }
94+ if resp == nil {
95+ app .logger .Error ().Err (err ).Msg ("Connection failed" )
96+ w .WriteHeader (http .StatusServiceUnavailable )
97+ return
98+ }
99+ } else {
100+ resp , err = app .sc .Do (req )
101+ if err != nil {
102+ app .logger .Error ().Err (err ).Msg ("Connection to SOCKS5 server failed" )
103+ w .WriteHeader (http .StatusServiceUnavailable )
104+ return
105+ }
106+ if resp == nil {
107+ app .logger .Error ().Err (err ).Msg ("Connection to SOCKS5 server failed" )
108+ w .WriteHeader (http .StatusServiceUnavailable )
109+ return
110+ }
82111 }
83112 defer resp .Body .Close ()
84113
85114 delHopHeaders (resp .Header )
86115 copyHeader (w .Header (), resp .Header )
87116 w .WriteHeader (resp .StatusCode )
88- written , err := io .Copy (w , resp .Body )
117+ n , err := io .Copy (w , resp .Body )
89118 if err != nil {
90119 app .logger .Error ().Err (err ).Msgf ("Error during Copy() %s: %s" , r .URL .String (), err )
91120 w .WriteHeader (http .StatusInternalServerError )
92121 return
93122 }
94- app .logger .Debug ().Msgf ("%s - %s - %s - %d - %dKB" , r .Proto , r .Method , r .Host , resp .StatusCode , written / 1000 )
123+ var written string
124+ if n < 1000 {
125+ written = fmt .Sprintf ("%d Bytes" , n )
126+ } else {
127+ written = fmt .Sprintf ("%d KB" , n )
128+ }
129+ app .logger .Debug ().Msgf ("%s - %s - %s - %d - %s" , r .Proto , r .Method , r .Host , resp .StatusCode , written )
95130}
96131
97132func (app * app ) handleTunnel (w http.ResponseWriter , r * http.Request ) {
98- dstConn , err := app .dialer .Dial ("tcp" , r .Host )
99- if err != nil {
100- http .Error (w , err .Error (), http .StatusServiceUnavailable )
101- return
133+ var dstConn net.Conn
134+ var err error
135+ if isLocalAddress (r .Host ) {
136+ dstConn , err = net .DialTimeout ("tcp" , r .Host , 10 * time .Second )
137+ if err != nil {
138+ http .Error (w , err .Error (), http .StatusServiceUnavailable )
139+ return
140+ }
141+ } else {
142+ dstConn , err = app .dialer .Dial ("tcp" , r .Host )
143+ if err != nil {
144+ http .Error (w , err .Error (), http .StatusServiceUnavailable )
145+ return
146+ }
102147 }
103148 defer dstConn .Close ()
104149 w .WriteHeader (http .StatusOK )
@@ -188,14 +233,21 @@ func New(conf *Config) *app {
188233 CheckRedirect : func (req * http.Request , via []* http.Request ) error {
189234 return http .ErrUseLastResponse
190235 },
236+ Timeout : 10 * time .Second ,
191237 }
192238 hs := & http.Server {
193239 Addr : conf .AddrHTTP ,
194240 ReadTimeout : 10 * time .Second ,
195241 WriteTimeout : 10 * time .Second ,
196242 MaxHeaderBytes : 1 << 20 ,
197243 }
244+ hc := & http.Client {
245+ CheckRedirect : func (req * http.Request , via []* http.Request ) error {
246+ return http .ErrUseLastResponse
247+ },
248+ Timeout : 10 * time .Second ,
249+ }
198250 logger .Info ().Msgf ("SOCKS5 Proxy: %s" , conf .AddrSOCKS )
199251 logger .Info ().Msgf ("HTTP Proxy: %s" , conf .AddrHTTP )
200- return & app {hs : hs , sc : socks , dialer : dialer , logger : & logger }
252+ return & app {hs : hs , sc : socks , hc : hc , dialer : dialer , logger : & logger }
201253}
0 commit comments