Annoyances: vBulletin Version Check

I hate vBulletin. I really, really, really hate vBulletin, and as much as I’d like to pin it on their apparent disdain for K&R coding style (curly braces should, in my opinion, always be on the same line as the if statement to which they are bound) or their awful code in general, I’m afraid I can’t. Mostly, my experiences have been with vBulletin 3 and 4, but while I have no experience with vBulletin 5, I can’t imagine it’s any better.

vBulletin represents everything that is wrong with the PHP development community as a whole. Or rather, everything from the earliest, darkest ages of PHP antiquity that I’d rather just fade away. It’s 2015, and there’s absolutely no reason to continue encouraging people to do stupid, idiotic things when there’s plenty of fantastic documentation out there that would be much better reading for new developers.

Sadly, though, we have to contend with what have rather than what we want.

(Aside: XenForo isn’t much better, but at least they’re using the Zend Framework and provide at least something of a fa├žade that they might actually know what parameterized statements are.)

Today, I wasted about 15-20 minutes on a confounding problem with a vBulletin plugin. The version check URL wasn’t working–at all. Why? Well, there’s the rub, isn’t it? Here’s what I had done: I put an XML file containing the appropriate nonsense for plugin versioning (which would fail XML validation, but that’s besides the point) with nginx sitting in front, pointed vBulletin at the URL, and… nothing.

What the…?

After some fiddly rubbish, I finally ran Wireshark to see what was going on. Lo and behold, it was obviously much more work to host some simple version checking nonsense than to just throw in a static page:

POST /some/path/to/version.xml HTTP/1.0
Host: example.org
User-Agent: vBulletin Product Version Check
Content-Length: 0
 
HTTP/1.1 200 OK
Server: nginx/1.8.0
Date: Tue, 28 Jul 2015 22:27:25 GMT
Content-Type: text/xml
Content-Length: 52
Last-Modified: Tue, 28 Jul 2015 22:21:13 GMT
Connection: close
ETag: "55b80059-34"
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
 
<version productid="test_product">1.0.0</version>

Did one of their developers read somewhere that POST is somehow better than GET? Not only did this violate the principle of least surprise (for me at least), but it also flies in the face of HTTP verb standards. GET is generally expected to be used for repeatable requests with no side effects. POST is generally expected to be used for requests that create a resource or otherwise perform tasks that have side effects. A version check should not, in my opinion, have side effects since the only reason for doing such a thing is to check the damn version in the first place.

An even more egregious problem in this particular case is the lack of any post data. Seriously, look! Content-Length: 0. Nothing. Nada. Zero. Why would you do this? Do I have to write some kind of script just to handle a stupid version check that does nothing but look here, examine the number, and say “Oh, hey, guess I better not update. It’s still the same!”

No. Or rather, Hell, no.

I hate to abuse nginx’s config for something of this nature, but since I haven’t finished setting up a distribution framework for these plugins, all I wanted to do was push some static files indicating the current version somewhere. So, after a cursory search, here’s what I stumbled on:

error_page 405 =200 $uri;

If nginx would otherwise return a “405 Method Not Allowed,” we redirect it to the URL we were going to retrieve anyway, and return that. It’s a horrible workaround, and there’s probably better, but I shouldn’t have to do this in the first place.

I suppose I could understand it if you were passing along some sort of token with the version check, perhaps for client identification or similar, but in this case it’s just used to determine whether a plugin has outstanding updates ready. Let’s GET real, people. Stop abusing HTTP verbs.

Oh, and that tag (yes, you know which one) is an inside joke. I’m not allowed to repeat it in mixed company.

No comments.
***