mirror of
https://github.com/mmatczuk/go-http-tunnel.git
synced 2026-05-15 14:16:17 -06:00
transfer: don't close connections in transfer
This commit is contained in:
parent
8cf9ce23ec
commit
496df4d34f
3 changed files with 25 additions and 34 deletions
27
server.go
27
server.go
|
|
@ -465,16 +465,16 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
http.Error(w, err.Error(), http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
copyHeader(w.Header(), resp.Header)
|
||||
w.WriteHeader(resp.StatusCode)
|
||||
if resp.Body != nil {
|
||||
transfer(w, resp.Body, log.NewContext(s.logger).With(
|
||||
"dir", "client to user",
|
||||
"dst", r.RemoteAddr,
|
||||
"src", r.Host,
|
||||
))
|
||||
}
|
||||
|
||||
transfer(w, resp.Body, log.NewContext(s.logger).With(
|
||||
"dir", "client to user",
|
||||
"dst", r.RemoteAddr,
|
||||
"src", r.Host,
|
||||
))
|
||||
}
|
||||
|
||||
// RoundTrip is http.RoundTriper implementation.
|
||||
|
|
@ -504,7 +504,7 @@ func (s *Server) RoundTrip(r *http.Request) (*http.Response, error) {
|
|||
func (s *Server) proxyConn(identifier id.ID, conn net.Conn, msg *proto.ControlMessage) error {
|
||||
s.logger.Log(
|
||||
"level", 2,
|
||||
"action", "proxy",
|
||||
"action", "proxy conn",
|
||||
"identifier", identifier,
|
||||
"ctrlMsg", msg,
|
||||
)
|
||||
|
|
@ -520,6 +520,9 @@ func (s *Server) proxyConn(identifier id.ID, conn net.Conn, msg *proto.ControlMe
|
|||
return err
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
transfer(pw, conn, log.NewContext(s.logger).With(
|
||||
|
|
@ -527,6 +530,7 @@ func (s *Server) proxyConn(identifier id.ID, conn net.Conn, msg *proto.ControlMe
|
|||
"dst", identifier,
|
||||
"src", conn.RemoteAddr(),
|
||||
))
|
||||
cancel()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
|
|
@ -534,6 +538,7 @@ func (s *Server) proxyConn(identifier id.ID, conn net.Conn, msg *proto.ControlMe
|
|||
if err != nil {
|
||||
return fmt.Errorf("io error: %s", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
transfer(conn, resp.Body, log.NewContext(s.logger).With(
|
||||
"dir", "client to user",
|
||||
|
|
@ -545,7 +550,7 @@ func (s *Server) proxyConn(identifier id.ID, conn net.Conn, msg *proto.ControlMe
|
|||
|
||||
s.logger.Log(
|
||||
"level", 2,
|
||||
"action", "proxy done",
|
||||
"action", "proxy conn done",
|
||||
"identifier", identifier,
|
||||
"ctrlMsg", msg,
|
||||
)
|
||||
|
|
@ -556,7 +561,7 @@ func (s *Server) proxyConn(identifier id.ID, conn net.Conn, msg *proto.ControlMe
|
|||
func (s *Server) proxyHTTP(identifier id.ID, r *http.Request, msg *proto.ControlMessage) (*http.Response, error) {
|
||||
s.logger.Log(
|
||||
"level", 2,
|
||||
"action", "proxy",
|
||||
"action", "proxy HTTP",
|
||||
"identifier", identifier,
|
||||
"ctrlMsg", msg,
|
||||
)
|
||||
|
|
@ -605,7 +610,7 @@ func (s *Server) proxyHTTP(identifier id.ID, r *http.Request, msg *proto.Control
|
|||
|
||||
s.logger.Log(
|
||||
"level", 2,
|
||||
"action", "proxy done",
|
||||
"action", "proxy HTTP done",
|
||||
"identifier", identifier,
|
||||
"ctrlMsg", msg,
|
||||
"status code", resp.StatusCode,
|
||||
|
|
|
|||
|
|
@ -97,6 +97,7 @@ func (p *TCPProxy) Proxy(w io.Writer, r io.ReadCloser, msg *proto.ControlMessage
|
|||
)
|
||||
return
|
||||
}
|
||||
defer local.Close()
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
|
|
|
|||
31
utils.go
31
utils.go
|
|
@ -7,36 +7,21 @@ package tunnel
|
|||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/mmatczuk/go-http-tunnel/log"
|
||||
)
|
||||
|
||||
type closeWriter interface {
|
||||
CloseWrite() error
|
||||
}
|
||||
|
||||
type closeReader interface {
|
||||
CloseRead() error
|
||||
}
|
||||
|
||||
func transfer(dst io.Writer, src io.ReadCloser, logger log.Logger) {
|
||||
n, err := io.Copy(dst, src)
|
||||
if err != nil {
|
||||
logger.Log(
|
||||
"level", 2,
|
||||
"msg", "copy error",
|
||||
"err", err,
|
||||
)
|
||||
}
|
||||
|
||||
if d, ok := dst.(closeWriter); ok {
|
||||
d.CloseWrite()
|
||||
}
|
||||
|
||||
if s, ok := src.(closeReader); ok {
|
||||
s.CloseRead()
|
||||
} else {
|
||||
src.Close()
|
||||
if !strings.Contains(err.Error(), "context canceled") && !strings.Contains(err.Error(), "CANCEL") {
|
||||
logger.Log(
|
||||
"level", 2,
|
||||
"msg", "copy error",
|
||||
"err", err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
logger.Log(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue