pythonwebsocket

Python Web Socket closes immediately after opening


So I have an issue with a websocket in Python. I'm trying to interface with a website that uses websockets for some of its content communication. Here is the javascript code on their site:

 var $j = jQuery.noConflict(); // Use $j to reference JQuery selectors instead of $
 function sockify() {
    var ws = new WebSocket("ws://website:1234");
    ws.onmessage = function (evt) {
        console.log(evt.data)
       $j('#output').html(evt.data);
    }
    ws.onopen = function () {
        ws.send(JSON.stringify($j('#srctext').val()));
    }
    ws.onerror = function () {
        alert("socket down");
    }
 }

So the site works fine, and theres no issue with it, however when I try this python code, I get an error stating that the socket has been closed immediately after it opens:

ws = create_connection("ws://website:1234/")
print "Sending 'Hello, World'..."
ws.send("Hello, World")
print "Sent"
print "Receiving..."
result = ws.recv()
print "Received '%s'" % result
ws.close()

This is sample code pulled from the websocket man page on python.org, and it does work if I do not change the host to the website i'm trying to pull from, but rather leave the example's host as it is in the example.

Here is the error I receive:

Traceback (most recent call last):
  File "irc.py", line 462, in <module>
    tmpmsg = getSocket()
  File "irc.py", line 64, in getTrump
    result = ws.recv()
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 293, in recv
    opcode, data = self.recv_data()
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 310, in recv_data
    opcode, frame = self.recv_data_frame(control_frame)
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 323, in recv_data_frame
    frame = self.recv_frame()
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 357, in recv_frame
    return self.frame_buffer.recv_frame()
  File "/Library/Python/2.7/site-packages/websocket/_abnf.py", line 336, in recv_frame
    self.recv_header()
  File "/Library/Python/2.7/site-packages/websocket/_abnf.py", line 286, in recv_header
    header = self.recv_strict(2)
  File "/Library/Python/2.7/site-packages/websocket/_abnf.py", line 371, in recv_strict
    bytes_ = self.recv(min(16384, shortage))
  File "/Library/Python/2.7/site-packages/websocket/_core.py", line 427, in _recv
    return recv(self.sock, bufsize)
  File "/Library/Python/2.7/site-packages/websocket/_socket.py", line 93, in recv
    "Connection is already closed.")
websocket._exceptions.WebSocketConnectionClosedException: Connection is already closed.

Any idea why its closing right away?

Edit:

Ran with enableTrace true.

Here is the error I get:

--- request header ---
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: website
Origin: website
Sec-WebSocket-Key: 6jsV5DEWXPGTTTLKSEwz6g==
Sec-WebSocket-Version: 13


-----------------------
--- response header ---
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: CX4DYsItQC6utXvt8JH641455mM=
-----------------------
send: '\x81\x8b\x98\x8d\x81\xce\xd0\xe8\xed\xa2\xf7\xad\xd6\xa1\xea\xe1\xe5'

Please note that I dont actually have control over the websocket, so any fixes would need to be on my end. I'm on Python 2.7.10

I also noticed that if I intercept the websocket request in Burp while using the website, the websocket initial connection request is different. Here it is as captured from the website:

GET / HTTP/1.1
Host: website
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Sec-WebSocket-Version: 13
Origin: website
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Key: uyG2WBK51ZtPhy9RXLNTmg==
Connection: keep-alive, Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket

Solution

  • You have for sure an error (most probably your socket is exploding silently..)

    set instead in the configuration a callback for the errors in the socket and print the msg you get..

    example: (taken from here)

     websocket.enableTrace(True)
     ws = websocket.WebSocketApp("ws://echo.websocket.org/",
                                  on_message = on_message,
                                  on_error = on_error,
                                  on_close = on_close)
    

    and define the method

    def on_error(ws, error):
        print(error)