2012-01-05 81 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 

?>