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?
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);
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);
?>