“双向proxied"用PHP下载?(一个服务器提供文件,用客户机数据ping另一个服务器)


"Two-way proxied" download with PHP? (one server serves file, and pings another server with client data)

对于"双向代理下载"术语感到抱歉-我不确定这将如何被称为(正确的术语非常感谢)。无论如何:

让我们假设我有一篇文章的PDF文件,test.pdf(见下面的Latex示例),我是该文章的作者,它托管在一个会议网站上,并且可以在那里免费获得。假设我想(并且被允许)也从我的网站上分发相同的PDF副本。

因此,为了便于示例,我们说:

  • 本地PC有一个(全局可解析的)IP地址80.800.0.80
  • 我的网站服务器在myserver.com, IP地址90.90.90.90
    • 到PDF的链接是http://myserver.com/dl/test.php?file=./test.pdf
  • 会议网址为conference.org, IP地址为100.100.100.100
    • PDF的链接是http://conference.org/2001/downloads/test.pdf

我想做的是:当本地PC从我的网站(通过http://myserver.com/dl/test.php?file=./test.pdf)下载PDF文件时,test.php脚本也应该:

  • 启动http://conference.org/2001/downloads/test.pdf的下载,使用客户端的原始报头数据(即conference.org应该在他们的日志中看到请求的是80.800.0.80),以我的网站为引用(即90.990.0.90);这样做的想法是,conference.org网站主机将记录相同的客户端下载myserver.com
  • conference.org的下载应该在100字节左右后终止,以免浪费conference.org的带宽——否则,是myserver.com提供PDF文件
  • 如果从conference.org下载失败(例如,如果conference.org暂时离线),那么应该记录在一个文本文件中-但它不应该以其他方式干扰(例如,引入额外的延迟)从myserver.com提供文件的过程。

下面是test.php的一个例子,它只执行"from myserver.com";否则,myserver.com本地文件与它们在conference.org上的位置之间的关系在$filesRelations数组中模拟:

<?php
$filesRelations = array(
  './test.pdf'   => 'http://conference.org/2001/downloads/test.pdf',
);
if(!(isset($_GET['file']))) {
  echo "<html>
  <head/>
  <body>
  <a href='?file=./test.pdf'>test.pdf</a>
  <br/> <sub>(".$filesRelations['./test.pdf'].")</sub>
  </body>
  </html>
  ";
} else {
  # echo "-- " . $_GET['file'] . " -- "; # dbg
  $localpath = $_GET['file'];
  $fdname = basename($localpath);
  $fsize = filesize($localpath);
  $includeFile = file_get_contents($localpath);
  if ($includeFile === false)
  {
    echo "Error with $localpath";
  } else {
    header("Content-type: application/pdf");
    header("Content-Disposition: attachment; filename='"".$fdname."'"");
    header("Content-length: $fsize");
    header("Cache-control: private");
    echo $includeFile;
  }
}
exit;
?>

我如何修改这段代码,使脚本"ping"链接(通过启动和终止一个短的,100字节的下载)在各自的$filesRelations条目中,使用调用客户端的头数据,在它提供头和文件之前(通过回显$includeFile)?


对于测试,这是test.tex文件(您可以使用pdflatex test.tex编译它以获得test.pdf):

'documentclass{article}
'usepackage{lipsum}
'begin{document}
'title{Lorem Ipsum}
'author{Author's Name}
'maketitle
'begin{abstract}
'lipsum[1]
'end{abstract}
'section{Introduction}
'lipsum[1-12]
'end{document}

(为了测试,将test.phptest.pdf放在一个目录下,在该目录下运行php-5.4.10 -S localhost:8000,然后在web浏览器中访问http://localhost:8000/test.php)

我认为障碍是客户端的原始头数据。客户端的IP地址不包含在报头中,而是由客户端所连接的套接字的TCP/IP层决定。这就是日志里的内容。所以,不可能这么简单。

服务器可以通过以下方式获取客户端的IP地址:

$clientIP = $_SERVER['REMOTE_ADDR'];

如果你能想出一种机制让其他服务器知道这是一个代表客户端的请求,你当然可以把这个数据发送给他们。正如您所指出的,也许可以尝试在对该服务器的请求中设置HTTP_X_FORWARDED_FOR标头。

祝你好运!