My current Perl Ironman Challenge status is: My Ironman Badge

Tuesday, March 30, 2010

Catalyst::TraitFor::Controller::Ping

So this is a little silly, but I needed a simple method for "pinging" a web app to see if it was up and running. And since for work, this one $client has a whole hell of a lot of apps to monitor, I didn't want to have to script for a bazillion different ways to access these apps. So what is my alternative?

How about role for the root controllers? And so Catalyst::TraitFor::Controller::Ping was born.

That is my solution. And it takes a couple of different configuration options if you want to do a little more than just spit back an HTTP 200. Give a model name and a method name, and it will attempt to gather that model and execute the method name. If it is successful (meaning, it doesn't cause an exception), then you still get back a 200. Otherwise, the status will be 500 and you get the catalyst error page.

I'll talk about the other end next week, but basically I am writing a daemon that takes advantage of this ping role to check statuses, and logs them in a database. And you want access to that information? Well, the third piece is a little Web::Simple magic to write a web service that spits out some JSON. Ideally, I'd like to make POE::Component::Server::PSGI much more resource conservative, and have the daemon+webservice all one thingy, so we will see.

Saturday, March 20, 2010

Modules that need love

So I have been busy with work lately and I haven't had the drive or the time to work on some of my modules.

The other day in IRC, someone mentioned that there were problems with POE::Component::PubSub. And I readily admit that there are likely problems with that module. I had already replaced it with POEx::PubSub. But the problem is this: POE::Component::Jabber was scheduled for an overhaul last summer but I was suddenly employed and my work turn a turn toward something else even more awesome. PCJ's dependencies where the first to go through the conversion largely because I needed the new PubSub while working on the POEx::WorkerPool.

All that said, I never got around to actually taking the plunge with PCJ and doing the needed conversion to Moose and Roles.

So. Some of my modules need some love. POEx::Role::SessionInstantiation specifically was getting some fail reports. That ties into a whole bunch of other modules. Speaking of fail reports, my MooseX::CompileTime::Traits was showing failures on 5.11.x. I need to investigate if I still want my modules to run cleanly on 5.12. POEx::ProxySession particularly could use some real love because I really believe it is the way forward with distributed modern POE versus using old-school IKC.

And I really need to follow through on my promises on POE work with specifically taking the time to being Reflex to my will. This would also include organizing talks for the YAPCs this year.

Anyhow, with a hopeful lull coming up in work soonish, I might get the time to improve the state of the art. And maybe even take the time to take ownership of that module that mst was pushing some weeks ago. I know I owe him a test for Web::Simple that involved an odd combination for the signature of a particular dispatch.

All Perl modules need love. I encourage people that read the Ironman feed to step up and spread some love to your favorite modules. Anything from doc patches, to tests, to feature implementations, no one I know ever turns down work on their projects. In the end, we end up using each other's modules to deliver high-end performing solutions to our clients and partners. Let's make sure we give back.

Wednesday, March 10, 2010

Of Exquisite Nerd Hackery

DISCLAIMER: The following post is for educational purposes only. This post details circumvention of a registration function in a popular flash game. The author does not condone copyright infringement. The author paid for the game and encourages others to support independent developers.

And so our journey begins. Robokill is an awesome game. It is like Legend of Zelda with guns. I sunk some time into it last night. Just ask my wife, I was cursing up a storm because one of the levels was being a bitch to finish. In other words, I ♥ Robokill.

But then came to the end of the demo. Up popped the REGISTER ME screen in the game asking for an email address. Hrm. Odd. So I plunk down "test@test.com" just to see what would happen. It failed obviously, but Firebug happened to be on and I saw just exactly what kind of request was being sent and the response it was getting. It was just a dumb HTTP GET with the email and a salt in the URL like so:


And the response as just plain text:
test@test.com is not a registered email address! caccabad


Wait. What? That's all? The gears started turning at this point.

What if I could somehow subvert that request and return a valid result? And what does a valid result even look like? First thing is first, I need to make sure DNS points to somewhere I control.

I logged into the local fileserver. Here at home, I am running dnsmasq which is an awesome little utility that provides DHCP services, and local DNS + forwarding. I added an address for www.rocksolidarcade.com and point it back to this machine.

Next step was to actually respond to the request. This is when I thought of mst's wonderful Web::Simple. So my first attempt at returning a result was this:


So how did I run this? I mean it looks like a dumb CGI script. Easy. Plack. I simply said:
sudo plackup -p 80 hacks.psgi


(I know running on port 80 while sudo is fail, but remember this is a quick hack. A better solution would have been for me to write some iptables rules to send the traffic to a non-privileged port)

As you can see, I naively thought that perhaps the server was simply hashing the result and returning it. It would need to be something the client can do too. That failed. So I tried other combinations of things and ultimately wasn't able to make any headway.

Then another bright idea came to mind, what if I decompiled the .swf and peered inside the action script to see what it doing? So I downloaded a couple of flash decompilers and installed them in a windows vm. The first one was lame and wouldn't let me see the action script at all without paying (har har). The second one was much more generous though. It let me look but not copy the code. WIN.

So take a peak inside and what do I see? Something like this:


Nuh-uh. Really? That dumb?

So I adjust my code like so:


And like magic it works.

The last step in the process for me is to be able to play the game offline. So I try to load the .swf directly in the browser. So far so good. Even the register check still works. But when I go to press "Start" it wants to popup a window and take me back to their website. Well that is dumb. I want to play it offline.

So back into the decompiler I go and I find another tidbit that is explicitly checking the URL for their domain name. Huh. So I adjust my Web::Simple app one last time to search up the file directly:


Now it works whenever I want. But was it really worth my time and effort? No. All in all, it took me about 1.5 hours from start to finish (knowing nothing about Web::Simple, Plack, and futzing with flash decompilers). It would have been much easier to just go get the credit card from the wallet in the other room and pay them the ten bucks first instead of showing off my 1337 skillz. That said, this morning, I did pay them for their wonderful game:

Tuesday, March 2, 2010

Encouraging Contributors

I think one of the most awesome things about doing open source/free software work is working with others toward a common goal. Of course, when you hold the reins of a projects you can't do everything to please everyone. So the simplest course of action is to encourage people to write failing tests for the functionality they would like to see.

This is surprisingly effective for getting regular, active contributors. Of course, once the test is written, and the contributor is confident it tests what they want it to test, it is a simple hop to peering into the code itself and making their own test pass. And usually all that takes is guiding the new found contributor in the right direction: "Oh, your testing for stuff in Flarg.pm, you know, you could probably add that easily if you do X".

I think that near-instant gratification is important and it makes herding the cats that much easier. It makes my life that much easier and I am sure I make other people's lives easier when I participate in the same fashion.

That said, Perl has a great testing culture developed that makes it very easy to cast the "Write me a test" net, far and wide. Plunk down a new t/foo.t, and fire it off with prove -l. No need to spin up a gigantic harness to make the magic happen.

mst is (in)famous for getting work out of people by suggesting projects and ideas to others. Even going as far as private messaging me on IRC about an orphaned module that could use some POEx::SessionInstantiation lovin'. And his method for encouraging contributors is equally as valid and important as well.

In the grand scheme of things, we are all trying to make software development easier. Perl, CPAN, its culture of testing, the community at large-- It all just makes it that much better.