13

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 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()
1
  • Can you add some code to your question? It will be good if you can add a SSCCE sscce.org Commented Jan 22, 2013 at 9:16

2 Answers 2

14

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

Sign up to request clarification or add additional context in comments.

4 Comments

This one didn't work, that's why I added the source code modification .. unless you tested it yourself and it worked for you
Yes, I've successfully tested it. I looked at the changes to the source since your answer in January, and since then they've fixed the non-existent header param, so I thought I'd leave an alternate answer here for future viewers. See source line 773: github.com/liris/websocket-client/blob/master/websocket.py#L773
It also appears to accept a dictionary instead of a list of formatted strings, so you could have used header={'Sec-WebSocket-Protocol': custom_protocol}. This may make for simpler coding.
@securecurve Although your monkey patch answer is inspired (and thanks for sharing) this is now the correct answer to accept.
10

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.

2 Comments

I struggle with similar topic as you. Can i ask you how do you deal with this situation: When you pass session id (from http server) to websocket server, i suppose you check on server side is this session id valid. How do you store this session id? in database? and I am right in assumption that both http server and websocket server needs to use the same pool of id session?
Default value for header argument of WebSocketApp contructor is confusing; header=[] . In fact, it shouldn't be a list but a dictionary.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.