2012-01-05 123 views
1

我想創建一個像應用程序一樣的代理服務器,我可以從該服務器向服務器發送標題,並且響應會直接傳遞給客戶端,並且不會使用所有服務器帶寬。PHP通過代理

我能想到的唯一方法就是使用PHP cURL來做這件事,但這不起作用,因爲它下載文件並將其發送到客戶端。我想知道是否有辦法消除或最小化使用的帶寬。

我想要做什麼: 客戶端打開頁面,按下載按鈕,然後MY服務器向文件服務器請求文件(使用標題)並將其直接發送到客戶端或MY服務器重定向到客戶端。

+0

你打算如何計算髮送給服務器的帶寬,然後發送給客戶端的服務器?熱力學第一定律(當然是抽象的) – 2012-01-05 00:35:31

+0

我對你的問題有點困惑。 「帳戶」是什麼意思? (這不像我不知道這個詞,但我在這方面不明白) – Memoria 2012-01-05 00:40:42

+0

爲什麼不直接使用反向代理? – Layke 2012-01-05 00:43:56

回答

0

沒有,沒有客戶端直接向服務器發出請求,Web服務器無法向客戶端發送響應。

+0

我想你誤解了一些東西。 – Memoria 2012-01-05 01:28:38

+0

您在問題中詢問的內容(代理請求不使用代理服務器的帶寬)必然涉及讓後端服務器向客戶端發送響應(未直接)從客戶端收到請求。這是不可能的。 – duskwuff 2012-01-05 01:33:34

+0

這是一個選項,我想盡量減少服務器使用的帶寬。 – Memoria 2012-01-05 01:44:48

1
  • 客戶端打開的頁面中按下下載按鈕
  • 我的服務器請求發送到文件服務器的文件,並在時間發送給客戶端8K(在下面的例子)。

這使用CURLOPT_BUFFERSIZE,CURLOPT_HEADERFUNCTION和CURLOPT_WRITEFUNCTION。

<?php 
/* 
* curl-pass-through-proxy.php 
* 
* propose: php curl pass through proxy handle: big file, https, autentication 
* example: curl-pass-through-proxy.php?url=precise/ubuntu-12.04.4-desktop-i386.iso 
* limitation: don't work on binary if is enabled in php.ini the ;output_handler = ob_gzhandler 
* licence: BSD 
* 
* Copyright 2014 Gabriel Rota <[email protected]> 
* 
*/ 

    $url = "http://releases.ubuntu.com/" . $_GET["url"]; // NOTE: this example don't use https 
    $credentials = "user:pwd"; 
    $headers = array(
    "GET ".$url." HTTP/1.1", 
    "Content-type: text/xml", 
    "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", 
    "Cache-Control: no-cache", 
    "Pragma: no-cache", 
    "Authorization: Basic " . base64_encode($credentials) 
); 

    global $filename; // used in fn_CURLOPT_HEADERFUNCTION setting download filename 
    $filename = substr($url, strrpos($url, "/")+1); // find last/

    function fn_CURLOPT_WRITEFUNCTION($ch, $str){ 
    $len = strlen($str); 
    echo($str); 
    return $len; 
    } 

    function fn_CURLOPT_HEADERFUNCTION($ch, $str){ 
    global $filename; 
    $len = strlen($str); 
    header($str); 
    //~ error_log("curl-pass-through-proxy:fn_CURLOPT_HEADERFUNCTION:str:".$str.PHP_EOL, 3, "/tmp/curl-pass-through-proxy.log"); 
    if (strpos($str, "application/x-iso9660-image") !== false) { 
     header("Content-Disposition: attachment; filename=\"$filename\""); // set download filename 
    } 
    return $len; 
    } 

    $ch = curl_init(); // init curl resource 
    curl_setopt($ch, CURLOPT_URL,$url); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); // a true curl_exec return content 
    curl_setopt($ch, CURLOPT_TIMEOUT, 600); // 60 second 
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // login $url 
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // don't check certificate 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // don't check certificate 
    curl_setopt($ch, CURLOPT_HEADER, false); // true Return the HTTP headers in string, no good with CURLOPT_HEADERFUNCTION 
    curl_setopt($ch, CURLOPT_BUFFERSIZE, 8192); // 8192 8k 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
    curl_setopt($ch, CURLOPT_HEADERFUNCTION, "fn_CURLOPT_HEADERFUNCTION"); // handle received headers 
    curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'fn_CURLOPT_WRITEFUNCTION'); // callad every CURLOPT_BUFFERSIZE 

    if (! curl_exec($ch)) { 
     error_log("curl-pass-through-proxy:Error:".curl_error($ch).PHP_EOL, 3, "/tmp/curl-pass-through-proxy.log"); 
    } 

    curl_close($ch); // close curl resource 

?>