Transparent Proxy for Broadway ( Gtk3 / HTML5 backend )

I’m a big fan of Gtk+. One of the interesting additions since version 3 is the ‘broadway’ backend. Broadway is a rendering backend that lets you distribute your Gtk+ app via a browser. It does this by serving up a simple page with an HTML5 canvas and some Javascript, and then pushes GUI updates over web sockets. It’s an intriguing approach, and very useful if you need to distribute to a bunch of people without installing dependencies ( which is still painful on Windows ).

There are some shortfalls of the broadway component. It only supports a single client per broadway process. If a 2nd client connects to the port broadway is listening on, the 1st client gets disconnected. There is only very simple authentication offered, which is set on a per-user ( ie Linux user ) basis. These 2 issues make it difficult to use broadway in a production environment.

While I hope Gtk+ people will flesh out broadway functionality further, I’ve managed to bring up a proof-of-concept transparent proxy for broadway that goes a long way to addressing the above issues. Here’s how I currently have things working:

  • A simple authentication page at /auth does application logins. I’ve implemented this in PHP, just to remind myself how much I hate it 🙂 Successful logins result in:
    • A new broadwayd process being launched on an available port
    • A new instance of my Gtk+ app being launched, and directed to use the new broadway process we just launched
    • A new random string ( $random_string ) being generated ( eg 20 characters )
    • A cookie being set, auth_key=$random_string
    • A database entry being created that maps the auth_key values to broadway ports – this is timestamped and gets culled regularly
    • Finally, the web client is redirected to /app
  • An nginx reverse proxy that adds https termination, and forwards requests to /app to the port that the transparent proxy is listening on ( I use 10666 )

Next … the proxy code: broadway_proxy.pl

This code is originally by Peteris Krumins ( details in the code ). I’ve modified it slightly, adding the concept of a ‘ConnectionFuture’, which doesn’t need to know ‘in advance’ where a connection is being proxied to.

All the magic happens in the syswrite() method. I pass the incoming buffer to HTTP::Request, so I can parse out the cookie ( if one exists ). You’ll see in the code I then look for a cookie named ‘port’:

if ( $cookies =~ /port=(\w*)/ ) {
    $port = $1;
} elsif ( $cookies = 'cookie1=test' ) {
    $port = 10000;
}

This is obviously a simplification that is looking for the port number directly in the cookie. There is also a check for a cookie named ‘cookie1’, which is hard-coded to port 10000. I’ve done this in the example code so you can quickly verify that the general approach will work for you. You should remove this whole block, and replace with some logic that looks for the auth_key cookie, checks in the database that it exists, fetches the correct port, and sets $port accordingly. As this will depend a lot on your particular environment, I’ve left it as an exercise for the viewer 🙂 You should also add some cleanup code in disconnect() to kill the app process, broadway process, and delete the database entry for the auth_key and port.

There are most likely bugs ( eg we should explicitly disconnect clients that don’t have our cookie, or redirect them to /auth ).

I wondered what performance would be like, with the proxying code having to inspect each incoming request to determine where to redirect it. It’s actually extremely efficient. As luck would have it, there are only a couple of ‘requests’ for the entire duration of a Gtk+ / broadway application. The 1st couple of requests fetch the html and javascript. After that, as the connection is ‘upgraded’ to websockets, all subsequent traffic exists as a part of the same ‘request’, so interacting with the application once it’s started performs as well as a direct broadway connection ( ie no proxy ). There is very low CPU usage for me.

Hopefully this is useful to someone who likes Gtk+ and is looking for a secure way of deploying apps via broadway. Hopefully it also inspires someone more handy in C that I am to implement something like the above in the broadway component itself.

JewelKit-1.0 released

I’m happy to announce another initial release: JewelKit-1.0 – a Windows distribution of Perl, Gtk3, and bindings ( which are the “glue” between the Perl language and the Gtk3 toolkit ). Gtk3 developers rejoice! Details of the project are in the ‘permanent’ WordPress page ( as opposed to these ‘posts’ ).

Powercom-Utils-1.1 released

I’ve just released version 1.1 of my powercom-utils. This release mainly brings some greatly improved graphing code ( I don’t use any graphing libraries – I use Cairo directly ).

graph

Full changelog:

  • New configs for the graph’s min and max hour.  The previous method of calculating the min & max per day  meant that the start & end of the graph represented a different  time for each day’s readings, making it hard to compare across days
  • Changed calculation of X position in graph to use a ‘minutes past earliest’ concept – the earliest being a config option
  • Render graphs with a Cairo gradient – looks much nicer
  • Added vertical and horizontal lines from each X & Y axis label
  • Fixed position of X & Y axis labels
  • Summary and details datasheets are now next to each other – they don’t take up much horizontal space. Added a vertical pane to hold these 2 datasheets
  • Added a horizontal pane to hold the graphs and datasheets
  • Started decimal place formatting in datasheets

You can download the latest version from the links down the right-hand side of the page.

Gtk3::Ex::DBI-3.1 released

Hot on the tails of the tech-preview of the stand-alone Datasheet library released earlier, I’m proud to now release the next major incarnation of my cross-platform RAD libraries for database development, Gtk3::Ex::DBI.

This release is a culmination of many years of hacking and contains over 700 individual commits. It drives the GUIs of a number of production systems currently in use. Major features in this release:

  • Ported from Gtk2 to Gtk3
  • Added support for Netezza
  • Added preliminary support for Teradata
  • Added proper support for non-autoincrementing primary keys, and non-numeric primary keys
  • Added more hooks for events ( eg on_delete etc )
  • Added support for autoconstruction of recordset tool buttons, eg Add, Delete, etc, and record navigator spin buttons
  • Merged Form and Datasheet functionality into a single package
  • Many, many bug fixes and optimisations

This release has been extensively tested using Gtk3’s new Broadway backend, which renders the GUI in HTML5. This means deployment to Windows desktops can be simplified considerably; no installation of software is necessary, and users can just point their browsers to a port that broadway ( and the app ) is running on.

I’m working on a Broadway session manager, which I’ll be releasing as soon as it’s ready. This utility will be able to launch new instances of broadway and Gtk3 apps when a web user successfully authenticates.

I’ll be posting HOWTOs on using Gtk3::Ex::DBI in the coming weeks / months – time permitting.

You can download the latest version of Gtk3::Ex::DBI using the links on the right, or from CPAN.