Plugwise-2-py with reconnecting websockets

One of the problems with the Plugwise-2-py web application (Plugwise-2-web.py) was that when a computer running a browser with the web client fell asleep, that in the next session the page had to be manually reloaded to get the websocket stream of power readings started again.

This seemed easy to fix, with a timeout call in the javascript or something like that. But before coding this I thought of gooling it. And of course it did already exist.
https://github.com/joewalnes/reconnecting-websocket
It did not only exist, but also got it working within 30 minutes. Reliably! (more…)

SSL/HTTPS – Grade A+ python SimpleHTTPServer

After adding SSL to my HTTPWebSocket server, I found that originally it was not so secure due to the fact the the linux distribution I used did not get essential security updates. I used Qualsys SSL Labs: https://www.ssllabs.com/ssltest/analyze.html to analyze the security level of my server. Well, it started out with ‘grade E’. Finally, I ended up with ‘grade A+’. These are the steps to follow: (more…)

SSL/HTTPS – Secure Web and WebSocket server in python

As a next step, I created a SSL/HTTPS – Secure Web and WebSocket server in python. It can be found in github as wotking example and as (updated) gist:
https://github.com/SevenW/httpwebsockethandler
https://gist.github.com/SevenW/47be2f9ab74cac26bf21

In this post, I described how to setup a python webserver that servers normal webpages, as well as websockets at the same port. In other words, at the same page. I real application using it is the Plugwise-2-py web application. This application can actually switch on and off lights, so there are some demands on its security and robustness.

Enabling SSL/HTTPS in a python webserver is actually very simple. (more…)

WebSocket HTML webserver Python

I have written a HTTP and WebSocket handler in python being able to serve them on one and the same port:

https://gist.github.com/SevenW/HTMLWebSocketHandler.py

Although this sounded very obvious as application, I could not find an example only using standard python 2 (2.7) libraries. There are some WebSocket extensions for well-known python web-server applications such as Tornado.

Background

I wanted to make a web-interface for a python application controlling and reading Plugwise devices from small linux computers suchs as Raspberry Pi, Beagle Bone Black or Odroid U3 or XU. It would add value if it was a standalone webserver, not requiring further installation of something like LAMP, or having the need to copy the to be served files to specific webserver locations. Python has nice HTML page serving in its standard library.

As it had to become a dynamically updating application, I was considering server side events (SSE) or WebSockets. I found a few websocket implementaitons for python, but they all used lower level socket libraries. I tried to get two of them work to serve HTTP and websockets on the same port, but did only get it partially working. The upside was that I was starting to get a deeper understanding of standard python SocketServer, BaseHTTPServer and SimpleHTTPRequestHandler. This has led to a combined HTTP- and WebSocket server, which is able to use the same port.

I was inspired by two earlier implementations:

Jamie Kirkpatrick’s jkp/websocketsserver.py https://gist.github.com/jkp/3136208
Opiate’s SimpleWebSocketServer https://github.com/opiate/SimpleWebSocketServer

Design

In its design it is simply using  SimpleHTTPServer which just acts as a basic webserver responding to GET requests to serve files. This is specialized into a new HTTPWebSocketsHandler which overrides handle_one_request(self) to intercept any request to be able to handle it as websocket communication, once the connection is upgraded to a websocket.

The other method it overrides is do_GET() so it can tap into GET requests to detect a WebSocket upgrade request, and put the handler into the websocket state. For other GET requests, it just calls the super-class handler: SimpleHTTPRequestHandler.do_GET(self)

    def do_GET(self):
        if self.headers.get('Upgrade', None) == 'websocket':
            self.handshake()
        else:
            SimpleHTTPRequestHandler.do_GET(self)

In the Plugwise-2-py application, I further specialize HTTPWebSocketsHandler into class PW2PYwebHandler(HTTPWebSocketsHandler) to handle GET and POST requests, where one normally would use PHP scripts to handle for example AJAX calls. If this specialized class decides not to handle the request, it calls the super class methods.

This handler also implemements overrides for the websocket handling, for example to publish and handle received MQTT messages.

See my github for the plugwise application:

https://github.com/SevenW/Plugwise-2-py