August 17, 2009

300 words 2 mins read

PHP & CURL – Expectation Failed

I’ve been doing some reasonable amount of programming as of late, working for miscellaneous projects around the Wikimedia universe. I’ll announce the specific projects as I get things to a “finished” or releasable point. For now I thought I’d tease you with random bits of “fun” I encounter when working with PHP.

Today’s posting is not the failure of PHP to live up to my expectations, it is about HTTP Error 417 “Expectation Failed”. I was writing a file upload bot to push images up to Mediawiki sites, and on my local testing environment it worked perfectly. I then re-pointed the script to upload to Wikimedia Commons and it went all to hell. I started getting HTTP Error 417, which for as long as I’ve been around the net, I had never before seen. I turned on the debug info for curl:

    curl_setopt($ch, CURLOPT_VERBOSE, TRUE);

I watched the headers closely and saw that my application was sending “Expect: 100-continue” and after a bit of googling I found that it was something from the HTTP/1.1 spec on negotiating data upload. This is great, but my application sends that it is playing in HTTP/1.0. Obviously this isn’t a good thing, and it has been known about for a while. Why it still does it, beats me, but there is an easy way to “fix” it in a PHP application:

    curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Expect:' ) );

That’s it.

This way curl will send an empty “Expect:” instead of the full “Expect: 100-continue”, and subsequently it will get ignored by the server you’re talking to. I’ve found that Apache handles this sort of issue gracefully, which is why my local tests worked. The issue is Squid (which the Wikimedia Foundation uses as reverse proxies) which is much more of a stickler for standards compliance.