Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I stop cURL from using 100 Continue?

Tags:

So, long story short, I have an AJAX application that uses MVC Web API as the back end. The client however calls from a different domain and uses a PHP proxy file to get around cross-domain request issues.

However, using the PHP proxy, the Web API responds to certain requests with a 100 Continue HTTP header and any requests that get this back take excessive time to complete (we're talking up to 2 mins or so) and can also return a non-valid response.

This appears to be a known issue with cURL and the workaround is commonly cited as inserting the below line to remove the expect: 100 header in the cURL request

Unfortunately, the solution seems to be elusive for me:

$headers = getallheaders(); $headers_new = ""; foreach($headers as $title => $body) {     $headers_new[] = $title.": ".$body; } //$headers_new[] = 'Expect:'; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers_new); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:') ); 

This code works but removes all the other headers (which isn't workable for me as I'm using HTTP basic auth headers to authenticate with the API). You may also notice I tried adding the Expect: to the existing headers, but this didn't help me either.

How can I maintain the existing headers, but also prevent cURL from expecting a 100 continue?

like image 973
jmillar Avatar asked Jan 04 '13 14:01

jmillar


People also ask

What does expect 100 continue do?

The client will expect to receive a 100-Continue response from the server to indicate that the client should send the data to be posted. This mechanism allows clients to avoid sending large amounts of data over the network when the server, based on the request headers, intends to reject the request.

What is 100 continue behavior?

The HTTP 100 Continue informational status response code indicates that everything so far is OK and that the client should continue with the request or ignore it if it is already finished.


2 Answers

Using $headers_new[] = 'Expect:'; does work unless the $headers_new array contains a string that is 'Expect: 100-continue'. In this case you need to remove it from the array otherwise it will be expecting the 100 continue (logically).

Because in your code you use getallheaders() and you're not checking if it contains an Expect: 100-continue header already so this probably is the case in your case.

Here is a summary for the general situation (and the script that created it):

PHP Curl HTTP/1.1 100 Continue and CURLOPT_HTTPHEADER  GET request ..........................................: Continue: No GET request with empty header ........................: Continue: No POST request with empty header .......................: Continue: Yes POST request with expect continue explicitly set .....: Continue: Yes POST request with expect (set to nothing) as well ....: Continue: Yes POST request with expect continue from earlier removed: Continue: No 

Code:

<?php  $ch = curl_init('http://www.iana.org/domains/example/');  function curl_exec_continue($ch) {     curl_setopt($ch, CURLOPT_HEADER, 1);     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);     $result   = curl_exec($ch);     $continue = 0 === strpos($result, "HTTP/1.1 100 Continue\x0d\x0a\x0d\x0a");     echo "Continue: ", $continue ? 'Yes' : 'No', "\n";      return $result; }  echo "GET request ..........................................: ", !curl_exec_continue($ch);  $header = array(); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "GET request with empty header ........................: ", !curl_exec_continue($ch);  curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, array('hello')); echo "POST request with empty header .......................: ", !curl_exec_continue($ch);  $header[] = 'Expect: 100-continue'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "POST request with expect continue explicitly set .....: ", !curl_exec_continue($ch);  $header[] = 'Expect:'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "POST request with expect (set to nothing) as well ....: ", !curl_exec_continue($ch);  unset($header[0]); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "POST request with expect continue from earlier removed: ", !curl_exec_continue($ch); 
like image 185
hakre Avatar answered Oct 07 '22 04:10

hakre


Thanks for the script, Hakre. Since I needed this for HTTP PUT, I extended it a bit with the following results:

GET request ..........................................: Continue: No GET request with empty header ........................: Continue: No POST request with empty header .......................: Continue: Yes POST request with expect continue explicitly set .....: Continue: Yes POST request with expect (set to nothing) as well ....: Continue: Yes POST request with expect continue from earlier removed: Continue: No PUT request with empty header ........................: Continue: Yes PUT request with expect continue explicitly set ......: Continue: Yes PUT request with expect (set to nothing) as well .....: Continue: Yes PUT request with expect continue from earlier removed : Continue: No DELETE request with empty header .....................: Continue: Yes DELETE request with expect continue explicitly set ...: Continue: Yes DELETE request with expect (set to nothing) as well ..: Continue: Yes DELETE request with expect continue from earlier removed : Continue: No 

Here's the script:

<?php   $ch = curl_init('http://www.iana.org/domains/example/');  function curl_exec_continue($ch) {     curl_setopt($ch, CURLOPT_HEADER, 1);     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);     $result   = curl_exec($ch);     $continue = 0 === strpos($result, "HTTP/1.1 100 Continue\x0d\x0a\x0d\x0a");     echo "Continue: ", $continue ? 'Yes' : 'No', "\n";      return $result; }  // --- GET  echo "GET request ..........................................: ", !curl_exec_continue($ch);  $header = array(); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "GET request with empty header ........................: ", !curl_exec_continue($ch);  // --- POST  curl_setopt($ch, CURLOPT_POST, TRUE);  curl_setopt($ch, CURLOPT_POSTFIELDS, array('hello')); echo "POST request with empty header .......................: ", !curl_exec_continue($ch);  $header[] = 'Expect: 100-continue'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "POST request with expect continue explicitly set .....: ", !curl_exec_continue($ch);  $header[] = 'Expect:'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "POST request with expect (set to nothing) as well ....: ", !curl_exec_continue($ch);  unset($header[0]); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "POST request with expect continue from earlier removed: ", !curl_exec_continue($ch);  // --- PUT  curl_setopt($ch, CURLOPT_PUT, TRUE);  $header = array(); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "PUT request with empty header ........................: ", !curl_exec_continue($ch);  $header[] = 'Expect: 100-continue'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "PUT request with expect continue explicitly set ......: ", !curl_exec_continue($ch);  $header[] = 'Expect:'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "PUT request with expect (set to nothing) as well .....: ", !curl_exec_continue($ch);  unset($header[0]); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "PUT request with expect continue from earlier removed : ", !curl_exec_continue($ch);  // --- DELETE  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");  $header = array(); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "DELETE request with empty header .....................: ", !curl_exec_continue($ch);  $header[] = 'Expect: 100-continue'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "DELETE request with expect continue explicitly set ...: ", !curl_exec_continue($ch);  $header[] = 'Expect:'; curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "DELETE request with expect (set to nothing) as well ..: ", !curl_exec_continue($ch);  unset($header[0]); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); echo "DELETE request with expect continue from earlier removed : ", !curl_exec_continue($ch);  ?> 
like image 41
Xenonite Avatar answered Oct 07 '22 05:10

Xenonite