add http request forwarding support for http handler

This commit is contained in:
rui.zheng 2017-08-02 23:39:32 +08:00
parent 8d4c18ab07
commit 36b61e0580
2 changed files with 52 additions and 8 deletions

View File

@ -9,6 +9,7 @@ import (
"net/http/httputil"
"net/url"
"strings"
"time"
"github.com/go-log/log"
)
@ -118,13 +119,14 @@ func (h *httpHandler) Handle(conn net.Conn) {
}
req.Header.Del("Proxy-Authorization")
req.Header.Del("Proxy-Connection")
// forward http request
//lastNode := s.Base.Chain.lastNode
//if lastNode != nil && lastNode.Transport == "" && (lastNode.Protocol == "http" || lastNode.Protocol == "") {
// s.forwardRequest(req)
// return
//}
lastNode := h.options.Chain.LastNode()
if req.Method != http.MethodConnect && lastNode.Protocol == "http" {
h.forwardRequest(conn, req)
return
}
// if !s.Base.Node.Can("tcp", req.Host) {
// glog.Errorf("Unauthorized to tcp connect to %s", req.Host)
@ -170,6 +172,48 @@ func (h *httpHandler) Handle(conn net.Conn) {
log.Logf("[http] %s >-< %s", conn.RemoteAddr(), req.Host)
}
func (h *httpHandler) forwardRequest(conn net.Conn, req *http.Request) {
if h.options.Chain.IsEmpty() {
return
}
lastNode := h.options.Chain.LastNode()
cc, err := h.options.Chain.Conn()
if err != nil {
log.Logf("[http] %s -> %s : %s", conn.RemoteAddr(), lastNode.Addr, err)
b := []byte("HTTP/1.1 503 Service unavailable\r\n" +
"Proxy-Agent: gost/" + Version + "\r\n\r\n")
if Debug {
log.Logf("[http] %s <- %s\n%s", conn.RemoteAddr(), lastNode.Addr, string(b))
}
conn.Write(b)
return
}
defer cc.Close()
if lastNode.User != nil {
s := lastNode.User.String()
if _, set := lastNode.User.Password(); !set {
s += ":"
}
req.Header.Set("Proxy-Authorization",
"Basic "+base64.StdEncoding.EncodeToString([]byte(s)))
}
cc.SetWriteDeadline(time.Now().Add(WriteTimeout))
if err = req.WriteProxy(cc); err != nil {
log.Logf("[http] %s -> %s : %s", conn.RemoteAddr(), req.Host, err)
return
}
cc.SetWriteDeadline(time.Time{})
log.Logf("[http] %s <-> %s", conn.RemoteAddr(), req.Host)
transport(conn, cc)
log.Logf("[http] %s >-< %s", conn.RemoteAddr(), req.Host)
return
}
func basicProxyAuth(proxyAuth string) (username, password string, ok bool) {
if proxyAuth == "" {
return

View File

@ -318,8 +318,6 @@ func (h *http2Handler) roundTrip(w http.ResponseWriter, r *http.Request) {
}
defer cc.Close()
log.Logf("[http2] %s <-> %s", r.RemoteAddr, target)
if r.Method == http.MethodConnect {
w.WriteHeader(http.StatusOK)
if fw, ok := w.(http.Flusher); ok {
@ -337,12 +335,13 @@ func (h *http2Handler) roundTrip(w http.ResponseWriter, r *http.Request) {
}
defer conn.Close()
log.Logf("[http2] %s -> %s : downgrade to HTTP/1.1", r.RemoteAddr, target)
log.Logf("[http2] %s <-> %s : downgrade to HTTP/1.1", r.RemoteAddr, target)
transport(conn, cc)
log.Logf("[http2] %s >-< %s", r.RemoteAddr, target)
return
}
log.Logf("[http2] %s <-> %s", r.RemoteAddr, target)
errc := make(chan error, 2)
go func() {
_, err := io.Copy(cc, r.Body)
@ -361,6 +360,7 @@ func (h *http2Handler) roundTrip(w http.ResponseWriter, r *http.Request) {
return
}
log.Logf("[http2] %s <-> %s", r.RemoteAddr, target)
if err = r.Write(cc); err != nil {
log.Logf("[http2] %s -> %s : %s", r.RemoteAddr, target, err)
return