php - 如何处理来自代理的额外 HTTP header ?

标签 php curl proxy http-headers twilio

我们的环境需要使用出站代理来提供异地服务。通常这不是问题。在这种使用 Twilio 的情况下,返回的额外 header 会破坏客户端。

传出 header :

POST /2010-04-01/Accounts/FOO/SMS/Messages.json HTTP/1.1
Authorization: Basic FOO==
User-Agent: twilio-php/3.10.0
Host: api.twilio.com
Accept: */*
Accept-Charset: utf-8
Content-Type: application/x-www-form-urlencoded
Content-Length: 108

响应头:

HTTP/1.0 200 Connection established

HTTP/1.1 201 Created
Server: nginx
Date: Thu, 06 Jun 2013 14:39:24 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 551
Connection: close
X-Powered-By: PHP/5.3.11

我只能假设代理正在添加额外的 HTTP header 。

Twilio 客户端会检查:

list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue') 

据我了解,有些时候或版本的 curl 会自动在请求中添加 Expect header ,并且会在响应中返回 HTTP 100,但在这种情况下不是,响应是 200连接已建立。添加一个空的 Expect: 或 Expect:bacon 并没有改变结果是值得的。

我真的不想在这里过多地攻击 Twilio 客户端,我特别想避免只添加一个 || $parts[0] == 'HTTP/1.0 200 Connection established' 因为看起来很乱。

是否可以发送一个请求头来抑制/隐藏额外的头?或者,我没有看到忽略它的 curl 选项?

出站代理是Linux/Squid

最佳答案

代理问题是很多脚本都面临的问题。我可以在 Internet 上找到的首选解决方案是简单地添加以下代码行。

<?php
// 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);
}
?>

现在将其添加到 twilio 客户端确实有点困惑。幸运的是,您可以使用 namespace 来重新创建 native 函数。请参阅以下示例。

<?php
namespace 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>';

?>

输出

ADDED TO RESPONSE

HTTP/1.1 200 OK
Cache-Control: public, max-age=11
Content-Length: 191951
Content-Type: text/html; charset=utf-8
Expires: Wed, 12 Jun 2013 07:09:02 GMT
Last-Modified: Wed, 12 Jun 2013 07:08:02 GMT
Vary: *
X-Frame-Options: SAMEORIGIN
Date: Wed, 12 Jun 2013 07:08:49 GMT

所以要与 twilio 客户端一起使用,您需要在脚本的最顶部放置以下内容:

<?php
namespace 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");
?>

如果命名空间选项由于某种原因失败,我会在 twilio 客户端之外添加一个简单的函数,例如。

<?php
function 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;
}

然后更改 twilio 脚本 TinyHttp.php 并仅更改以下行 (~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')

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

关于php - 如何处理来自代理的额外 HTTP header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16965530/

相关文章:

javascript - api 中的 Google map 旅行模式

PHP OOP : Handling multiple row outputs from a database, 最好的方法是什么?

php - 从 Web 服务器提交时 CURL 错误请求 400

PHP CURL GET 请求返回 500,其中 bash curl 成功

proxy - SonarQube 代理配置,棘手

php - 没有指定输入文件 plesk server4you

php - php中SoapClient请求和Soap curl请求的区别

xcode - 在代理后面使用 XCode 提交应用程序

javascript - NodeJS/ExpressJS : proxy an HTTP video stream (from VLC)

javascript - 如何删除弹出窗口中出现的 onclick 按钮 - CSS 和 JS 相关