2010-03-04 2 views
7

Ich habe eine mod_rewrite Regel, die Subdomain-Anfragen an ein PHP-Skript, Proxy diese Anforderungen an einen anderen Host (interner Proxy, nicht 302) senden soll.PHP: Proxy eine andere URL

Ich bin in der Nähe, dass mein Skript arbeitet mit Web-Browsern, aber Locke scheint es nicht mögen:

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

Hier ist meine mod_rewrite:

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

Und mein 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); 

Irgendein Grund, warum curl dies nicht mag, aber Browser sind ok damit?

EDIT: Es scheint, wenn ich alles nicht die Transfer-Encoding: chunked Header senden, ok ist (da ich die volle Anfrage bin Proxying, Chunking ist nicht möglich). Also eine weitere Frage: Kann ich als echter Mittelsmann fungieren und die Daten senden, wenn ich sie über die Steckdose bekomme?

Antwort

3

Ja, Sie sollten Daten über das Netzwerk senden können, wenn Sie es erhalten. Aber ich vermute, dass Ihr Problem von persistenten HTTP-Verbindungen herrühren kann. HTTP 1.0 wird die Verbindung nach der Anforderung brechen, in Ihrem Code, den Sie für jede Anfrage eine neue ROTATION Griff erstellen, die eher wie HTTP/1.0 anstelle des Standard-HTTP/1,1

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); 

Sie können immer noch Probleme haben, mit der Anwendungsschicht, da CURL nicht als Proxy-Server dienen soll. Ein anderer Ansatz bestünde darin, ein vorhandenes PHP HTTP Client zu ändern und sicherzustellen, dass die weitergeleiteten Anforderungen für Ihre Anforderungen nah genug sind.

Egal, welchen Ansatz Sie verwenden, ich empfehle dringend, WireShark zum Debuggen zu verwenden. Sie können dann 2 http-Anfragen ablegen und dann etwas wie Meld verwenden, um die Unterschiede herauszusuchen.