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?
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.
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.
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); ?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With