我有很多的麻烦Apache的mod_proxy.so适当的configuration工作,如所需…
主要的想法是在networking中的本地机器上创build一个代理,这个代理将能够在PHP中处理客户端请求(通过这个Apache准备的代理连接的客户端)。 而且,它也有能力在PHP上处理服务器响应。
这是两个function,它们是相互独立的。
让我介绍一下我需要实现的一些模式:

正如你在这里看到的,有两种方式:蓝色和红色。
对于蓝色的,我基本上连接了本地networking(家庭)上的客户端(机器B – 手机),并将其configuration为通过代理(即完全相同networking上的机器A(个人计算机))。
所以我们说(不是DHCP):
机器A: 192.168.1.40 – > Apache正在这台机器上运行,并configuration为侦听端口80。
机器B(手机): 192.168.1.75 – >configuration为通过代理,即IP 192.168.1.75和端口80(基本上,机器A)。
正确configurationApache之后,基本上就是从mod_proxy.so(main worker),mod_proxy_connect.so(SSL,allowCONNECT,…)和mod_proxy_http.so(需要)中的httpd.conf中删除“#”处理HTTP请求/响应),并在我的情况下,这样的行:
# Implements a proxy/gateway for Apache. Include "conf/extra/httpd-proxy.conf" # Various default settings Include "conf/extra/httpd-default.conf" # Secure (SSL/TLS) connections Include "conf/extra/httpd-ssl.conf"
这使我能够configuration文件httpd-proxy.conf来准备转发代理或反向代理。
所以我不确定,如果我需要的是正向代理或反向代理。
对于一个转发代理我做了这个:
<IfModule proxy_module> <IfModule proxy_http_module> # # FORWARD Proxy # #ProxyRequests Off ProxyRequests On ProxyVia On <Proxy *> Order deny,allow # Allow from all Deny from all Allow from 192.168.1 </Proxy> </IfModule> </IfModule>
它基本上将所有数据包通常传递给服务器并返回给客户端。 我可以完美地跟踪它(并testing它的工作)看Apache的“access.log”。 然后出现在Apache日志上。 所以它的工作。
但问题来了:
我读了很多关于这个。 我已经详细阅读了Apache关于mod_proxy的官方网站。 而且我在论坛上search了很多,但没有运气。
所以我想到了第一个近似值:
1)在Apache中转发代理,传递所有的数据包,不可能处理它们。 这似乎是真的,那么,反向代理呢?
所以我设想了一些像:
ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy> ProxyPass http://www.google.com http://www.yahoo.com ProxyPassReverse http://www.google.com http://www.yahoo.com
这只是一个testing,但这应该导致我的手机,当试图导航到谷歌,我应该去雅虎,不是吗? 但不是。 它不起作用。
所以你真的看到,所有在Apache反向代理上的例子都是这样的:
ProxyPass /foo http://foo.example.com/bar ProxyPassReverse /foo http://foo.example.com/bar
这意味着,在当地情况下的任何types的请求都将在远程位置解决。
但是我需要的是相反的! 这就是当我的手机要求远程站点时,我在本地服务器(Apache的)上解决了这个请求,用PHP模块处理它。
所以,如果它是一个正向代理,我需要先通过PHP。 如果它是一个反向代理,我需要改变我的本地服务器的“走向”方向,首先在PHP上进行处理。
然后想到第二个选项:
2)我见过类似的东西:
<Proxy http://example.com/foo/*> SetOutputFilter INCLUDES </Proxy>
我开始searchSetOutputFilter,SetInputFilter,AddOutputFilter和AddInputFilter 。
但我真的不知道如何使用它。
似乎是好的,或者我的解决scheme,因为有了这样的事情,我应该能够添加一个inputfilter来处理PHP的客户端请求,并发回客户端我编程/想要的(而不是远程服务器响应),这是架构上的BLUEpath ,我应该可以添加一个输出filter,这个filter似乎能够在将远程服务器响应发送到客户端(应该是架构上的REDpath)之前处理远程服务器响应。
红色的path,它只是读取服务器响应,并与他们一起玩。 但没有更多。 蓝色的path,是重要的。 因为在处理请求之后,我会发送给客户端。
对不起,这个惊人的大post,但我需要尽我所能解释。
我希望有人会明白我的问题,并会帮助我解决它!
好的,首先,Apache是错误的工具!
Apache是一个networking服务器,而不是代理服务器。 是的,它带有一个代理模块,但首先它是一个networking服务器。
相反,你应该看看一个真正的代理服务器,如鱿鱼。 而在鱿鱼,你正在寻找一个称为“内容适应”的function:
@Sarek是对的,但问题是如何处理代理请求与PHP(从Apache的mod_proxy),而不是如果Apache是正确的工具。
为了使用PHP作为代理,我在httpd.conf使用了(它需要mod_proxy和mod_rewrite):
# Forward proxy server <VirtualHost *:8080> ProxyRequests On ProxyVia On <Proxy *> Order deny,allow Deny from all Allow from 192.168 RewriteEngine On RewriteCond %{REQUEST_URI} !/pac.php RewriteRule ^ /endpoint.php [L] </Proxy> </VirtualHost>
然后在/pac.php (定义PAC文件内容)中:
<?php header('Content-Type: application/x-javascript-config') ?> function FindProxyForURL(url, host) { return "PROXY <?php echo $_SERVER['SERVER_ADDR'] ?>:<?php echo $_SERVER['SERVER_PORT'] ?>; DIRECT"; }
它用于机器B(代理客户端)上的代理configuration。 使用http://192.168.1.40:8080/pac.php 。 这样,客户端将总是使用代理服务器的任何域名/ IP(如127.0.0.1,本地主机,*。本地等)。 注意:IE和.Net Apps仍然只需要为localhost和127.0.0.1写FQDN尾随点: http://localhost. 和http://127.0.0.1. 。
最后在/endpoint.php :
<?php // Don't handle domain existance $url = $_SERVER['REQUEST_URI']; $url_parts = parse_url($url); // Some security checks (no local file...) if(false === $url_parts || empty($url_parts['scheme']) || !in_array($url_parts['scheme'], array('http', 'https'))){ die(); } $headers_raw = ''; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') { $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))); $headers_raw .= $name . ': ' . $value . "\r\n"; } else if ($name == "CONTENT_TYPE") { $headers_raw .= 'Content-Type: ' . $value . "\r\n"; } else if ($name == "CONTENT_LENGTH") { $headers_raw .= 'Content-Length: ' . $value . "\r\n"; } } // http://php.net/manual/en/context.http.php $context = stream_context_create(array( 'http' => array( 'method' => $_SERVER['REQUEST_METHOD'], 'header' => $headers_raw, 'ignore_errors' => true, 'content' => file_get_contents('php://input') ) )); $content = file_get_contents($url, false, $context); $content_type = 'application/octet-stream';// "text/html" $content_type_raw = $content_type;// "text/html; charset=UTF-8" foreach($http_response_header as $response_header){ if('Content-Type:' == substr($response_header, 0, 13)){ $content_type_raw = substr($response_header, 14); $content_type = strstr($content_type_raw, ';', true); header($response_header); } elseif('Content-Encoding:' == substr($response_header, 0, 17) && 'gzip' == substr($response_header, 18, 4)) { //Now lets uncompress the compressed data $content = gzinflate(substr($content, 10, -8)); } elseif('Content-Length:' == substr($response_header, 0, 15)) { //Skip it } else{ header($response_header); } } // Content transforms //var_dump($url_parts);exit(); if('text/html' == $content_type){ echo str_replace('cat', 'dog', $content); }else{ echo $content; }
这是一个例子,不要在生产中使用它。 它不处理任何无效/超时域/ IP。
由此,您可以重写所请求的url(该代理可以提供http://google.com/search?q=dogurlhttp://google.com/search?q=cat ,一个有趣的笑话)和更新内容(如删除广告,插入JS / CSS等)