How to add more headers in websocket python client
Question:
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()
Answers:
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.
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
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()
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.
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