2010-03-04 31 views
7

我有一个mod_rewrite规则,将发送任何子域请求到一个PHP脚本,应该代理这些请求到另一个主机(内部代理,而不是302)。PHP:代理另一个网址

我很近,在我的脚本与Web浏览器的工作原理,但似乎袅袅不喜欢它:

curl: (56) Received problem 2 in the chunky parser 

这里是我的mod_rewrite:

RewriteCond %{HTTP_HOST} ^(.*)\.example\.com$ 
RewriteRule ^.*$ %{DOCUMENT_ROOT}/proxy.php?__path=%1 [QSA,L] 

而且我proxy.php

<?php 

$name = $_GET['__path']; 
unset($_GET['__path']); 
$path = $_SERVER['REQUEST_URI']; 

$url = "http://$name.internal.example.com$path"; 
$ch = curl_init($url); 
$headers = array(); 
foreach (apache_request_headers() as $key => $value) { 
    $headers[] = "$key: $value"; 
} 
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']); 
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST)); 
curl_setopt($ch, CURLOPT_HEADER, TRUE); 

$data = curl_exec($ch); 

list($headers, $body) = explode("\r\n\r\n", $data, 2); 
$headers = explode("\r\n", $headers); 
foreach ($headers as $header) { 
    header($header); 
} 
die($body); 

任何理由为什么卷曲不喜欢这个,但浏览器可以吗?

编辑:看来,如果我不发送Transfer-Encoding: chunked标题,一切都OK(因为我代理完整的请求,分块是不可能的)。因此,后续问题:我可以充当真正的中间人,并通过套接字发送数据吗?

回答

3

是的,你应该可以通过网络发送数据。但我怀疑你的问题可能源于持久的http连接。 HTTP 1.0将打破请求后的连接,在你的代码中创建为每个请求一个新的卷曲处理,这更像是HTTP/1.0,而不是默认的HTTP/1.1

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); 

您可能还是有问题与应用程序层,因为CURL并不意味着像这样的代理。另一种方法是修改现有的PHP HTTP Client并确保转发的请求足够满足您的需求。

无论您使用什么方法,我强烈建议使用WireShark进行调试。然后,您可以转储2个http请求,然后使用类似Meld的东西来挑选差异。

相关问题