2010-03-04 28 views
7

Tôi có quy tắc mod_rewrite sẽ gửi bất kỳ yêu cầu miền phụ nào đến tập lệnh php cần ủy quyền các yêu cầu đó tới máy chủ khác (proxy nội bộ, chứ không phải 302).PHP: Proxy một url khác

Tôi gần, trong đó kịch bản của tôi làm việc với các trình duyệt web, nhưng curl dường như không thích nó:

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

Đây là mod_rewrite của tôi:

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

Và tôi 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); 

Bất kỳ lý do gì khiến curl không thích điều này nhưng các trình duyệt đều ổn với nó?

EDIT: Dường như nếu tôi không gửi tiêu đề Transfer-Encoding: chunked, mọi thứ đều ổn (vì tôi đang ủy quyền yêu cầu đầy đủ, không thể chunking). Vì vậy, một câu hỏi tiếp theo: Tôi có thể hoạt động như một người trung gian thực sự và gửi dữ liệu khi tôi nhận được nó qua ổ cắm?

Trả lời

3

Có, bạn sẽ có thể gửi dữ liệu qua mạng khi nhận được. Nhưng tôi nghi ngờ vấn đề của bạn có thể xuất phát từ các kết nối http liên tục. HTTP 1.0 sẽ phá vỡ các kết nối sau khi yêu cầu, trong mã của bạn, bạn đang tạo ra một tay cầm mới CURL cho mỗi yêu cầu, mà là giống như HTTP/1.0 thay vì HTTP default/1,1

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); 

Bạn vẫn có thể có vấn đề với lớp ứng dụng vì CURL không có nghĩa là hoạt động như một proxy như thế này. Một cách tiếp cận khác là sửa đổi PHP HTTP Client hiện có và đảm bảo rằng các yêu cầu được chuyển tiếp đủ gần cho nhu cầu của bạn.

Bất kể bạn sử dụng phương pháp gì, tôi khuyên bạn nên sử dụng WireShark để gỡ lỗi. Sau đó bạn có thể đổ 2 yêu cầu http và sau đó sử dụng một cái gì đó như Meld để chọn ra sự khác biệt.

Các vấn đề liên quan