@@ -514,21 +514,34 @@ func (p *Server) handleDecryptedHTTPS(w http.ResponseWriter, r *http.Request) {
514
514
func (p * Server ) handleConnectionWithTLSDetection (conn net.Conn ) {
515
515
defer conn .Close ()
516
516
517
- // Use a buffered reader to peek at the first byte without consuming it
518
- bufReader := bufio . NewReader ( conn )
519
- firstByte , err := bufReader . Peek ( 1 )
517
+ // Peek at first byte to detect protocol
518
+ buf := make ([] byte , 1 )
519
+ _ , err := conn . Read ( buf )
520
520
if err != nil {
521
- p .logger .Debug ("Failed to peek at connection data " , "error" , err )
521
+ p .logger .Debug ("Failed to read first byte from connection " , "error" , err )
522
522
return
523
523
}
524
524
525
+ // Create connection wrapper that can "unread" the peeked byte
526
+ connWrapper := & connectionWrapper {conn , buf , false }
527
+
525
528
// TLS handshake starts with 0x16 (TLS Content Type: Handshake)
526
- if len ( firstByte ) > 0 && firstByte [0 ] == 0x16 {
529
+ if buf [0 ] == 0x16 {
527
530
p .logger .Debug ("Detected TLS handshake, performing TLS termination" )
528
- p .handleTLSTerminationDirect (bufReader , conn )
531
+ // Perform TLS handshake
532
+ tlsConn := tls .Server (connWrapper , p .tlsConfig )
533
+ err := tlsConn .Handshake ()
534
+ if err != nil {
535
+ p .logger .Debug ("TLS handshake failed" , "error" , err )
536
+ return
537
+ }
538
+ p .logger .Debug ("TLS handshake successful" )
539
+ // Use HTTP server with TLS connection
540
+ http .Serve (& singleConnectionListener {conn : tlsConn }, http .HandlerFunc (p .handleHTTPS ))
529
541
} else {
530
542
p .logger .Debug ("Detected HTTP request, handling normally" )
531
- p .handleHTTPConnectionDirect (bufReader , conn )
543
+ // Use HTTP server with regular connection
544
+ http .Serve (& singleConnectionListener {conn : connWrapper }, http .HandlerFunc (p .handleHTTP ))
532
545
}
533
546
}
534
547
@@ -806,6 +819,44 @@ func (p *Server) handleTLSTerminationDirect(bufReader *bufio.Reader, conn net.Co
806
819
p .handleTLSConnection (tlsConn , hostname )
807
820
}
808
821
822
+ // connectionWrapper lets us "unread" the peeked byte
823
+ type connectionWrapper struct {
824
+ net.Conn
825
+ buf []byte
826
+ bufUsed bool
827
+ }
828
+
829
+ func (c * connectionWrapper ) Read (p []byte ) (int , error ) {
830
+ if ! c .bufUsed && len (c .buf ) > 0 {
831
+ n := copy (p , c .buf )
832
+ c .bufUsed = true
833
+ return n , nil
834
+ }
835
+ return c .Conn .Read (p )
836
+ }
837
+
838
+ // singleConnectionListener wraps a single connection into a net.Listener
839
+ type singleConnectionListener struct {
840
+ conn net.Conn
841
+ used bool
842
+ }
843
+
844
+ func (sl * singleConnectionListener ) Accept () (net.Conn , error ) {
845
+ if sl .used || sl .conn == nil {
846
+ return nil , io .EOF
847
+ }
848
+ sl .used = true
849
+ return sl .conn , nil
850
+ }
851
+
852
+ func (sl * singleConnectionListener ) Close () error {
853
+ return nil
854
+ }
855
+
856
+ func (sl * singleConnectionListener ) Addr () net.Addr {
857
+ return sl .conn .LocalAddr ()
858
+ }
859
+
809
860
// bufferedConnection wraps a connection with a buffered reader
810
861
type bufferedConnection struct {
811
862
net.Conn
0 commit comments