December 8, 2013

Copy Pasta for Amazon’s Cloud Reader

Tinkering with ImpactJS, I wanted to copy an example from the book, but Amazon’s Cloud Reader has that on lock down… or so they thought. Using Firebug and FireQuery I was able to dig through the html to find the contents I needed. It is quite the deep dive, jumping though 2 iframes to get to the meat of the page. The following jQuery brick will grab the text of the presently viewed section:

$('body div.KindleAppContainer:visible:first iframe').contents().contents().find('div #kindleReader_content iframe#column_0_frame_1').contents().contents().find('body').text()

It returns everything for that section and strips all formating, so you will have to futz with the result to get what you want.

Comments (View)
October 15, 2013

Unpeeling a Maven POM with LockJar

Snagging the deps for a Maven POM and writting it to deps.yml using LockJar

File.open('deps.yml', 'w') { |file| file.write( 
  LockJar.list(resolve: true) { pom 'pom.xml'}.to_yaml ) }

Generates

---
- ch.qos.logback:logback-core:jar:1.0.13
- org.slf4j:log4j-over-slf4j:jar:1.7.5
- org.slf4j:jul-to-slf4j:jar:1.7.5
Comments (View)
July 8, 2013
Comments (View)
July 3, 2013

Rspec helper to add find_or_create to FactoryGirl

Helper for FactoryGirl to allow for find_or_create

Make sure to include the helper in your spec_helper.rb

config.include FactoryGirlHelper

Now in your specs, you can simply:

role = find_or_create(:role, name: 'Admin')
Comments (View)
June 19, 2013
Comments (View)
June 11, 2013

Secure Websockets

If you want to use a Websocket on a page dished out from https you should (and most likely have to) use wss:// to connect. This will have the Websocket connect securely using TLS.

Using stunnel

Stunnel will easily allow you to secure an existing Websocket service. Stunnel accepts secure connections, then proxies them over to the Websocket service. Here is an example stunnel config that securely proxies 8676 to 8765:

But Chrome hates me

The stunnel using the config about works happily with Firefox, but the wss:// connection dies silently with Chrome. Chrome works using the Echo Test. The only thing I can think of is Chrome is not accepting the wildcard cert.

The work around is to force Chrome to use an insecure Websocket, ws://. This works since Chrome does not enforce secure connections. I check the navigator.userAgent to see if the browser is Chrome.

Debugging a Websocket

If you are using the Stilts to talk with Torquebox you can enable logging by adding a debug function to the client:

client.debug = function(msg) { console.log(msg) }
Comments (View)
June 4, 2013

What to do when TB needs SSL using APR

or How acronyms will destroy us all

The Torquebox docs for getting SSL with APR to work are a bit scattered. They reference the JBoss docs for getting SSL to work with Java, unfortunately they only tease. The separate docs for using APR with JBoss explain what is going on, but use the outdated XML config.

To get it working, cram them all together. This leads to changing your standalone.xml so that the subsystem urn:jboss:domain:web:1.2 has native=’true’:

<subsystem xmlns='urn:jboss:domain:web:1.2' default-virtual-server='default-host' native='true'>

and add a connector for https that points at your ssl certs (example points at the default Ubuntu self certs):

<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
   <ssl name="web-ssl" password="secret" certificate-key-file="/etc/ssl/private/ssl-cert-snakeoil.key" certificate-file="/etc/ssl/certs/ssl-cert-snakeoil.pem"/>
</connector>

The total package should look similar to:

<subsystem xmlns='urn:jboss:domain:web:1.2' default-virtual-server='default-host' native='true'>
    <connector name='http' protocol='HTTP/1.1' scheme='http' socket-binding='http'/>
    <connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true">
       <ssl name="web-ssl" password="secret" certificate-key-file="/etc/ssl/private/ssl-cert-snakeoil.key" certificate-file="/etc/ssl/certs/ssl-cert-snakeoil.pem"/>
    </connector>
    <virtual-server name='default-host'>
        <alias name='localhost'/>
        <alias name='example.com'/>
    </virtual-server>
</subsystem>

By default, Torquebox has port 8443 setup to handle https. You know you are in a good place when your http://localhost:9990/console/App.html#web reports https is up and running.

Comments (View)
May 28, 2013

WebSockets: The joys of Instant Gratification

or How I stopped the Curse of the never ending Nag.

If you have built a web site tossing up real time data, most likely it is powered by AJAX requests. You are stuck in the never ending dance of polling. Is there stuff? How about now? Should I come back in 100ms? 200ms? Over the years I have built several of these and there is always a code explosion trying to juggle getting the data as fast as possible without melting the servers with a mound of nagging “Is it done yet”. If only there could be a two way conversation on the same connection.

Trumpet sound Well hello WebSockets. A new protocol for a full duplex TCP connection, meaning a two way conversation in a connection (more trumpet sounds). Now instead of constantly checking for new data, you simply have to open the WebSocket and the data will be pushed as it arrives. Ahh, instant gratification. No nagging for data, it just flies in.

Torquebox makes getting a WebSocket services up and running really easy. This is achieved by using Stomplets and passing data using Stomp. The Stomp messages are passed from the Browser client to Torquebox, which are placed on a queue. The queue doles out the messages to the Stomplet, which handles how the message is processed.

A crude diagram of what is going on:
Stomplet - What is going on

The good news is all of this boils down to a few libraries and some tweaks to Torquebox.

Configuring for WebSockets

For WebSockets to work a few configurations need to be set. First, you will need the latest version of Torquebox, 2.3.1. Next Torquebox needs to control the web session. This enables the session to be passed along with Stomp message, which is important for allow a Stomplet to authenticating a message. For Rails, add an initializer that sets the session_store to :torquebox_store:

# config/initializer/torquebox_init.rb

AppName::Application.config.session_store :torquebox_store 

Next, the Stomplet needs to be configured. This maps the Stomplet to the queue the Stomp messages are sent to. This is set in the Torquebox config, for example using the DSL:

# config/torquebox.rb

TorqueBox.configure do 
   stomplet DemoStomplet do 
     route '/queues/demo' 
   end 
end 

Note: the default port used is 8675

My first Stomplet

With configuration complete, you can add your Stomplet. A client will subscribe, send message(s), receive message(s), and unsubscribe to a queue that is managed by the Stomplet. Fairly straight forward, the Stomplet keeps track of subscribers to the queue, sends messages to the subscribers, and removes them when they unsubscribe. A Stomplet has full access to your Rails stack, Torquebox spins up a separate pool of Rails instances that are used for the Stomplet. This is a simple working demo based on the one from the docs that relays the message sent to all subscribers:

require 'torquebox-stomp' 
class DemoStomplet 
    def initialize() 
        super @subscribers = [] 
    end 

    def configure(stomplet_config) 
    end 

    def on_message(stomp_message, session) 

      # send the message to each subscriber 
      @subscribers.each do |subscriber| 
        subscriber.send( stomp_message ) 
      end 
  end 

  def on_subscribe(subscriber) 

    # add a new subscriber 
    @subscribers &lt;&lt; subscriber 
  end 

  def on_unsubscribe(subscriber) 
    # remove subscriber @subscribers.delete( subscriber ) 
  end 
end 

A more complicated demo Stomplet that shows how to use the session for authentication. Has support for a pass through token to allow local requests, otherwise it checks the User model for an authentication token.

The JavaScript client

With the server set up, now it is time to set up a client. The library stilts-stomp-client.js (Torquebox ships with the lib) handles the work of communicating over Stomp to Torquebox:

// Stomp client for url 
client = Stomp.client("ws://localhost:8675/"); 

// Connect to Torquebox, executing the function when connected 
client.connect("", "", function(frame) { 
  // Subscribe to the demo queue to fire callback 
  client.subscribe("/queue/demo", function(msg) { 
    alert(msg); 
  }); 

  // Send a test message 
  client.send( "/queue/demo", {}, "This is a test of the Demo" ); 
}); 

// Disconnect client on close 
$(window).unload(function() { client.disconnect(); }); 

This will connect to ws://localhost:8675/, subscribe to the /queue/demo queue to fire the callback every time a message is received to open a popup, and then send a test message.

The Ruby client

Similar to the JavaScript client, the stilts-stomp-client gem handles sending the work of sending Stomp messages:

client = StompClient.new( "stomp://localhost:8675/" ) 
client.connect client.send( "/queues/demo", "test" ) 
client.disconnect # this gives an error from the present gem 

The StompClient is an implementation of the Java version and it still a bit rough around the edges. I added support for sending headers and fixed the disconnect error in the Ruby client - (https://gist.github.com/mguymon/5650321).

Victory lap

Now, go have some fun, fire off some message in your rails console and see them instantly appear in the browser. Neat! Normally this sort of step up is a colossal pain the in ass to get chugging along, but I got it all up in running in a few hours.

With making WebSocket this accessible, I look forward to seeing it used more instead of AJAX. Now instead of a dozen AJAX request going out, followed by untold number more sniffing around for new data, a single WebSocket connection could slurp down all the data, updates and all.

Comments (View)
May 8, 2013
Comments (View)
April 22, 2013

Crazy one line bash script to test web ports

Making a web reminder for this crazy one line bash script checks a web port to see if a server has started up yet. Attempts for ~5 minutes before giving up (Torquebox can take a while to boot).

i=0; while ! (curl --retry 0 --connect-timeout 5 --silent http://localhost:3000 | grep sign_in || false) ; do sleep 5; i=`expr $i + 1`; if [ $i -gt 120 ]; then echo "server failed to respond"; break; else echo "no response. . .yet" done

A valid question would be, Why? Well, this is useful for the automated build server (Jenkins) that wants to run acceptances tests on a running instance. This means Jenkins needs to wait for the app server to stand up and accept responsibility for its port.

Heck, here is another web reminder for myself, the kill it dead that scans the process list for the pid, but doesnt fail if the process does not exist:

kill -9 `ps aux | grep torquebox | grep java| awk '{print $2}'` || echo "Torquebox was not running"
Comments (View)