PHP通过代理

时间:2012-01-05 00:32:28

标签: php proxy

我想创建一个像应用程序这样的代理,我将头发送到服务器并且响应直接发送到客户端并且不使用所有服务器带宽。

我能想到的唯一方法是使用PHP cURL,但这不起作用,因为它下载文件并将其发送到客户端。我想知道有没有办法删除或最小化使用的带宽。

我想做什么: 客户端打开页面,按下载按钮,然后MY服务器向文件服务器请求文件(使用标题)并将其直接发送到客户端或MY服务器重定向到客户端。

2 个答案:

答案 0 :(得分:1)

  • 客户端打开页面按下载按钮
  • MY服务器向文件服务器请求文件并在时间发送给客户端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 <gabriel.rota@gmail.com>
 * 
 */

  $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

?>

答案 1 :(得分:-1)

不,如果客户端没有直接向该服务器发出请求,就无法让Web服务器向客户端发送响应。