档案

Posts Tagged ‘rewrite’

从天涯论坛看终极页的缓存控制

12月 10, 2010 留下评论

一般不太上天涯论坛灌水或者潜水,不过经常去天涯SA刘天斯的blog上逛逛~在他开源memlink后,想起来去天涯看看前端设计,发现其论坛主列表页采用nginx发布(预计有nginx的module直接读取memlink),终极页前端采用varnish缓存,回复时的动态asp页面由IIS处理。但在终极页上,虽然显示的server也还是IIS,我却有一定的怀疑~

在访问某终极页时,可以看到类似如下的header
Age:78
Cache-Control:public
Connection:close
Content-Encoding:gzip
Content-Length:34687
Content-Type:text/html
Date:Fri, 10 Dec 2010 09:03:48 GMT
Expires:Fri, 10 Dec 2010 09:07:30 GMT
Last-Modified:Fri, 10 Dec 2010 09:02:30 GMT
Server:Microsoft-IIS/6.0
Vary:Accept-Encoding
Via:Tianya Cache
X-Cache:HIT118
X-Powered-By:ASP.NET
X-tianya:1098678484 1098675384

如果按下F5,会看到一个IMS请求,最后返回304或者200的结果。

如果按下Ctrl+F5,会看到一个no-cache请求,最后返回200的结果。

不过奇怪的是,在no-cache请求后,虽然明知页面没有变(请求的是一个多页帖子的第一页,wget和wget –header ‘Cache-Control: no-cache’下来后的页面的MD5值都一样),但返回的last-modified时间却变成了和Date一致的当前时间了。以至于让我怀疑这个*.shtml难道不是静态化生成的?

然后回复该帖。通过POST方式向另一个动态域名传输数据,并302跳转回原页面。由于POST方式的不可缓存性,浏览器自动带上了no-cache请求头,并传递给了302之后的动作,即以no-cache重新请求了原帖子的url,并重新下载了该页面。由此完成了对回复的即时更新——对于论坛来说,重要的就是发帖人自己能即时看到,其他人完全可以等一会页面过期或者IMS比对来看别人的新回复。

假设前面说到的shtml确实是静态化生成的话,那么这个直接跳转的做法就有一定的风险,即要求系统在极短时间(从浏览器时间看就是POST的firstbyte时间开始,到200的connection时间结束,网络较好的情况下应该是毫秒级)内,完成对终极页的静态化工作。
写到这里,愈发怀疑这个shtml是asp的伪装版了……

分类:Uncategorized 标签:,

nagios的add-ons安装小抄~

12月 4, 2010 留下评论

给nagios安装几个add-ons,碰到一些一般安装教程上不会提及的问题,记录一下:

1、ndoutils:
在./configure通过后make一直error,因为不管是否–with-mysql-lib,也不管–with-mysql-lib=/usr/local/mysql/lib还是/usr/local/mysql/lib/mysql,甚至使用LDFLAGS=-I/usr/local/mysql/lib等等,最后在make的时候总还是会报出如下错误:
../include/config.h:261:25: error: mysql/mysql.h: No such file or directory
../include/config.h:262:26: error: mysql/errmsg.h: No such file or directory
解决办法:编辑config.h文件的261和262行,把mysql/*.h的mysql/删除掉即可。

make完成后,将相应文件cp到指定目录,启动ndomod会报错libmysqlclient.so.6.0.0动态链接库无法找到。网上一般都说ln -s /usr/local/mysql/lib/* /usr/lib;echo ‘/usr/lib’ >> /etc/ld.so.conf;ldconfig即可。其实还不行。
解决办法:echo ‘/usr/local/mysql/lib/mysql’ > /etc/ld.so.conf.d/mysql.conf;ldconfig即可。因为通用办法的目录不够深。

2、pnp4nagios:
之前使用的pnp0.4.*版本,今天下的是pnp0.6.*版本。整个url设计发生了较大变化。各监控项页面的url从pnp4nagios/index.php?host=&service=变成了/pnp4nagios/graph?host=&service=。而这个graph(rrd图像的url是/pnp4nagios/image?***)则通过apache的mod_rewrite实现。
pnp自己编译时可以make出来一个httpd.conf。其中相关Rewrite的包括:
<Directory ‘”/usr/local/pnp4nagios/share/”>
RewriteEngine On
RewriteBase /pnp4nagios/
RewriteRule ^(application|modules|system) – [F,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php$0 [PT,L]
</Directory>
因为pnp编译时没有具体区分etc和share的路径,所以之后apache的发布路径也不同,为了方便,不再写directory。最后经过反复试验,可用配置如下:
RewriteEngine On
RewriteRule ^(application|modules|system) – [F,L]
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/nagios/pnp4nagios/(.*) /nagios/pnp4nagios/index.php$1 [PT,L]

试验中发现几个apache与nginx的不同:
1、rewriterule的转向url不能用^标记起始端!
2、PT的强制进入下一个处理器相当有用,不然会形成回环rewrite!
3、rewritecond里德%{REQUEST_FILENAME}默认是在rewritebase下的——而rewritebase只能在directory里使用。

域名切换&SEO

7月 17, 2010 留下评论
网站某频道准备启用新域名,切换过程中,为了保证网民访问效果,对老域名下的所有请求设置了重定向到新域名下相同url。测试访问正常后上线使用。
过几天,发现该频道在各搜索引擎的收录数和关键词排名中都消失了!
(一)SE收录的问题
原来对于搜索引擎来讲,301永久重定向与302临时重定向属于不同情况。它们认可301永久重定向规则,并依此规则转移原请求的数据……
照此修改nginx配置
server {
server_name old.domain.com;
#rewrite ^/(.*)$ http://new.domain.com/$1 last;
rewrite ^/(.*)$ http://new.domain.com/$1 permanent;

}

server {
#server_name old.domain.com toold.domain.com;
server_name new.domain.com toold.domain.com;

root /www/old.domain.com;

index index.html;
}
配置生效后,收录逐渐恢复。
目前查询的结果,新老域名的google收录比为28600:46100,百度收录比为1200:97400。
据网友经验,百度对301重定向大概也需要3个月左右的时间才能完全反应过来……汗死
(二)googlePR的问题
收录解决后,PR的问题又报出来了。目前查询结果,old.domain.com的PR为6,new.domain.com的PR还是0,而且toolod.domain.com的PR也是6,并提示可能是劫持了old.domain.com的PR!
只好再去看PR的资料……PR是google发明的对页面重要性等级的分析算法。从0到10非等比升高。主要是通过相互之间的链接来衡量得出的,外部链接的PR越高,网站得到的PR评分也越高(粗略的说)。对于google来说,google、yahoo等搜索引擎的收录,显然是PR衡量中极为重要的(google自定为10,yahoo、baidu等搜索是9,sina等门户是8…)显然,对于网站域名迁移切换来说,搜索引擎的收录数迁移是基础。
不过收录转移完了,PR也变不了——因为PR计算太复杂了,哪怕以google的实力也不可能做到实时更新,而是几乎2.5-3个月才更新一次!
同时,据google的Webspam团队老大Matt Cutts说:即使在域名迁移中使用301重定向,在PR统计时,也会有一定的损失!
总之,想看到new.domain.com的PR恢复成6,耐心等待吧……
然后研究toold的劫持PR报告是怎么来的……
一般大家的说法,劫持PR都是采用重定向或者别名的方式(上面提到了,这个方式也不会获得完全一样的PR)。显然我这里的情况不是。
也有人说,劫持PR直接A到IP更方便。也有人怀疑自己租机建站得到的是其他站的PR,难道相同IP的域名PR都会一样?查询一下和new.domian.com在同一台nginx上的另一个域名,PR是5。猜测不对。
或许,因为toold读取的网页文件和old是一致的,所以获得的外链也一致。但外面的反向链接,肯定指的都是old而不是toold,导致toold的反链数过少,所以被怀疑为PR劫持了。
不过,据编辑说,toold这个域名从来就没有上线发布使用过,搜索引擎从哪里抓到的页面呢?
nginx的同一server{}段内的多个server_name配置,默认只会把第一个域名设定为$server_name。
dns上也没有配反向解析。
实在想不到还有哪里能泄露出这个toold了……
分类:未分类 标签:, , ,

url_rewrite配置的小区别

5月 20, 2010 留下评论
一直以为squid的url_rewrite就是改写url后,传给squid分析是否缓存,然后返回缓存或者回源。在浏览器地址栏上的url是不变的。
今天才知道在print $uri的时候,可以给他加上http_code。变成print 302:$uri的格式,然后就可以由浏览器发起302跳转到新页面了。
分类:未分类 标签:,

apache防盗链(mod_perl试用)

4月 15, 2010 留下评论
客户需求如下:
在web请求视频时,按算法生成密文和明文串,然后依规则组成最终的url请求;
算法规则——用如下三个关键词生成MD5密文:
1、自定义密钥:abcde.;
2、视频文件真实路径,即/path/to/file.rmvb;
3、请求时间,以当前UNIX时间换算为十六进制字符串,并作为明文;
最终url格式是http://www.test.com/path/to/file.rmvb?key=1234567890abcdefghijklmnopqrstuy&t=1234abcd这样。
要求失效时间为8小时。
这个需求和之前一次相当类似,不过上回是squid,这次是apache。同样采用perl脚本进行防盗链设置,apache需要使用mod_perl模块。
首先安装perl模块:
wget http://perl.apache.org/dist/mod_perl-2.0-current.tar.gz
tar zxvf mod_perl-2.0-current.tar.gz
cd mod_perl-2.0-current.tar.gz
perl Makefile.PL MP_APXS=/home/apache2/bin/apxs
make && make
install
echo "LoadModule perl_module modules/mod_perl.so" >> /home/apache2/conf/httpd.conf
perl -MCPAN -e shell
>install Apache2::Request
>look Apache2::Request
rm -f configure
rm -f apreq2-config
./buildconf
perl Makefile.PL
make && make install
exit
(因为64位系统的libexpat.so有问题,编译libapreq2会出问题,只好如此强制安装)
echo "LoadModule apreq_module modules/mod_apreq2.so" >> /home/apache2/conf/httpd.conf
因为libapreq2.so安装在/home/apache2/lib/下了,所以需要echo "/home/apache2/lib">/etc/lo.so.conf.d/apache.conf,然后ldconfig。
修改httpd.conf,加入如下设置:
PerlPostConfigRequire /home/apache2/perl/start.pl
<Location /smg>
SetHandler modperl
PerlAccessHandler DLAuth
PerlSetVar ShareKey abcde.
</Location>
然后mkdir /home/apache2/perl/,在其中创建start.pl和DLAuth.pm两个文件。start.pl文件内容如下:
use strict;
use lib qw(/home/apache2/perl);
use Apache2::RequestIO ();
use Apache2::RequestRec ();
use Apache2::Connection ();
use Apache2::RequestUtil ();
use Apache2::ServerUtil ();
use Apache2::Log ();
use Apache2::Request ();
1;
DLAuth.pm文件内容如下:
package DLAuth;
use strict;
use warnings;
use Socket qw(inet_aton);
use POSIX qw(difftime strftime);
use Digest::MD5 qw(md5_hex);
use Apache2::RequestIO ();
use Apache2::RequestRec ();
use Apache2::Connection ();
use Apache2::RequestUtil ();
use Apache2::ServerUtil ();
use Apache2::Log ();
use Apache2::Request ();
use Apache2::Const -compile => qw(OK FORBIDDEN);
sub handler {
    my $r = shift;
    my $s = Apache2::ServerUtil->server;
    my $shareKey = $r->dir_config(‘ShareKey’) || ”;
    my $uri = $r->uri() || ”;
    my $args = $r->args() || ”;
    my $expire = 8 * 3600;
    if ($args =~ m#^key=(w{32})&t=(w{8})$#i){
    my ($key, $date) = ($1, $2);
    my $str = md5_hex($shareKey . $uri . $date)
    my $reqtime = hex($date);
    my $now = time;
    if ( $now – $reqtime < $expire){
        if ($str eq $key) {
            return Apache2::Const::OK;
        } else {
                $s->log_error("[$uri FORBIDDEN] Auth failed");
            return Apache2::Const::FORBIDDEN;
        }
    }
    }
    $s->log_error("[$uri FORBIDDEN] Auth failed");
    return Apache2::Const::FORBIDDEN;
}
1;
就可以了。
apachectl restart。测试一下,先用perl自己生成一个测试链接:
#!/usr/bin/perl -w
use Digest::MD5 qw(md5_hex);
my $key = "bestv.";
$path = shift(@ARGV);
my $date = sprintf("%x",time);
$result = md5_hex($key . $path . $date);
my $uri = "http://127.0.0.1$path?key=$result&t=$date&quot;;
print $uri;
运行./url.pl /smg/abc.rmvb生成http://127.0.0.1/smg/abc.rmvb?key=4fb6b4e6a0ec484aea98fa727fc7149d&t=4bc7dd5a,然后wget -S -O /dev/null "http://127.0.0.1/smg/abc.rmvb?key=4fb6b4e6a0ec484aea98fa727fc7149d&t=4bc7dd5a",返回200 OK;任意修改t为12345678,再wget,返回403 Forbidden。error_log显示如下:
[Fri Apr 16 11:47:06 2010] [error] [/smg/abc.rmvbkey=4fb6b4e6a0ec484aea98fa727fc7149d&t=12345678 FORBIDDEN] Auth failed

分类:未分类 标签:, ,

客户页面小故障

4月 10, 2010 留下评论
今天接到客户电话,说,主页已经提交过了刷新任务,上面的图片已经更新,但点击图片后链接到的页面内容还是老的……
仔细一看,原来主页里的html是这么定义的:
<a href="http://msn.golfbox.cn/cache/922/36717.html&quot; target="_blank"><img src="/upload/img/20100410/20100410144202.jpg" width="125" height="80" class="border_blue" /></a>
而http://msn.golfbox.cn/cache/922/36717.html的内容是这样:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><script language="JavaScript">
 location.replace("http://msn.golfbox.cn/cache/874/36804.html&quot;);
</script>
于是跟客户交流确认,他们网站的主页框架上比较固定的地方,都是采用这种方式,来提供内容更新的。。。
他们又不肯给出具体更新了那些跳转页面,只好写个小脚本,去处理比对。如果有相同url的location.replace地址不统一的,就强制更新这些页面。
#!/bin/bash
curl http://msn.golfbox.cn/ |sed ‘s/\n//g’|sed ‘s/href=/\n/g’|grep "^"http://msn.golfbox.cn/cache&quot;|awk -F’"’ ‘{print $2}’>url
for j in `cat url`;do
 for i in `cat ip`;do
  curl -x $i:80 $j|awk -F’"’ ‘/replace/{print "’$j’","’$i’",$2}’>>golfbox.log
#  curl -x $i:80 -I $j|awk ‘/Age/{print "’$j’","’$i’",$2}’>>age.log
 done
done
cat golfbox.log |awk ‘{if($1==a){if($3!=b){system("/home/squid/bin/squidclient -p 80 -h "$2" -m purge "$1)}};a=$1;b=$3}’
(该脚本有一个问题:如果刚好是第一台的url未更新,结果会反而去刷新那些已经更新了的服务器;所以应该是输出url,然后再用for do done去刷新所有服务器~如果curl可以在获取内容的同时获取Age就好了~所以最后用一个讨巧的办法:在ip列表的最开始放上客户源站的ip,这样就能保证最新了)
以上是第一个。
第二个:
客户首页上还有一个问题:其右下角有跟随悬浮窗口,本来应该可以关闭的。但一点关闭,就提示javascrpt:iclose()错误页面。而用浏览器另存为html到桌面以后,再打开保存下来的页面,点击关闭就正常关闭了!
经过查找,其中调用的js文件是http://msn.golfbox.cn/js/show.js,内容中关于javascrpt:iclose()的内容如下:
var sogouTall ='<div style="z-index:1000;position: absolute;display:none;" id="sogoubox">’
   +'<a href="javascript:iclose();" style="float:left; margin-left:190px">关闭</a>’
   +'<div style="clear:both"></div>’
   +'<a href="http://new.msn.golfbox.cn/wd/"><img src="http://new.msn.golfbox.cn/wd/dbtt.jpg" style="width:220px;height:160px"/></a>’
      + ‘<input type=hidden name="sogouAccountId" value="202014">’
   + ‘</div>’
 function iclose()
 {
  document.getElementById(‘sogoubox’).style.display=’none’;
 }
以我浅薄的web知识,是没看出来什么问题~~客户也莫名其妙,最好撤销掉这个窗口了……

分类:未分类 标签:,

lighttpd试用

4月 9, 2010 留下评论
昨晚试了一下lighttpd,和nginx相比,加载模块实在麻烦很多。因为lighttpd没有提供一个–add-module的编译方法,全靠自己在Makefile文件里左一块右一块的添加。 版本稍有不同,结果就只能失败。
比如我下载的lighttpd1.4.26,而mod_h264只有针对1.4.23的,辛辛苦苦修改完后,最后报错说某某函数不存在……
好在几个第三方模块的作者,估计也考虑到这点,所以也放出修改完毕的lighttpd源码包,直接编译就行。但还想把几个module整合在一起,就比较难了。
至于配置文件,网上都比较多了,一一试验过,还好,没暗中挖坑的,呵呵~
首先是server.module,至少要加载mod_access和mod_accesslog两个,然后必须在mod_proxy之前加载mod_cache;
然后是server.document-root,这个必须定义,相当于apache的DocumentRoot;
然后是server.event-handler,启用linux-sysepoll;
然后是accesslog.format,我仿造squid写的是"%{%s}t.000 %T %h TCP_HIT/%s %b http://%v%U%q %u NONE/- "%{Referer}i" "%{User-Agent}i"",这里面有不少问题,比如时间只能到秒,不支持毫秒……
然后是url.access-deny,很好理解;
然后是server.range-requests,多线程,默认是disable;
然后是server.max-*,包括server.max-keep-alive-requests、server.max-keep-alive-idle(keepalive对于普通访问没什么意义,完全可以关掉,对于大文件下载可以保留,默认128,idle如果太多,socket可能就不够了)、server.max-read-idle、server.max-write-idle、server.max-fds;
如果上头开了mod_evasive,就可以定义连接数evasive.max-conns-per-ip;
如果上头开了mod_simple_vhost,就可以定义虚拟主机,包括simple-vhost.server-root、simple-vhost.default-host、simple-vhost.document-root;
如果上头开了mod_compress,就可以定义压缩,包括compress.cache-dir和compress.filetype;
如果上头开了mod_expire,既可以定义header里的过期时间,格式如右:expire.url = ( "/buggy/" => "access 2 hours", "/asdhas/" => "access plus 1 seconds 2 minutes");
如果上头开了mod_setenv,就可以用setenv.add-response-header来添加更多的header,类似nginx的add-header(这个功能lighttpd更强,还能加request-header);
如果上头开了mod_fastcgi,就可以定义php解释器路径(同理,mod_cgi可以定义cgi的解释器路径);
如果上头开了mod_trigger_b4_dl(编译时带了–with-memcached),就可以定义trigger-before-download.*,启用memcached。
如果上头开了mod_status,可以通过status.status-url看到服务状态;
如果上头开了mod_rewrite,可以通过url.rewrite = ( "^/$" => "/server-status" )这样的方式进行重写;
同理还有mod_redirect,这两个还能使用正则和引用(编译时带了–with-pcre)。比较怪的一个用法是针对域名的。如下:
          $HTTP["host"] =~ "^www.(.*)" {
                                                       url.redirect            = ( "^/(.*)" => "http://%1/$1" )
                                                       }
这个%n的定义如下:
          # %0 => domain name + tld(全域名)
          # %1 => tld(顶级域名,见上例)
          # %2 => domain name without tld(全主机名)
          # %3 => subdomain 1 name(一级域名)
          # %4 => subdomain 2 name(二级域名)
这个东西在定义虚拟主机的文件路径时显然比较有用,如果开了mod_evhost,就可以采用这么定义:evhost.path-pattern = "/srv/www/vhosts/%3/htdocs/";
针对shtml等,还有ssi模块,这个不熟悉,不过想到之前有写过另一个博文关于esi的~
还有一个mod_rrdtool,可以定义rrdtool路径和生成的rrd文件路径;
和apache一样,也可以include其他的配置文件;
还有下载加密和限速的mod_secdownload、mod_traffic-shaping,在之前有过详述~
还有POST内容大小限制的mod_security模块,可以定义server.max-request-size;
此外,lighttpd还有关于变量和外部shell的定义,这个比较复杂,单看default.conf也比较莫名其妙,先不说了~~
最后说关键的(仅对我来说)cache和proxy配置:
首先定义cache.bases,相当于cache_dir;
cache.dynamic-mode,动态请求缓存,配合cache.support-queries;当两个都是enable的时候,带?号的url分别缓存;当support是enable而dynamic是disable的时候,带?号的url会忽略参数统一缓存;
cache.purge-host,定义允许purge操作的主机;
然后定义cache.refresh-pattern,可以使用的参数包括:ignore-reload、update-on-refresh、nocache、fetchall-for-range-request(多线程下载)、override-expire、ignore-vary、ignore-cache-control-header、flv-streaming;
如果启用了mod_mem_cache,那么还有cache.max-memory-size(和squid一样,建议使用实际内存的一半)和cache.lru-remove-count两个配置,然后在cache.refresh-pattern中启用use-memory参数;
如果启用了mod_mem_compress,在cache.refresh-pattern中还有memory-compress参数,可以根据浏览器请求压缩内存中缓存的文件。
(需要注意的是,lighttpd在内存中采用lru算法,在磁盘上却没有,在磁盘上用的是Directory的store方式)
接下来是proxy配置:
首先定义proxy.worked-with-mod-cache为enable;
然后定义proxy.balance,默认算法是fair,即响应速度优先,然后还有round-robin和hash。注意这个hash不是squid的sourcehash或者userhash,也不是nginx的iphash或者urlhash,而是类似squid中的CARP算法(txt说也能保证同一条url到同一个后台),据说很消耗CPU。
然后定义proxy.server,针对具体的路径设定host和port。
分类:未分类 标签:, , ,

url_rewrite_concurrency

4月 8, 2010 留下评论
squid的重定向,我看网上一般都采用redirect_children(即url_rewrite_children)。估计是因为中文权威指南的原因吧。不过中文权威指南还是2.5版的时候出的。有些新东西没有。比如squid.conf.default中提供的另一种url_rewrite_concurrency。
简单的说,就是开启url_rewrite_concurrency后,squid传递给rewriter的流由四个域增加为五个——最前头多了一个ID。然后rewriter返回的,也就有两个域,ID和uri。
简单修改一下原来的脚本如下即可:
#!/usr/bin/perl -wl
use strict;
$|=1;
while (<>)
{
my ($id,$url,$client,$ident,$method) = ( );
($id, $url, $client, $ident, $method) = split;
if ($url =~m#^(.*)(?.*)#i)
{
my ($domain,$option) = ($1,$2);
print “$id $domainn”;
}
else
{
print “$idn”;
}
}
然后squid.conf里修改如下:
acl rewriteurl url_regex -i ^http://drag.g1d.net/.*.mp40drag?
url_rewrite_access deny !rewriteurl
url_rewrite_program /home/squid/etc/redirect.pl
#url_rewrite_children 10
url_rewrite_concurrency 10
分类:未分类 标签:,

squid源站故障转向(终结篇)

3月 28, 2010 留下评论
因为这么一个想法,我陆陆续续的把squid很多功能都理了一遍,今天终于打算写个不完美的终结篇。而就在写这个终结篇的同时,公司里也已经开始把这批别扭的客户改往nginx平台加速了。
总结这批客户的跳转要求,其实格式都比较统一,大抵就是*.abc.com(.cn)坏了就转到abc.cdn.21vokglb.cn。在3月24日的博文最后,已经有了一个思路——既然无法执行php的header(Location)和strstr(%U),那么就干脆在squid的src里对%U进行操作好了。
squid-src/errorpage.c中关于%U的注释是:
U – URL without password
相关语句是:
p = r ? urlCanonicalClean(r) : err->url ? err->url : “[no URL]”;
只要把url按”.”分割,然后取出第二个域abc,就可以在html代码中给它加上跳转后的url了——这一步也能在src里完成,不过以后不好修改了,虽然现在这样子的定制性也强不到哪去~
从大二到现在无数年了,c已经属于忘到冥王星外的东东,于是一个一个的翻c的字符串函数,从strstr、strchr、strcat、strtok、strsep到最后终于发现sscanf。只要在src/errorpage.c的588行下加这么一句话就可以了:
587     case ‘U’:
588         p = r ? urlCanonicalClean(r) : err->url ? err->url : “[no URL]”;
589+      sscanf(p,”%*[^.].%[^.]”,p);
590         break;
然后编译安装,一路通过没有问题~~启动squid服务,测试一下%U吧~
先把ERR_ACCESS_DENIED内容修改如下:
<HTML>
<BODY>
<head>
<META HTTP-EQUIV=”refresh”   Content=”0;URL=http://%U.cdn.21vokglb.cn/index.htm”>
</head>
</HTML>
然后在squid.conf中增加对自己本机的访问控制如下:
acl test src 222.62.104.189/255.255.255.255
http_access deny rao
squid -k reconfigure生效,访问一下www.xyfunds.com.cn,果然跳转到xyfunds.cdn.21vokglb.cn/index.htm啦~~
完毕。
虽然最终还是没能达到任意定义跳转url的目标,不过就本身的出发点来说,还是完成了需求。这也是我N年来第一次重新看C,也是第一次修改squid代码,虽然只加了一句~~~不过意义还是有滴,晚上吃个鸡蛋自我犒劳一下咯。

分类:未分类 标签:, ,

squid和nginx的error_page差别

3月 24, 2010 1条评论
nginx的error_page,有两个种办法。
一是直接error_page 502 503 504 = http://xyfunds.cdn.21vokglb.cn/index.htm;
二是error_page 502 503 504 =200 @fetch;然后location ~* @fetch {……}。
网上看到很多自定义error_page的方式,比如error_page 404 /404.php;把变量都传给php去分析处理;
也可以在location里用if(){}做rewrite等等。

squid的error_page,可以有error_directory、error_map、deny_info三种方式。其中deny_info仅适用于ERR_ACCESS_DENIED一种情况;目前对于源站故障跳转,采用的是修改error_directory里html的meta;今天由nginx的方式想到采用error_map试试,于是写了如下php页面:
<?php
switch ($_SERVER[‘SERVER_NAME’])
{
case ‘www.xyfunds.com.cn’:
header(“Location: http://xyfunds.cdn.21vokglb.cn/index.htm&#8221;);
break;
default:
echo $_SERVER[‘SERVER_NAME’];
}
?>
但测试结果,ERR的页面却是一片空白……在squid.conf,default中看到,原来error_map只是返回定义页面的内容,header还是原先的。
于是又想针对squid返回的%U,进行strtr(),然后再进行meta,如下:
<?php
$urlarray = array(‘com.cn’=>’21vokglb.cn’);
$urlrewrite = strtr(“%U”,$urlarray);
echo <META HTTP-EQUIV=”refresh” CONTENT=”0; $urlrewrite”>;
?>
很可惜,测试结果是把这串字符直接显示在了页面上。
这两个结果让我很无语。如果说squid不支持php,那为什么它能识别出来上一个是修改header而不是页面内容所以不显示文本;如果说squid支持php,那为什么下一个又无法执行呢?

想对%U进行操作,难道非得到squid/src/errorpage.c里去修改么?C语言的字符串处理没有封装好的函数,真的好麻烦的说……

分类:未分类 标签:, ,