http://www.perlmonks.org?node_id=1011193

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I need to inteface to a few websites that use Socket.IO for data transport between their backend Node.JS server and the client's browser. I need to log all chat messages and sometimes send responses to the server. The websites use SSL so I can't use a proxy to intercept the messages, and they also don't permit multiple logins, so I can't use a separate program to do the automation if I want to interact with the website with my browser at the same time.

This is a much simpler Socket.IO chat example similar to the the websites which I have to interface to: https://node-yapp.rhcloud.com/. So for this example I'd want to capture the data argument from the addMessage function.

I'm looking for a way to use WWW::Mechanize::Firefox to automate this, but none of the available examples resemble this use case. There is an example that listens for progress events, but I don't think I can use that here.

The only other solution I can figure out is to use Greasemonkey to wrap the target javascript function inside my own function that would then post the data with GM_xmlhttpRequest to a local webserver which would write it to the logfile and return any data that should be sent back to the website's server. This seems like a more complicated solution so I am hoping somebody can suggest a simpler solution with WWW::Mechanize::Firefox, MozRepl::RemoteObject, or something I haven't even thought of.

  • Comment on Listening for Socket.IO events with WWW::Mechanize::Firefox

Replies are listed 'Best First'.
Re: Listening for Socket.IO events with WWW::Mechanize::Firefox
by Corion (Patriarch) on Jan 02, 2013 at 09:25 UTC

    If you don't want to go the route of custom certificates and an SSL-stripping proxy as suggested by Anonymous Monk, I would simply inject my own callbacks into the page. There should be examples in MozRepl::RemoteObject and/or WWW::Mechanize::Firefox::Examples somewhere how to trigger a Perl callback from Javascript, but the general gist of it should be that you don't need to think about details:

    my $socket_io_handlers = $mech->repl->expr('variable_that_handles_the_ +callbacks'); $socket_io_handlers->{on_chat} = sub { print "socket.io: Got " . Dumper \@_; };

    This approach won't handle callback chaining in a nice way. For that, you'll have to use a proper Javascript function and inject that instead:

    my $create_tee = $mech->repl->declare(<<'JS'); function (next_handler, perl_handler) { next_handler.apply(arguments); perl_handler.apply(arguments); }; JS my $old_handler = $socket_io_handler->{ on_chat }; my $new_handler = $create_tee->( $old_handler, sub { print "socket.io: + " . Dumper \@_ }); $socket_io_handler->{ on_chat } = $new_handler;
Re: Listening for Socket.IO events with WWW::Mechanize::Firefox
by Anonymous Monk on Jan 02, 2013 at 06:39 UTC

    he websites use SSL so I can't use a proxy to intercept the messages

    Sure you can