<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>iridani.com &#187; curl</title>
	<atom:link href="http://iridani.com/tag/curl/feed/" rel="self" type="application/rss+xml" />
	<link>http://iridani.com</link>
	<description>dev://james.stansfield</description>
	<lastBuildDate>Mon, 26 Jul 2010 21:52:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Expect: php curl should play nice</title>
		<link>http://iridani.com/2009/04/expect-php-curl-should-play-nice/</link>
		<comments>http://iridani.com/2009/04/expect-php-curl-should-play-nice/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 13:06:43 +0000</pubDate>
		<dc:creator>jqs</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[dev]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://iridani.com/?p=56</guid>
		<description><![CDATA[<img src="http://iridani.com/wp-content/icons/125X75/wordpress.png" width="125" height="75" alt="" title="Blog" /><br/>Once again, my job has me writing mutli-threaded PHP1 scripts that use PHP&#8217;s CURL2 library to connect to remote servers. (I&#8217;m calling an API here!)  Without going into too much detail, the networking specifics changed between me and the api server, adding a new, or newly reconfigured, invisible proxy to the data path.
This proxy is [...]]]></description>
			<content:encoded><![CDATA[<img src="http://iridani.com/wp-content/icons/125X75/wordpress.png" width="125" height="75" alt="" title="Blog" /><br/><p>Once again, my job has me writing mutli-threaded PHP<sup><a id="fn-56-1" href="#foot-56-1" onclick="new Effect.ScrollTo('foot-56-1', {offset:-140}); return false">1</a></sup> scripts that use PHP&#8217;s CURL<sup><a id="fn-56-2" href="#foot-56-2" onclick="new Effect.ScrollTo('foot-56-2', {offset:-140}); return false">2</a></sup> library to connect to remote servers. (I&#8217;m calling an API here!)  Without going into too much detail, the networking specifics changed between me and the api server, adding a new, or newly reconfigured, invisible proxy to the data path.</p>
<p>This proxy is running Lighttpd, while light in name, is starting to throw around it&#8217;s weight and get in my way.</p>
<p>Warning! We are going to get technical!</p>
<p><span id="more-56"></span>Here is the output of curl when trying to access the api. (All ip addresses have been obfuscated to protect the innocent!)</p>
<p>[cc]</p>
<p>* About to connect() to theapi.com port 80 (#0)</p>
<p>*   Trying 42.42.42.42&#8230; * connected</p>
<p>* Connected to theapi.com (42.42.42.42) port 80 (#0)</p>
<p>> POST /ApiCommand HTTP/1.1</p>
<p>Host: theapi.com</p>
<p>Accept: */*</p>
<p>Content-Length: 1760</p>
<p>Content-Type: application/x-www-form-urlencoded</p>
<p>Expect: 100-continue</p>
<p>< HTTP/1.1 417 Expectation Failed</p>
<p>< Connection: close</p>
<p>< Content-Length: 0</p>
<p>< Date: Mon, 20 Apr 2009 14:16:26 GMT</p>
<p>< Server: lighttpd/1.4.1</p>
<p><</p>
<p>* Closing connection #0</p>
<p>[/cc]</p>
<p>Wow, that was short lived. The culprit here is that lighttpd doesn't handle the <em>Expect: 100-continue</em> properly. In fact it cacks on it entirely. What you get (if you aren&#8217;t looking at headers) is an empty response from curl. Not very fun to debug if you were expecting some kind of response from the api.</p>
<p>It has been suggested <sup><a id="fn-56-3" href="#foot-56-3" onclick="new Effect.ScrollTo('foot-56-3', {offset:-140}); return false">3</a></sup><sup><a id="fn-56-4" href="#foot-56-4" onclick="new Effect.ScrollTo('foot-56-4', {offset:-140}); return false">4</a></sup> that this bug will be fixed in version 1.5.x but that doesn&#8217;t help us right here, right now<sup><a id="fn-56-5" href="#foot-56-5" onclick="new Effect.ScrollTo('foot-56-5', {offset:-140}); return false">5</a></sup>. So what to do. Who will save me? The internet of course!</p>
<p><strong>gnegg</strong>, amongst others, has run into this problem before me and has a fix<sup><a id="fn-56-6" href="#foot-56-6" onclick="new Effect.ScrollTo('foot-56-6', {offset:-140}); return false">6</a></sup> that solves the problem easily. Just add a blank <em>Expect:</em> header to your curl call. That fixes the problem nice and quick:</p>
<p>[cc lang='php']curl_setopt($ch, CURLOPT_HTTPHEADER, array(&#8216;Expect:&#8217;));[/cc]</p>
<p>And that&#8217;s it, by implicitly setting the Expect: directive we bypass the default condition that CURL injects on every request.</p>
<p>Now I can&#8217;t say exactly what Expect: does, but I think it helps by chopping up data into smaller chunks, but that is a guess and I don&#8217;t feel like looking it up.</p>
<p><strong>Update: I&#8217;m so very wrong!</strong></p>
<p>Philip Hofstetter, who wrote the article on <em>gnegg.ch</em> sent me an email today clearing up my assumption about the Expect: 100-continue HTTP directive:</p>
<blockquote><p>I&#8217;m the author of the blog post on gnegg.ch you referred to and I</p>
<p>wanted to take the oportunity to explain what the idea behind Expect:</p>
<p>100-continue is:</p>
<p>The idea behind Expect: 100-continue is to give the server a chance to</p>
<p>make checks for the requests validity without the client actually</p>
<p>having to send all the data first.</p>
<p>So the clients sends the POST request just as if it would just post</p>
<p>the data, but it leaves the request body completely empty, but adds</p>
<p>the Expect: 100-continue.</p>
<p>The server can now check</p>
<p>- if maybe authentication is needed but not provided</p>
<p>- if the URL in question is even capable of accepting a POST request</p>
<p>- if the remote host is permitted to send the data</p>
<p>or what ever else that can be checked independently of the post body.</p>
<p>Now the server either sends back a fitting error code or it sends the</p>
<p>doe 100 telling the client that it&#8217;s ok to go ahead and resend the</p>
<p>request, but this time WITH the request body and WITHOUT the expect</p>
<p>header.</p>
<p>So the idea isn&#8217;t chopping up the data, it&#8217;s making it as sure as</p>
<p>possible to detect early failures without the client having to</p>
<p>transmit all the data first.</p>
<p>I hope that helps to explain what&#8217;s going on.</p></blockquote>
<p>I knew I should have just gone and looked it up! <strong>Thanks Philip!</strong><br />

<div class='footnotes'><span class="footnote" id="foot-56-1">1.&nbsp;<a href="http://php.net">php.net</a><a href="#fn-56-1" onclick="new Effect.ScrollTo('fn-56-1', {offset:-140}); return false">&#8617;</a></span><br /><span class="footnote" id="foot-56-2">2.&nbsp;<a href="http://php.net/manual/en/book.curl.php">php.net/curl</a><a href="#fn-56-2" onclick="new Effect.ScrollTo('fn-56-2', {offset:-140}); return false">&#8617;</a></span><br /><span class="footnote" id="foot-56-3">3.&nbsp;<a href="http://stackoverflow.com/questions/463144/php-http-post-fails-when-curl-data-1024">StackOverFlow.com</a><a href="#fn-56-3" onclick="new Effect.ScrollTo('fn-56-3', {offset:-140}); return false">&#8617;</a></span><br /><span class="footnote" id="foot-56-4">4.&nbsp;<a href="http://redmine.lighttpd.net/issues/show/1017">redmine.lighttpd.net</a><a href="#fn-56-4" onclick="new Effect.ScrollTo('fn-56-4', {offset:-140}); return false">&#8617;</a></span><br /><span class="footnote" id="foot-56-5">5.&nbsp;<a href="http://en.wikipedia.org/wiki/Jesus_Jones">Jesus Jones</a><a href="#fn-56-5" onclick="new Effect.ScrollTo('fn-56-5', {offset:-140}); return false">&#8617;</a></span><br /><span class="footnote" id="foot-56-6">6.&nbsp;<a href="http://www.gnegg.ch/2007/02/the-return-of-except-100-continue/">gnegg.ch</a><a href="#fn-56-6" onclick="new Effect.ScrollTo('fn-56-6', {offset:-140}); return false">&#8617;</a></span></div>
]]></content:encoded>
			<wfw:commentRss>http://iridani.com/2009/04/expect-php-curl-should-play-nice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
