2015-07-14

Publishing server-side code with Git and Bitbucket

As a security researcher with a background in software development, I write lots and lots of code. Most of it takes the form of small and fairly short-lived scripts: proofs-of-concept, quick demos, and highly specific single-purpose tools. And with my platform of choice being the web, I often need to host that code somewhere. Sometimes localhost might be enough, but if I want to show my demo to someone else, it won't do. And for some things you just need a public URL for them to work.

With client-side code, I might head for JSFiddle or CodePen, especially if my need is just sharing a demo with someone on the other side of the planet. But both of them are pretty terrible if you need to do anything even slightly more complicated, and they quickly become unusable if your code is something that's actually designed to break things. Iframes tend to interfere with demo code, CodePen likes to update pages automatically, which break things, and you just can't use JSFiddle at all on mobile. For some types of things they're fine, though.

For my larger projects' source code repositories my choice has for a while now been Bitbucket, simply because they give you an unlimited number of private repositories for free. I like Git, but the thing with Bitbucket is, it's just for source code.

Well, actually, it's not. You can also host static websites on Bitbucket as well, just like you can on GitHub Pages. That's already way better than using one of the JavaScript playground websites; you get to use your own code editor, can publish with a simple git push, and as a bonus, automatically get changelogs of everything you do. But it still won't run server-side code, and Bitbucket also injects JavaScript into your HTML pages to do analytics, which is just as bad as all the iframe stuff on the playground websites.

If you want to run server-side code, really the only choice is getting proper web hosting.

I've had cheap PHP hosting for a while already, but I never really put it into any use. Previously I had a static website in place of this blog and used the hosting for that. I would have used it to host my code snippets, except for one issue: uploading stuff was a serious pain. The archaic web UI from some time before the era of Web 1.0—possibly written by the same people who brought us the 1994 version of Microsoft.com—was the worst piece of UX I've ever come across. If only there were a better way.

If only I could sync my Bitbucket repo with the web hosting service.

Turns out Bitbucket has a pretty decent API. Basically every single piece of data is behind a simple HTTP request, from repository details to SSH keys to user account details. Authentication is done with either OAuth or HTTP Basic, and public data can be accessed with no authentication at all. Multiple response formats. No special API keys or any other weirdness required.

My need was extremely simple, and after a quick search through the API methods I had exactly what I wanted:

GET repositories/{accountname}/{repo_slug}/src/{revision}/{path}

To keep things simple I decided to go with the HTTP Basic authentication. I created a new repository and a fresh Bitbucket account to use with the API, and gave the new account read-only access to the repo. After that, all I had left was setting up a subdomain for the site and typing out a few lines of PHP.

I used mod_rewrite to map request paths to a GET parameter. Then, after a couple of lines of input validation, the API call:

$response = file_get_contents("https://$USER:$PASS@bitbucket.org/api/1.0/repositories/$REPO/src/master/$path");

Parse the response, map the file extension to a MIME type, add some simple caching, and voilĂ ! All in no more than 65 lines of code. The result can be seen at lab.igi.tl. There's not much there right now, of course, but in the future it'll become the home for a whole lot of interesting code snippets.

No comments:

Post a Comment