Skip to content

Commit 91899a3

Browse files
committed
fix
1 parent 7ae8362 commit 91899a3

File tree

1 file changed

+46
-73
lines changed

1 file changed

+46
-73
lines changed

proxy/proxy.go

Lines changed: 46 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func (p *Server) Start(ctx context.Context) error {
7777
p.logger.Error("Failed to create HTTP listener", "error", err)
7878
return
7979
}
80-
80+
8181
for {
8282
conn, err := listener.Accept()
8383
if err != nil {
@@ -90,7 +90,7 @@ func (p *Server) Start(ctx context.Context) error {
9090
continue
9191
}
9292
}
93-
93+
9494
// Handle connection with TLS detection
9595
go p.handleConnectionWithTLSDetection(conn)
9696
}
@@ -132,7 +132,7 @@ func (p *Server) Stop() error {
132132
// handleHTTP handles regular HTTP requests and CONNECT tunneling
133133
func (p *Server) handleHTTP(w http.ResponseWriter, r *http.Request) {
134134
p.logger.Debug("handleHTTP called", "method", r.Method, "url", r.URL.String(), "host", r.Host)
135-
135+
136136
// Handle CONNECT method for HTTPS tunneling
137137
if r.Method == "CONNECT" {
138138
p.handleConnect(w, r)
@@ -184,20 +184,19 @@ func (p *Server) handleHTTPS(w http.ResponseWriter, r *http.Request) {
184184
// forwardHTTPRequest forwards a regular HTTP request
185185
func (p *Server) forwardHTTPRequest(w http.ResponseWriter, r *http.Request) {
186186
p.logger.Debug("forwardHTTPRequest called", "method", r.Method, "url", r.URL.String(), "host", r.Host)
187-
187+
188188
// Create a new request to the target server
189189
targetURL := &url.URL{
190-
Scheme: "http",
191-
Host: r.Host,
192-
Path: r.URL.Path,
190+
Scheme: "http",
191+
Host: r.Host,
192+
Path: r.URL.Path,
193193
RawQuery: r.URL.RawQuery,
194194
}
195195

196196
p.logger.Debug("Target URL constructed", "target", targetURL.String())
197197

198198
// Create HTTP client with very short timeout for debugging
199199
client := &http.Client{
200-
Timeout: 2 * time.Second,
201200
CheckRedirect: func(req *http.Request, via []*http.Request) error {
202201
return http.ErrUseLastResponse // Don't follow redirects
203202
},
@@ -223,14 +222,7 @@ func (p *Server) forwardHTTPRequest(w http.ResponseWriter, r *http.Request) {
223222
}
224223

225224
p.logger.Debug("About to make HTTP request", "target", targetURL.String())
226-
227-
// Make the request synchronously - this is the key fix
228-
p.logger.Debug("Calling client.Do() now...")
229-
start := time.Now()
230225
resp, err := client.Do(req)
231-
duration := time.Since(start)
232-
p.logger.Debug("client.Do() completed", "duration", duration, "error", err)
233-
234226
if err != nil {
235227
p.logger.Error("Failed to make forward request", "error", err, "target", targetURL.String(), "error_type", fmt.Sprintf("%T", err))
236228
http.Error(w, fmt.Sprintf("Failed to make request: %v", err), http.StatusBadGateway)
@@ -281,7 +273,6 @@ func (p *Server) forwardHTTPSRequest(w http.ResponseWriter, r *http.Request) {
281273

282274
// Create HTTPS client
283275
client := &http.Client{
284-
Timeout: 30 * time.Second,
285276
Transport: &http.Transport{
286277
TLSClientConfig: &tls.Config{
287278
InsecureSkipVerify: false,
@@ -339,24 +330,7 @@ func (p *Server) writeBlockedResponse(w http.ResponseWriter, r *http.Request) {
339330
host = r.Host
340331
}
341332

342-
// Handle CONNECT requests differently (HTTPS tunneling)
343-
if r.Method == "CONNECT" {
344-
fmt.Fprintf(w, `🚫 HTTPS Request Blocked by Coder Jail
345-
346-
Connection: %s (HTTPS)
347-
Host: %s
348-
349-
This HTTPS request was blocked by jail's security policy.
350-
351-
To allow this request, restart jail with:
352-
--allow "%s" # Allow all methods to this host
353-
--allow "CONNECT %s" # Allow only HTTPS connections to this host
354-
355-
For more help: https://github.com/coder/jail
356-
`,
357-
r.URL.Host, host, host, host)
358-
} else {
359-
fmt.Fprintf(w, `🚫 Request Blocked by Coder Jail
333+
fmt.Fprintf(w, `🚫 Request Blocked by Coder Jail
360334
361335
Request: %s %s
362336
Host: %s
@@ -367,8 +341,7 @@ To allow this request, restart jail with:
367341
368342
For more help: https://github.com/coder/jail
369343
`,
370-
r.Method, r.URL.Path, host, host, r.Method, host, r.Method)
371-
}
344+
r.Method, r.URL.Path, host, host, r.Method, host, r.Method)
372345
}
373346

374347
// handleConnect handles CONNECT requests for HTTPS tunneling with TLS termination
@@ -420,11 +393,11 @@ func (p *Server) handleConnect(w http.ResponseWriter, r *http.Request) {
420393

421394
// Perform TLS handshake with the client using our certificates
422395
p.logger.Debug("Starting TLS handshake", "hostname", hostname)
423-
396+
424397
// Create TLS config that forces HTTP/1.1 (disable HTTP/2 ALPN)
425398
tlsConfig := p.tlsConfig.Clone()
426399
tlsConfig.NextProtos = []string{"http/1.1"}
427-
400+
428401
tlsConn := tls.Server(conn, tlsConfig)
429402
err = tlsConn.Handshake()
430403
if err != nil {
@@ -442,7 +415,7 @@ func (p *Server) handleConnect(w http.ResponseWriter, r *http.Request) {
442415
// handleTLSConnection processes decrypted HTTPS requests over the TLS connection
443416
func (p *Server) handleTLSConnection(tlsConn *tls.Conn, hostname string) {
444417
p.logger.Debug("Creating HTTP server for TLS connection", "hostname", hostname)
445-
418+
446419
// Use ReadRequest to manually read HTTP requests from the TLS connection
447420
bufReader := bufio.NewReader(tlsConn)
448421
for {
@@ -456,9 +429,9 @@ func (p *Server) handleTLSConnection(tlsConn *tls.Conn, hostname string) {
456429
}
457430
break
458431
}
459-
432+
460433
p.logger.Debug("Processing decrypted HTTPS request", "hostname", hostname, "method", req.Method, "path", req.URL.Path)
461-
434+
462435
// Set the hostname and scheme if not already set
463436
if req.URL.Host == "" {
464437
req.URL.Host = hostname
@@ -469,22 +442,22 @@ func (p *Server) handleTLSConnection(tlsConn *tls.Conn, hostname string) {
469442

470443
// Create a response recorder to capture the response
471444
recorder := httptest.NewRecorder()
472-
445+
473446
// Process the HTTPS request
474447
p.handleDecryptedHTTPS(recorder, req)
475-
448+
476449
// Write the response back to the TLS connection
477450
resp := recorder.Result()
478451
err = resp.Write(tlsConn)
479452
if err != nil {
480453
p.logger.Debug("Failed to write response", "hostname", hostname, "error", err)
481454
break
482455
}
483-
456+
484457
// Close connection after single request (HTTP/1.0 style)
485458
break
486459
}
487-
460+
488461
p.logger.Debug("TLS connection handling completed", "hostname", hostname)
489462
}
490463

@@ -556,50 +529,50 @@ func (p *Server) handleConnectionWithTLSDetection(conn net.Conn) {
556529
func (p *Server) handleTLSTermination(conn net.Conn, firstByte []byte) {
557530
// Create a connection that prepends the first byte we already read
558531
connWithFirstByte := &connectionWithPrefix{
559-
Conn: conn,
532+
Conn: conn,
560533
prefix: firstByte,
561534
}
562535

563536
// We need to extract the SNI (Server Name Indication) from the TLS handshake
564537
// to generate the appropriate certificate. For now, use a default hostname.
565538
hostname := "unknown-host"
566-
539+
567540
// TODO: Extract hostname from TLS ClientHello SNI extension
568541
// For now, we'll perform TLS termination with a generic certificate
569-
542+
570543
// Perform TLS handshake with our certificate
571544
tlsConn := tls.Server(connWithFirstByte, p.tlsConfig)
572545
err := tlsConn.Handshake()
573546
if err != nil {
574547
p.logger.Debug("TLS handshake failed", "error", err)
575548
return
576549
}
577-
550+
578551
p.logger.Debug("TLS handshake successful, processing decrypted HTTPS traffic")
579-
552+
580553
// Now handle the decrypted HTTPS requests using our existing logic
581554
p.handleTLSConnection(tlsConn, hostname)
582555
}
583556

584557
// handleHTTPConnection handles regular HTTP connections
585558
func (p *Server) handleHTTPConnection(conn net.Conn, firstByte []byte) {
586559
p.logger.Debug("Starting HTTP connection handling")
587-
560+
588561
// Create a connection that prepends the first byte we already read
589562
connWithFirstByte := &connectionWithPrefix{
590-
Conn: conn,
563+
Conn: conn,
591564
prefix: firstByte,
592565
}
593566

594567
p.logger.Debug("Created connection wrapper, starting HTTP server")
595-
568+
596569
// Create HTTP server to handle this connection
597570
server := &http.Server{
598571
Handler: http.HandlerFunc(p.handleHTTP),
599572
}
600573

601574
p.logger.Debug("About to serve HTTP connection")
602-
575+
603576
// Serve the HTTP request
604577
err := server.Serve(&singleConnListener{conn: connWithFirstByte})
605578
if err != nil && err != io.EOF && !isConnectionClosed(err) {
@@ -619,15 +592,15 @@ func (p *Server) handleHTTPWithTLSTermination(w http.ResponseWriter, r *http.Req
619592
// connectionWithPrefix wraps a connection and prepends some data
620593
type connectionWithPrefix struct {
621594
net.Conn
622-
prefix []byte
595+
prefix []byte
623596
prefixRead bool
624-
mu sync.Mutex
597+
mu sync.Mutex
625598
}
626599

627600
func (c *connectionWithPrefix) Read(b []byte) (n int, err error) {
628601
c.mu.Lock()
629602
defer c.mu.Unlock()
630-
603+
631604
if !c.prefixRead && len(c.prefix) > 0 {
632605
// Return the prefix data first
633606
n = copy(b, c.prefix)
@@ -659,7 +632,7 @@ type singleConnListener struct {
659632
func (l *singleConnListener) Accept() (net.Conn, error) {
660633
l.mu.Lock()
661634
defer l.mu.Unlock()
662-
635+
663636
if l.used {
664637
return nil, io.EOF
665638
}
@@ -678,7 +651,7 @@ func (l *singleConnListener) Addr() net.Addr {
678651
// handleHTTPConnectionDirect handles HTTP connections directly without HTTP server framework
679652
func (p *Server) handleHTTPConnectionDirect(bufReader *bufio.Reader, conn net.Conn) {
680653
p.logger.Debug("Starting direct HTTP connection handling")
681-
654+
682655
// Parse the HTTP request manually
683656
req, err := http.ReadRequest(bufReader)
684657
if err != nil {
@@ -717,12 +690,12 @@ func (p *Server) handleHTTPConnectionDirect(bufReader *bufio.Reader, conn net.Co
717690
// forwardHTTPRequestDirect forwards HTTP request and writes response directly to connection
718691
func (p *Server) forwardHTTPRequestDirect(req *http.Request, conn net.Conn) {
719692
p.logger.Debug("forwardHTTPRequestDirect called", "method", req.Method, "url", req.URL.String(), "host", req.Host)
720-
693+
721694
// Create target URL
722695
targetURL := &url.URL{
723-
Scheme: "http",
724-
Host: req.Host,
725-
Path: req.URL.Path,
696+
Scheme: "http",
697+
Host: req.Host,
698+
Path: req.URL.Path,
726699
RawQuery: req.URL.RawQuery,
727700
}
728701

@@ -786,7 +759,7 @@ func (p *Server) forwardHTTPRequestDirect(req *http.Request, conn net.Conn) {
786759
conn.Write([]byte(headerLine))
787760
}
788761
}
789-
762+
790763
// End headers
791764
conn.Write([]byte("\r\n"))
792765

@@ -805,31 +778,31 @@ func (p *Server) forwardHTTPRequestDirect(req *http.Request, conn net.Conn) {
805778
func (p *Server) handleTLSTerminationDirect(bufReader *bufio.Reader, conn net.Conn) {
806779
// Create a connection that uses the buffered reader
807780
bufferedConn := &bufferedConnection{
808-
Conn: conn,
781+
Conn: conn,
809782
reader: bufReader,
810783
}
811784

812785
// Extract hostname from TLS SNI (TODO: implement SNI parsing)
813786
hostname := "unknown-host"
814-
787+
815788
// Perform TLS handshake with our certificate
816789
tlsConn := tls.Server(bufferedConn, p.tlsConfig)
817790
err := tlsConn.Handshake()
818791
if err != nil {
819792
p.logger.Debug("TLS handshake failed", "error", err)
820793
return
821794
}
822-
795+
823796
p.logger.Debug("TLS handshake successful, processing decrypted HTTPS traffic")
824-
797+
825798
// Handle the decrypted HTTPS requests
826799
p.handleTLSConnection(tlsConn, hostname)
827800
}
828801

829802
// connectionWrapper lets us "unread" the peeked byte
830803
type connectionWrapper struct {
831804
net.Conn
832-
buf []byte
805+
buf []byte
833806
bufUsed bool
834807
}
835808

@@ -862,7 +835,7 @@ func newSingleConnectionListener(conn net.Conn) *singleConnectionListener {
862835
func (sl *singleConnectionListener) Accept() (net.Conn, error) {
863836
sl.mu.Lock()
864837
defer sl.mu.Unlock()
865-
838+
866839
if sl.used || sl.conn == nil {
867840
// Wait for close signal
868841
<-sl.closed
@@ -875,14 +848,14 @@ func (sl *singleConnectionListener) Accept() (net.Conn, error) {
875848
func (sl *singleConnectionListener) Close() error {
876849
sl.mu.Lock()
877850
defer sl.mu.Unlock()
878-
851+
879852
select {
880853
case <-sl.closed:
881854
// Already closed
882855
default:
883856
close(sl.closed)
884857
}
885-
858+
886859
if sl.conn != nil {
887860
sl.conn.Close()
888861
sl.conn = nil
@@ -905,4 +878,4 @@ type bufferedConnection struct {
905878

906879
func (bc *bufferedConnection) Read(b []byte) (n int, err error) {
907880
return bc.reader.Read(b)
908-
}
881+
}

0 commit comments

Comments
 (0)