Skip to content

Commit 797e28b

Browse files
committed
fix: http1.1
1 parent 7c065bc commit 797e28b

1 file changed

Lines changed: 20 additions & 3 deletions

File tree

grx/rawhttp/client.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,19 +83,36 @@ func (c *Client) dialUTLS(addr, serverName string) (net.Conn, error) {
8383
}
8484

8585
// Create uTLS config
86+
// Note: NextProtos here is just for the config, but browser fingerprints
87+
// override this with their own ALPN extensions
8688
config := &utls.Config{
8789
ServerName: serverName,
8890
InsecureSkipVerify: c.config.InsecureSkipVerify,
8991
MinVersion: tls.VersionTLS12,
9092
MaxVersion: tls.VersionTLS13,
91-
// For raw HTTP, we want HTTP/1.1 to preserve the raw request format
92-
NextProtos: []string{"http/1.1"},
9393
}
9494

9595
// Create uTLS connection with browser fingerprint
9696
utlsConn := utls.UClient(tcpConn, config, c.getUTLSClientHelloID())
9797

98-
// Perform TLS handshake
98+
// Build handshake state first so we can modify ALPN extension
99+
// Browser fingerprints include their own ALPN (typically ["h2", "http/1.1"])
100+
// which would cause server to negotiate HTTP/2. We must override to force HTTP/1.1.
101+
if err := utlsConn.BuildHandshakeState(); err != nil {
102+
tcpConn.Close()
103+
return nil, fmt.Errorf("failed to build handshake state for %s: %w", serverName, err)
104+
}
105+
106+
// Override ALPN extension to force HTTP/1.1 only
107+
// This is critical: without this, servers negotiate HTTP/2 and send binary frames
108+
for _, ext := range utlsConn.Extensions {
109+
if alpnExt, ok := ext.(*utls.ALPNExtension); ok {
110+
alpnExt.AlpnProtocols = []string{"http/1.1"}
111+
break
112+
}
113+
}
114+
115+
// Perform TLS handshake with the modified ALPN
99116
if err := utlsConn.HandshakeContext(ctx); err != nil {
100117
tcpConn.Close()
101118
return nil, fmt.Errorf("uTLS handshake failed for %s: %w", serverName, err)

0 commit comments

Comments
 (0)