Pithikos / python-websocket-server

A simple fully working websocket-server in Python with no external dependencies
MIT License
1.14k stars 381 forks source link

Support for endpoint in the GET request #52

Open PriyankBangar opened 6 years ago

PriyankBangar commented 6 years ago

Hello, I wanted to add the functionality of supporting an endpoint and assign that as an id to the socket connection, so I made the following changes to your code:

Change in WebSocketHandler class:

def read_http_headers(self):
        headers = {}
        # first line should be HTTP GET
        http_get = self.rfile.readline().decode().strip()
        # Next three lines will get your end_point
        global with_end_point
        if re.search('\/([A-Za-z0-9]+)', http_get).group(1):
            with_end_point = re.search('\/([A-Za-z0-9]+)', http_get).group(1)
        assert http_get.upper().startswith('GET')
        # remaining should be headers
        while True:
            header = self.rfile.readline().decode().strip()
            if not header:
                break
            head, value = header.split(':', 1)
            headers[head.lower().strip()] = value.strip()
        return headers

Change in WebsocketServer class:

def _new_client_(self, handler):
        self.id_counter += 1
        # This if-else block will check if you have provided an end_point and if you have, it assigns that    
        # endpoint as the 'Id' of the socket connection, otherwise it will assign a number as 'Id'
        if with_end_point:
            client = {
                'id': with_end_point,
                'handler': handler,
                'address': handler.client_address
            }
        else:
            client = {
                'id': self.id_counter,
                'handler': handler,
                'address': handler.client_address
            }
        self.clients.append(client)
        self.new_client(client, self)

I would like to ask, is this the correct way of doing it, and if it is, can I send a pull request?

poiuytrezaur commented 6 years ago

Looks like you are using re and forgot to mention this change : import re

poiuytrezaur commented 6 years ago

And here is my implementation :

import re

WebsocketServer class:

    def _new_client_(self, handler):
        self.id_counter += 1
        # Set the endpoint for the client if any
        client = {
            'id': self.id_counter,
            'handler': handler,
            'address': handler.client_address,
            'endpoint': handler.with_end_point
        }
        self.clients.append(client)
        self.new_client(client, self)

WebSocketHandlet class :

    def read_http_headers(self):
        headers = {}
        # first line should be HTTP GET
        http_get = self.rfile.readline().decode().strip()

        # Next three lines will get your end_point
        if re.search('\/([A-Za-z0-9]+)', http_get).group(1):
            self.with_end_point = re.search('\/([A-Za-z0-9]+)', http_get).group(1)

        assert http_get.upper().startswith('GET')
        # remaining should be headers
        while True:
            header = self.rfile.readline().decode().strip()
            if not header:
                break
            head, value = header.split(':', 1)
            headers[head.lower().strip()] = value.strip()
        return headers

This solves the issue I have with Firefox sockets :

Error message :

Exception happened during processing of request from ('127.0.0.1', 55208)                                               Traceback (most recent call last):                                                                                        File "C:\Users\Guillaume\AppData\Local\Programs\Python\Python36-32\lib\socketserver.py", line 696, in __init__            self.handle()                                                                                                         File "D:\Server\websocket_server.py", line 179, in handle                                                                 self.handshake()                                                                                                      File "D:\Server\websocket_server.py", line 314, in handshake                                                              headers = self.read_http_headers()                                                                                    File "D:\Server\websocket_server.py", line 303, in read_http_headers                                                      assert http_get.upper().startswith('GET')                                                                           AssertionError                                                                                                                                                                                                                                  During handling of the above exception, another exception occurred:                                                                                                                                                                             Traceback (most recent call last):                                                                                        File "C:\Users\Guillaume\AppData\Local\Programs\Python\Python36-32\lib\socketserver.py", line 639, in process_request_thread                                                                                                                      self.finish_request(request, client_address)                                                                          File "C:\Users\Guillaume\AppData\Local\Programs\Python\Python36-32\lib\socketserver.py", line 361, in finish_request      self.RequestHandlerClass(request, client_address, self)                                                               File "D:\Server\websocket_server.py", line 168, in __init__                                                               StreamRequestHandler.__init__(self, socket, addr, server)                                                             File "C:\Users\Guillaume\AppData\Local\Programs\Python\Python36-32\lib\socketserver.py", line 698, in __init__            self.finish()                                                                                                         File "D:\Server\websocket_server.py", line 351, in finish                                                                 self.server._client_left_(self)                                                                                       File "D:\Server\websocket_server.py", line 147, in _client_left_                                                          self.client_left(client, self)                                                                                        File "server.py", line 23, in client_left                                                                                 print("Client(%d) disconnected" % client['id'])                                                                     TypeError: 'NoneType' object is not subscriptable 
PriyankBangar commented 6 years ago

Thank you.