Skip to content

Commit

Permalink
Fix compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
wzshiming committed Jan 31, 2023
1 parent 629c912 commit b2e302f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 16 deletions.
17 changes: 15 additions & 2 deletions compatibility_read_deadline.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,20 @@ func (w listenerCompatibilityReadDeadline) Accept() (net.Conn, error) {
if err != nil {
return nil, err
}
return connCompatibilityReadDeadline{c}, nil
return NewConnCompatibilityReadDeadline(c), nil
}

// NewConnCompatibilityReadDeadline this is a wrapper used to be compatible with
// the net.Conn after wrapping it so that it can be hijacked properly.
// there is no effect if the content is not manipulated.
func NewConnCompatibilityReadDeadline(conn net.Conn) net.Conn {
if conn == nil {
return nil
}
if conn, ok := conn.(connCompatibilityReadDeadline); ok {
return conn
}
return connCompatibilityReadDeadline{conn}
}

type connCompatibilityReadDeadline struct {
Expand All @@ -35,7 +48,7 @@ type connCompatibilityReadDeadline struct {

func (d connCompatibilityReadDeadline) SetReadDeadline(t time.Time) error {
if aLongTimeAgo == t {
t = time.Now().Add(time.Second)
t = time.Now().Add(1 * time.Second)
}
return d.Conn.SetReadDeadline(t)
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module github.com/wzshiming/httpproxy

go 1.18

require golang.org/x/net v0.2.0
require golang.org/x/net v0.5.0

require golang.org/x/text v0.4.0 // indirect
require golang.org/x/text v0.6.0 // indirect
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
45 changes: 38 additions & 7 deletions proxy.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package httpproxy

import (
"bufio"
"context"
"fmt"
"io"
Expand Down Expand Up @@ -96,23 +97,22 @@ func (p *ProxyHandler) proxyConnect(w http.ResponseWriter, r *http.Request) {
http.Error(w, e, http.StatusInternalServerError)
return
}
defer targetConn.Close()

if flusher, ok := w.(http.Flusher); ok {
flusher.Flush()
} else {
w.WriteHeader(http.StatusOK)
}
w.WriteHeader(http.StatusOK)

clientConn, _, err := hijacker.Hijack()
conn, rw, err := hijacker.Hijack()
if err != nil {
e := err.Error()
e := fmt.Sprintf("hijack failed: %v", err)
if p.Logger != nil {
p.Logger.Println(e)
}
http.Error(w, e, http.StatusInternalServerError)
return
}

clientConn := newBufConn(conn, rw)

var buf1, buf2 []byte
if p.BytesPool != nil {
buf1 = p.BytesPool.Get()
Expand Down Expand Up @@ -151,3 +151,34 @@ func (p *ProxyHandler) proxyDial(ctx context.Context, network, address string) (
}
return proxyDial(ctx, network, address)
}

func newBufConn(conn net.Conn, rw *bufio.ReadWriter) net.Conn {
rw.Flush()
if rw.Reader.Buffered() == 0 {
// If there's no buffered data to be read,
// we can just discard the bufio.ReadWriter.
return conn
}
return &bufConn{conn, rw.Reader}
}

// bufConn wraps a net.Conn, but reads drain the bufio.Reader first.
type bufConn struct {
net.Conn
*bufio.Reader
}

func (c *bufConn) Read(p []byte) (int, error) {
if c.Reader == nil {
return c.Conn.Read(p)
}
n := c.Reader.Buffered()
if n == 0 {
c.Reader = nil
return c.Conn.Read(p)
}
if n < len(p) {
p = p[:n]
}
return c.Reader.Read(p)
}
1 change: 0 additions & 1 deletion tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"io"
)


// tunnel create tunnels for two io.ReadWriteCloser
func tunnel(ctx context.Context, c1, c2 io.ReadWriteCloser, buf1, buf2 []byte) error {
ctx, cancel := context.WithCancel(ctx)
Expand Down

0 comments on commit b2e302f

Please sign in to comment.