Like many blogs out there, I have spam-checking service Akismet set up to filter out the comment spam. It’s built-in on my Brew Site WordPress blog, but on chuggnutt and Hack Bend it’s using a PHP class that I coded myself.
Up until a few days ago, it’s been working beautifully on my two non-WordPress blogs. But all of a sudden, every spam comment to the two blogs started coming through approved (not marked as spam). Every single one.
Tonight I started poking around my code and the Akismet API to see if anything had changed. According to their API documentation, Akismet should only return two possible values for the spam check: "true" or "false".
I poked around with some cURL tests but that was inconclusive; appropriate testing strings ("viagra-test-123" will always return true) were performing as specified. But when I entered that test string as a comment on my site, it was not flagged as spam. Clearly, something had changed with the API, since the code has been running along just fine since, what, 2006?
So I set my PHP code to give me the raw response from the Akismet server(s), and these are the two results—this is the exact code and return values Akismet is returning:
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 12 Feb 2010 06:39:52 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: close
X-akismet-server: 192.168.7.4
4
true
0
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 12 Feb 2010 06:40:45 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Connection: close
X-akismet-server: 192.168.6.46
5
false
0
Do you see? Akismet has changed their return values. They are no longer simply "true" and "false", they are pre- and appended with digits on separate lines.
Of course, more fool me for coding my PHP to look explicitly for "true" and "false" only—once I saw this, I was able to fix the problem quickly. (Changing the comparison from "string equality" to "string contains".) Spam checking fixed.
The weird thing is, I can’t seem to find anything about this online (other than a comment on another blog so far), and I can’t figure why this is what’s being returned to my PHP while cURL reported only "true" and "false". Perhaps something to do with UTF encoding? Multi-byte strings? I don’t know.
And why now? There have been no server or PHP changes on my end and like I said, it’s been working fine for years. Literally.
Anyway, I posted this here to help out other people potentially having troubles with their Akismet code.
Comments
6 responses to “Akismet changed their return values”
AHA! So it isn’t just me either. I’ve got the same issue on my own blog. I thought I screwed something up somewhere. It’s actually relieving to know it’s coming from their end and not mine.
No idea why they changed the response values, but it completely broke the implementation in the PHP 5 class I got directly off the akismet.com site.
One other thing I noticed in the PHP 5 class I’m using for Akismet.
$this->akismetVersion = ‘1.11’;
That had to be changed to:
$this->akismetVersion = ‘111’;
Basically removing the decimal. Leaving it in was generating 404 errors. So not only did they mess with the responses, they messed with the actual paths on the webserver. It would really have been nice of them to say something somewhere about these changes.
Hi,
Akismet has not changed its API.
What’s happening is:
Your code is making a HTTP/1.1 request.
Akismet is returning a valid HTTP/1.1 response. The extra digits are part of the "chunked" Transfer-encoding in the HTTP/1.1 transport, not part of Akismet’s response.
Your code is failing to parse the valid HTTP/1.1 response.
We’re working on a change that will ensure we always return a HTTP/1.0 response even to a 1.1 request, so as to avoid problems with buggy clients. But the problem is not that we changed our API or failed to tell anyone. The problem is that the PHP5 class you are using is broken: it claims to understand HTTP/1.1 but does not; and it uses an invalid value for $this->akismetVersion. It happened to work in the past only by sheer luck.
The current version of the Akismet PHP5 class hosted at achingbrain.net does not have those problems – it uses HTTP/1.0 and has akismetVersion set correctly to 1.1. We test against it. It works fine.
Kind regards,
Alex
Akismet.com
Roger: I was going to point out the Akismet version "1.1" issue also. The recorded internal version for Akismet in the docs is "1.11", but the version variable in the class specifies the path on the server for the call, which remains "1.1".
Alex: Thanks for the info. I’ve noticed the HTTP/1.1 request is in several other code examples posted on the site as well; you might consider adding a note to the API docs regarding this.
Still, it’s curious that the buggy implementations were working up until about the same time recently; I also noticed a speed performance concurrent with that, and if I’m reading the PHP5 achingbrain.net’s notes correctly, the HTTP/1.1 implementation was yielding slow responses. Did you guys do something with the servers to optimize the HTTP/1.1 handling?
Hi Jon,
We replaced our old http servers with Nginx. For performance reasons, but not specifically for HTTP/1.1.
The old servers would respond to a HTTP/1.1 request with a HTTP/1.1 response that happened to be the same as a HTTP/1.0 response, so the client bug was not visible until now.
@Alex and others on the Akismet dev team, thanks for being patient about this. I’ve got everything worked out now with the correct HTTP/1.0 request and Akismet 1.1 version path.
It would be a good idea to put up some kind of blog post over at akismet.com to point the issue out though. Plenty of the libraries you have linked there use HTTP/1.1 incorrectly, such as the PHP 4 class by Bret Kuhns.