websocket
websocket copied to clipboard
[BUG] websocket: bad handshake 403 Forbidden
Is there an existing issue for this?
- [X] I have searched the existing issues
Current Behavior
1.golang implementation code
url := "wss://wspap.okx.com:8443/ws/v5/public"
requestHeader := http.Header{}
requestHeader.Set("Origin", "https://wspap.okx.com")
dialer := websocket.Dialer{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
EnableCompression: true,
HandshakeTimeout: 45 * time.Second,
}
conn, resp, err := dialer.DialContext(
context.Background(),
url,
requestHeader,
)
request header: `Connection: Upgrade
Sec-WebSocket-Key: w8Nxuu9f9XmCGhjx8JGCbQ== Sec-WebSocket-Version: 13 Origin: https://wspap.okx.com Sec-WebSocket-Extensions: permessage-deflate; server_no_context_takeover; client_no_context_takeover Upgrade: websocket ` Origin: Plus or minus, it's 403
2 python code, python code is normal:
uri = "wss://wspap.okx.com:8443/ws/v5/public"
async with websockets.connect(uri) as websocket:
print("Connected to OKX WebSocket server")
3. postman is normal, too
Expected Behavior
No response
Steps To Reproduce
No response
Anything else?
No response
Print the response body to see if that gives a hint about the problem. I tried that, but cannot reproduce the bug.
The following program prints success for me:
func main() {
url := "wss://wspap.okx.com:8443/ws/v5/public"
requestHeader := http.Header{}
requestHeader.Set("Origin", "https://wspap.okx.com")
dialer := websocket.Dialer{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
EnableCompression: true,
HandshakeTimeout: 45 * time.Second,
}
conn, resp, err := dialer.DialContext(
context.Background(),
url,
requestHeader,
)
if err != nil {
fmt.Println("error:", err)
if resp != nil {
fmt.Println("status:", resp.Status)
fmt.Println("body:")
io.Copy(os.Stdout, resp.Body)
}
return
}
conn.Close()
fmt.Println("success")
}
Print the response body to see if that gives a hint about the problem. I tried that, but cannot reproduce the bug.
The following program prints
successfor me:func main() { url := "wss://wspap.okx.com:8443/ws/v5/public" requestHeader := http.Header{} requestHeader.Set("Origin", "https://wspap.okx.com") dialer := websocket.Dialer{ ReadBufferSize: 1024, WriteBufferSize: 1024, EnableCompression: true, HandshakeTimeout: 45 * time.Second, } conn, resp, err := dialer.DialContext( context.Background(), url, requestHeader, ) if err != nil { fmt.Println("error:", err) if resp != nil { fmt.Println("status:", resp.Status) fmt.Println("body:") io.Copy(os.Stdout, resp.Body) } return } conn.Close() fmt.Println("success") }
error: websocket: bad handshake
status: 403 Forbidden
body:
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6 oldie" lang="en-US"> <![endif]-->
<!--[if IE 7]> <html class="no-js ie7 oldie" lang="en-US"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en-US"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en-US"> <!--<![endif]-->
<head>
<title>Attention Required! | Cloudflare</title>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<link rel="stylesheet" id="cf_styles-css" href="/cdn-cgi/styles/cf.errors.css" />
<!--[if lt IE 9]><link rel="stylesheet" id='cf_styles-ie-css' href="/cdn-cgi/styles/cf.errors.ie.css" /><![endif]-->
<style>body{margin:0;padding:0}</style>
<!--[if gte IE 10]><!-->
<script>
if (!navigator.cookieEnabled) {
window.addEventListener('DOMContentLoaded', function () {
var c--- PASS: TestOkex (0.34s)
PASS
It looks like the request was denied by the Cloudflare bot detector, but I am not 100% sure of that. To get past the detector, try adding a User-Agent request header that matches one of the programs that does work.
Print the response headers as below. Perhaps there's something useful there, but I doubt it.
url := "wss://wspap.okx.com:8443/ws/v5/public"
requestHeader := http.Header{}
requestHeader.Set("Origin", "https://wspap.okx.com")
dialer := websocket.Dialer{
ReadBufferSize: 1024,
WriteBufferSize: 1024,
EnableCompression: true,
HandshakeTimeout: 45 * time.Second,
}
conn, resp, err := dialer.DialContext(
context.Background(),
url,
requestHeader,
)
fmt.Println("error:", err)
if resp != nil {
fmt.Println("status:", resp.Status)
for k, vs := range resp.Header {
for _, v := range vs {
fmt.Printf("%s: %s\n", k, v)
}
}
fmt.Println("body:")
io.Copy(os.Stdout, resp.Body)
}
if err != nil {
return
}
conn.Close()
The program works for me and will probably work for others who try to debug it.