som*_*dev 10 php proxy curl http-headers twilio
我们的环境需要使用出站代理来进行异地服务.通常这不是问题.在这种情况下使用Twilio,返回的额外标头会破坏客户端.
传出标题:
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
Run Code Online (Sandbox Code Playgroud)
响应标题:
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
Run Code Online (Sandbox Code Playgroud)
我只能假设代理正在添加额外的HTTP标头.
Twilio客户端会检查:
list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue')
Run Code Online (Sandbox Code Playgroud)
据我了解,有些时候或版本的curl会在请求中自动添加Expect标头,而HTTP 100将在响应中返回,但在这种情况下它不是,并且响应是200 Connection建立.为什么值得添加一个空的Expect:或Expect:培根没有改变结果.
我真的不想在这里过多地破解Twilio客户端,我特别想避免只添加一个|| $ parts [0] =='HTTP/1.0 200建立连接',因为它看起来很混乱.
是否可以发送请求标头来抑制/隐藏额外的标头?或者,我没有看到一个卷曲选项忽略它?
出站代理是Linux/Squid
Hug*_*ing 14
代理问题是很多脚本面临的问题.我可以在互联网上找到的首选解决方案是简单地添加以下代码行.
<?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);
}
?>
Run Code Online (Sandbox Code Playgroud)
现在将这个添加到twilio客户端确实有点乱.幸运的是,您可以使用命名空间来重新创建本机函数.请参阅以下示例.
<?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>';
?>
Run Code Online (Sandbox Code Playgroud)
产量
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
Run Code Online (Sandbox Code Playgroud)
因此,要与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");
?>
Run Code Online (Sandbox Code Playgroud)
如果命名空间选项由于某种原因失败,我会在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;
}
Run Code Online (Sandbox Code Playgroud)
然后更改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')
Run Code Online (Sandbox Code Playgroud)
至
if ($response = curl_exec($curl)) {
$parts = explode("\r\n\r\n", fixProxyResponse($response), 3);
list($head, $body) = ($parts[0] == 'HTTP/1.1 100 Continue')
Run Code Online (Sandbox Code Playgroud)
一些很晚的澄清.当您通过代理连接到SSL/TLS服务器时,代理使用HTTP CONNECT建立隧道.这包含在RFC2817和过期的隧道规范中,而不是RFC2616.
原始隧道规范要求代理在成功连接到服务器后向客户端返回"200 Connection Established",这就是您所看到的.在连接变为透明并且您从服务器获得实际响应之前,可能会有更多标题,然后是空行.所以,你得到两组标题.RFC 2817放宽了这一点,并允许任何2xx响应CONNECT请求.
简而言之,这意味着您不能依赖于使用上面的php代码检测和剥离单个标题行.可能有多个行,第一行可能没有200个代码,并且可能不包含"建立连接"字符串.您必须准备好检测两组完整的标头.
cURL在2004年7.11.1之前删除了初始连接响应,但现在将所有内容发送回客户端.详情请见此处.
| 归档时间: |
|
| 查看次数: |
5825 次 |
| 最近记录: |