Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add more headers in websocket python client

I'm trying to send session id (I got it after authentication against http server) over a websocket connection (I'm using python websocket client), I need to pass it as a header parameter, where the server (Tornado Websocket server) will read all the headers and get them checked.

The questions is: how can I add headers to using one of the existing client python Websocket implementations, I find none of them can do that, or am I following the wrong approach in the first place for authentication?

-- Update --, Below a template of the code I use:

def on_message(ws, message):
    print 'message received ..'
    print message


def on_error(ws, error):
    print 'error happened .. '
    print error


def on_close(ws):
    print "### closed ###"


def on_open(ws):

    print 'Opening Websocket connection to the server ... '

    ## This session_key I got, need to be passed over websocket header isntad of ws.send.
    ws.send(session_key)

if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("ws://localhost:9999/track",
                                on_open = on_open,
                                on_message = on_message,
                                on_error = on_error,
                                on_close = on_close, 
                                )
    ws.on_open = on_open

    ws.run_forever()
like image 508
securecurve Avatar asked Jan 22 '13 09:01

securecurve


People also ask

Can a client have multiple WebSocket connections?

A server can open WebSocket connections with multiple clients—even multiple connections with the same client. It can then message one, some, or all of these clients. Practically, this means multiple people can connect to our chat app, and we can message some of them at a time.

Do WebSockets use headers?

WebSocket extensions and subprotocols are negotiated via headers during the handshake.

Is Python good for WebSockets?

websockets is a library for building WebSocket servers and clients in Python with a focus on correctness, simplicity, robustness, and performance. Built on top of asyncio , Python's standard asynchronous I/O framework, it provides an elegant coroutine-based API.

How do I create a WebSocket client in Python?

WebSocket Client with Python Create a new File “client.py” and import the packages as we did in our server code. Now let's create a Python asynchronous function (also called coroutine). async def test(): We will use the connect function from the WebSockets module to build a WebSocket client connection.


2 Answers

It seems that websocket-client was updated to include websocket headers since this question was asked. Now you can simply pass a list of header parameters as strings:

custom_protocol = "your_protocol_here"
protocol_str = "Sec-WebSocket-Protocol: " + custom_protocol
ws = websocket.WebSocketApp("ws://localhost:9999/track",
                            on_open = on_open,
                            on_message = on_message,
                            on_error = on_error,
                            on_close = on_close, 
                            header = [protocol_str]
                            )

If you are interested in the complete list of valid headers, see the websocket RFC6455 document: https://www.rfc-editor.org/rfc/rfc6455#section-4.3

GitHub Source: https://github.com/liris/websocket-client/blob/master/websocket.py

like image 103
IanTheEngineer Avatar answered Oct 08 '22 01:10

IanTheEngineer


Nothing is more amusing than reading the source code :))

I monkey patched the source code of the Websocket client library to make it able to receive a header as a normal parameter in the initializer, like this:

ws = websocket.WebSocketApp("ws://localhost:9999/track",
                                on_open    = on_open,
                                on_message = on_message,
                                on_error   = on_error,
                                on_close   = on_close, 
                                header     = {'head1:value1','head2:value2'} 
                                )

This can be done by editing 3 lines in the websocket.py source code of the library:

1- Add header parameter:

   ## Line 877
   class WebSocketApp(object):
        """
        Higher level of APIs are provided.
        The interface is like JavaScript WebSocket object.
        """
        def __init__(self, url,
                     on_open = None, on_message = None, on_error = None,
                     on_close = None, keep_running = True, get_mask_key = None, header = None):

self.url = url
        self.on_open = on_open
        self.on_message = on_message
        self.on_error = on_error
        self.on_close = on_close
        self.keep_running = keep_running
        self.get_mask_key = get_mask_key
        self.sock = None
        self.header = header 

2- Then, pass the self.header to websocket connect method as a header parameter, like this:

## Line 732
self.sock.connect(self.url, header = self.header) 

Actually I tried to import the WebSocketApp class, but it didn't work, as the whole websocket.py module is interdependent, that I found myself importing a lot of things to make it work, monkey patching is easier and more solid in this case.

That's all, enjoy using your patched library with all the headers you need.

like image 44
securecurve Avatar answered Oct 08 '22 01:10

securecurve