Skip to content

Commit 5140601

Browse files
blink-so[bot]f0ssel
andcommitted
Fix singleConnectionListener to prevent immediate EOF
- Use channel-based approach to control listener lifecycle - Prevent http.Serve from shutting down immediately after first Accept() - Add proper Close() method with channel signaling - Use constructor function for proper initialization - Should fix the premature EOF issue Co-authored-by: f0ssel <[email protected]>
1 parent 1642b9b commit 5140601

File tree

1 file changed

+40
-4
lines changed

1 file changed

+40
-4
lines changed

proxy/proxy.go

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,17 @@ func (p *Server) handleConnectionWithTLSDetection(conn net.Conn) {
537537
}
538538
p.logger.Debug("TLS handshake successful")
539539
// Use HTTP server with TLS connection
540-
http.Serve(&singleConnectionListener{conn: tlsConn}, http.HandlerFunc(p.handleHTTPS))
540+
listener := newSingleConnectionListener(tlsConn)
541+
defer listener.Close()
542+
err = http.Serve(listener, http.HandlerFunc(p.handleHTTPS))
543+
p.logger.Debug("http.Serve completed for HTTPS", "error", err)
541544
} else {
542545
p.logger.Debug("Detected HTTP request, handling normally")
543546
// Use HTTP server with regular connection
544547
p.logger.Debug("About to call http.Serve for HTTP connection")
545-
err = http.Serve(&singleConnectionListener{conn: connWrapper}, http.HandlerFunc(p.handleHTTP))
548+
listener := newSingleConnectionListener(connWrapper)
549+
defer listener.Close()
550+
err = http.Serve(listener, http.HandlerFunc(p.handleHTTP))
546551
p.logger.Debug("http.Serve completed", "error", err)
547552
}
548553
}
@@ -841,23 +846,54 @@ func (c *connectionWrapper) Read(p []byte) (int, error) {
841846

842847
// singleConnectionListener wraps a single connection into a net.Listener
843848
type singleConnectionListener struct {
844-
conn net.Conn
845-
used bool
849+
conn net.Conn
850+
used bool
851+
closed chan struct{}
852+
mu sync.Mutex
853+
}
854+
855+
func newSingleConnectionListener(conn net.Conn) *singleConnectionListener {
856+
return &singleConnectionListener{
857+
conn: conn,
858+
closed: make(chan struct{}),
859+
}
846860
}
847861

848862
func (sl *singleConnectionListener) Accept() (net.Conn, error) {
863+
sl.mu.Lock()
864+
defer sl.mu.Unlock()
865+
849866
if sl.used || sl.conn == nil {
867+
// Wait for close signal
868+
<-sl.closed
850869
return nil, io.EOF
851870
}
852871
sl.used = true
853872
return sl.conn, nil
854873
}
855874

856875
func (sl *singleConnectionListener) Close() error {
876+
sl.mu.Lock()
877+
defer sl.mu.Unlock()
878+
879+
select {
880+
case <-sl.closed:
881+
// Already closed
882+
default:
883+
close(sl.closed)
884+
}
885+
886+
if sl.conn != nil {
887+
sl.conn.Close()
888+
sl.conn = nil
889+
}
857890
return nil
858891
}
859892

860893
func (sl *singleConnectionListener) Addr() net.Addr {
894+
if sl.conn == nil {
895+
return nil
896+
}
861897
return sl.conn.LocalAddr()
862898
}
863899

0 commit comments

Comments
 (0)