What to do with extra HTTP header from proxy? What to do with extra HTTP header from proxy? curl curl

What to do with extra HTTP header from proxy?


The proxy issue is something a lot of scripts are facing. The preferred solution I can find on the internet is to simply add the following lines of code.

<?php// cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" stringif (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {  $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);}?>

Now to add this to the twilio client would be a bit messy indeed. Luckily you can use namespaces to recreate native functions. See the following example.

<?phpnamespace FakeCurl;//create curl_exec function with same name, but its created in the FakeCurl namespace now.function curl_exec($ch) {  //execute the actual curl_exec function in the main namespace  $response =  \curl_exec($ch);  // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string  if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);  }   return "ADDED TO RESPONSE\r\n\r\n".$response;}//make a regular curl request, no alterations.$curl = curl_init();curl_setopt_array( $curl, array(    CURLOPT_HEADER => true,    CURLOPT_NOBODY => true,    CURLOPT_RETURNTRANSFER => true,    CURLOPT_URL => 'http://stackoverflow.com' ) );$response = curl_exec( $curl );curl_close( $curl );echo '<pre>'.$response.'</pre>';?>

Output

ADDED TO RESPONSEHTTP/1.1 200 OKCache-Control: public, max-age=11Content-Length: 191951Content-Type: text/html; charset=utf-8Expires: Wed, 12 Jun 2013 07:09:02 GMTLast-Modified: Wed, 12 Jun 2013 07:08:02 GMTVary: *X-Frame-Options: SAMEORIGINDate: Wed, 12 Jun 2013 07:08:49 GMT

So to use with the twilio client, you need to put at the very top of your script the following:

<?phpnamespace FakeCurl;function curl_exec($ch) {  $response =  \curl_exec($ch);  // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string  if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);  }   return $response;}include("twilio.php");?>

Should the namespace option fail for some reason, I would add a simple function outside the twilio client like.

<?phpfunction fixProxyResponse($response) {  // cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string  if (false !== stripos($response, "HTTP/1.0 200 Connection established\r\n\r\n")) {    $response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $response);  }   return $response;}

And then alter the twilio script TinyHttp.php and change only the following line (~linenr 63)

if ($response = curl_exec($curl)) {  $parts = explode("\r\n\r\n", $response, 3);  list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue')

to

if ($response = curl_exec($curl)) {  $parts = explode("\r\n\r\n", fixProxyResponse($response), 3);  list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue')


Some very late clarification. When you connect to an SSL/TLS server through a proxy, the proxy establishes a tunnel, using HTTP CONNECT. This is covered in RFC2817 and the expired tunneling spec, and not RFC2616.

The original tunneling spec required the proxy to return a '200 Connection Established' to the client once it had successfully connected to the server, which is what you're seeing. This is potentially followed by more headers, and then an empty line, before the connection becomes transparent and you get the actual response from the server. So, you get two sets of headers. RFC 2817 relaxes this, and allows any 2xx response to a CONNECT request.

Which means, in short, that you can't rely on detecting and stripping out a single header line using the php code above. There may be more than one line, and the first line may not have a 200 code, and and may not include the 'connection established' string. You have to be prepared to detect two full sets of headers.

cURL stripped out the initial connect response until 7.11.1 in 2004, but now sends everything back to the client. See here for details.