2016-09-15 18:51:26 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
'''
|
2016-09-16 17:50:55 +01:00
|
|
|
Python WebSocket server base
|
2016-09-15 18:51:26 +01:00
|
|
|
Copyright 2011 Joel Martin
|
|
|
|
Copyright 2016 Pierre Ossman
|
|
|
|
Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
|
|
|
|
'''
|
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
import sys
|
2016-09-15 18:51:26 +01:00
|
|
|
|
|
|
|
# python 3.0 differences
|
2017-11-10 10:18:32 +00:00
|
|
|
try:
|
|
|
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
|
|
except ImportError:
|
|
|
|
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
|
2016-09-15 18:51:26 +01:00
|
|
|
|
|
|
|
from websockify.websocket import WebSocket, WebSocketWantReadError, WebSocketWantWriteError
|
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
class WebSocketRequestHandler(BaseHTTPRequestHandler):
|
|
|
|
"""WebSocket request handler base class.
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
This class forms the base for a server that wishes to handle
|
|
|
|
WebSocket requests. It functions exactly as BastHTTPRequestHandler,
|
|
|
|
except that WebSocket requests are intercepted and the methods
|
|
|
|
handle_upgrade() and handle_websocket() are called. The standard
|
|
|
|
do_GET() will be called for normal requests.
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
The class instance SocketClass can be overridden with the class to
|
|
|
|
use for the WebSocket connection.
|
|
|
|
"""
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
SocketClass = WebSocket
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
def __init__(self, request, client_address, server):
|
|
|
|
BaseHTTPRequestHandler.__init__(self, request, client_address, server)
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
def handle_one_request(self):
|
|
|
|
"""Extended request handler
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
This is where WebSocketRequestHandler redirects requests to the
|
|
|
|
new methods. Any sub-classes must call this method in order for
|
|
|
|
the calls to function.
|
2016-09-15 18:51:26 +01:00
|
|
|
"""
|
2016-09-16 17:50:55 +01:00
|
|
|
self._real_do_GET = self.do_GET
|
|
|
|
self.do_GET = self._websocket_do_GET
|
|
|
|
try:
|
|
|
|
BaseHTTPRequestHandler.handle_one_request(self)
|
|
|
|
finally:
|
|
|
|
self.do_GET = self._real_do_GET
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
def _websocket_do_GET(self):
|
|
|
|
# Checks if it is a websocket request and redirects
|
|
|
|
self.do_GET = self._real_do_GET
|
2016-09-15 18:51:26 +01:00
|
|
|
|
|
|
|
if (self.headers.get('upgrade') and
|
|
|
|
self.headers.get('upgrade').lower() == 'websocket'):
|
2016-09-16 17:50:55 +01:00
|
|
|
self.handle_upgrade()
|
2016-09-15 18:51:26 +01:00
|
|
|
else:
|
2016-09-16 17:50:55 +01:00
|
|
|
self.do_GET()
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
def handle_upgrade(self):
|
|
|
|
"""Initial handler for a WebSocket request
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
This method is called when a WebSocket is requested. By default
|
|
|
|
it will create a WebSocket object and perform the negotiation.
|
|
|
|
The WebSocket object will then replace the request object and
|
|
|
|
handle_websocket() will be called.
|
2016-09-15 18:51:26 +01:00
|
|
|
"""
|
2016-09-16 17:50:55 +01:00
|
|
|
websocket = self.SocketClass()
|
|
|
|
try:
|
|
|
|
websocket.accept(self.request, self.headers)
|
|
|
|
except Exception:
|
|
|
|
exc = sys.exc_info()[1]
|
|
|
|
self.send_error(400, str(exc))
|
|
|
|
return
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
self.log_request(101)
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
self.request = websocket
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
# Other requests cannot follow Websocket data
|
|
|
|
self.close_connection = True
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
self.handle_websocket()
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
def handle_websocket(self):
|
|
|
|
"""Handle a WebSocket connection.
|
2016-09-15 18:51:26 +01:00
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
This is called when the WebSocket is ready to be used. A
|
|
|
|
sub-class should perform the necessary communication here and
|
|
|
|
return once done.
|
2016-09-15 18:51:26 +01:00
|
|
|
"""
|
|
|
|
pass
|
|
|
|
|
2016-09-16 17:50:55 +01:00
|
|
|
class WebSocketServer(HTTPServer):
|
|
|
|
pass
|