Webhooks behind the firewall with Reverse HTTP
With the growing popularity of building webhooks to link applications together, and the stunning ease of building web applications with lightweight web frameworks in various languages (such as Sinatra in Ruby), the thorny issue of NAT-firewalls remains a substantial dampener on development ease. Enter another use for Reverse HTTP. With Reverse HTTP, applications running behind a firewall can be attached to a public server without any firewall changes, and accessed as if they belonged to the public server.
Brought to you through the magic of the Ruby Rack interface, I’d like to announce Hookout. Hookout provides an adapter for Rack-based ruby applications to make the application directly available to the outside world via a Reverse HTTP server.
As an example, take the GitHub post-receive hook sample detailed in their documentation at http://github.com/guides/post-receive-hooks. It consists of a ruby app (for this example, call it github-hook.rb):
require 'rubygems'
require ’sinatra’
require ‘json’
post ‘/github’ do
push = JSON.parse(params[:payload])
puts “I got some JSON: #{push.inspect}”
”Ok”
end
And you’ll also want a rackup configuration file (call it config.ru):
require 'github-hook'
set :run, false
run Sinatra::Application
Before you can run this with Reverse HTTP, you’ll need to install the hookout gem. Assuming that you have a working Ruby environment, install the dependencies then Hookout itself. (Note that the gem sources line is only required if you’ve never installed gems from github before):
sudo gem install sinatra thin
sudo gem sources -a http://gems.github.com
sudo gem install paulj-hookout
To run this, come up with a novel name (eg, mygithub-hook), and execute:
hookout -a http://www.reversehttp.net/reversehttp -n mygithub-hook -R config.ru start
(Note, if you don’t pick a novel name and change the -n statement, then it is possible you might clash with someone else on the server. If things don’t work as expected, pick a new name and try again…)
Once the app starts, you should see a line reading:
Bound to location http://mygithub-hook.www.reversehttp.net/
Go to a Github project you have control over, enter the Admin section, then the Service Hooks subsection. From here, you can add a reference to your hook (http://mygithub-hook.www.reversehttp.net/github). Hit Update Settings, then click “Test Hook”. After a few seconds, you should see the details of the GitHub test appear in your console. Your webhook has just worked from behind a firewall!
Hookout is available on GitHub at http://github.com/paulj/hookout/tree/master.

Webhooks behind the firewall with Reverse HTTP | dv8-designs
on 22/07/09 at 11:42 am
[...] the firewall with Reverse HTTP July 22nd, 2009 admin Leave a comment Go to comments Webhooks behind the firewall with Reverse HTTP. Hookout is a Ruby / rack adapter that lets you serve a web application from behind a firewall, by [...]
roger
on 22/07/09 at 9:12 pm
looks great! but can’t get it to work with jruby though. do you have any suggestions ?
paulj
on 23/07/09 at 5:01 pm
The actual code itself is relatively simple - I’d suspect that the problem is with Thin not being available on JRuby (https://thin.lighthouseapp.com/projects/7212/tickets/13-get-working-on-jruby). The Hookout code currently uses Thin for two things - the HTTP parser component and as management for daemonization when run with the command line. The actual Reverse HTTP connector is free of these dependencies however, so it would be entirely possible to use a more JRuby dependency for the other parts.
Tony Garnock-Jones
on 23/07/09 at 8:07 pm
One possibility for JRuby might be to use reversehttp’s java classes: http://github.com/tonyg/reversehttp/tree/master/priv/java/src/main/java/net/reversehttp
selem
on 18/08/09 at 6:48 pm
have you tried tihs with file uploads? small files are ok, but anything larger than 500k gives an error.
Steve Hawkins
on 27/10/09 at 9:12 pm
Thanks for this! This is genius. I’ve been playing with this Ruby/Hookout/Sinatra example and my mind is blown away by the possibilities it opens up. As an example: mobile data synchronization to an application behind a firewall. You establish a unique reversehttp listener from the application behind the firewall. From the mobile device you push data to a cloud database, then subsequently fire a request to the public reversehttp address. This is caught behind the firewall and the application wakes up and gets the data from the cloud. No polling!
Of course, I could also get rid of the cloud database entirely by enhancing the interface of the ruby app.
paulj
on 28/10/09 at 9:36 am
Great to hear that you’re getting some use out of it!