#!/usr/local/bin/perl -w # # jscache.cgi - Cache javascript feed content on your server # # AUTHOR: Tatsuhiko Miyagawa # LICENSE: free software, licensed under the same license as Perl. # use strict; use vars qw($VERSION $remote_url $cache_dir $cache_ttl $get_app $debug); $VERSION = "0.01"; #-------------------------------------------------- # 設定項目ここから # 中継する javascript URL # パラメータなどはのぞく $remote_url = "http://bulkfeeds.net/app/similar.js"; # キャッシュディレクトリ # Web サーバのユーザ権限で writable である必要がある $cache_dir = "/tmp/jscache"; # キャッシュする時間 (単位: 分) $cache_ttl = 60; # HTTP 接続に使用するアプリケーション # LWP がインストールされている場合は設定不要 # 'lynx -source' # 'wget --quiet -O -' # 'curl -m 30 -s' $get_app = ''; # デバッグ変数 $debug = 1; # 設定項目ここまで #-------------------------------------------------- my $url = $remote_url; $url .= "?$ENV{QUERY_STRING}" if $ENV{QUERY_STRING}; warn "remote url is $url" if $debug; my $cache_file = cache_for($url); warn "cache file for $url is $cache_file" if $debug; if (-e $cache_file && -M _ < ($cache_ttl / (24 * 60))) { warn "using cache file $cache_file" if $debug; output_content($cache_file); } else { warn "no cache available or expired." if $debug; my $content = get_content($url); store_cache($cache_file, $content); output_content($cache_file); } sub cache_for { my $url = shift; $url =~ s/(\W)/'%' . unpack('H2', $1)/eg; # uri_escape unless (-e $cache_dir) { warn "cache dir $cache_dir doesn't exit. Try mkdir" if $debug; mkdir $cache_dir, 0777 or die "$cache_dir: $!"; } return $cache_dir . "/" . $url; } sub get_content { my $url = shift; my $have_lwp = eval "require LWP::Simple; 1"; if ($have_lwp) { warn "you have LWP::Simple installed." if $debug; return LWP::Simple::get($url); } else { # taint it $url =~ s/([^A-Za-z0-9\-_.!~*'()=\?&])/'%' . unpack('H2', $1)/eg; my $content; open APP, qq/$get_app "$url" |/ or die "$get_app: $!"; while () { $content .= $_; } close APP; return $content; } } sub output_content { my $cache_file = shift; my $content_type = "application/x-javascript"; if ($ENV{MOD_PERL}) { my $r = Apache->request; $r->send_http_header("Content-Type: $content_type"); } else { print "Content-Type: $content_type\n\n"; } open CACHE, $cache_file or die "$cache_file: $!"; while () { print } close CACHE; } sub store_cache { my($cache_file, $content) = @_; warn "writing content to $cache_file" if $debug; open OUT, ">$cache_file" or die "$cache_file: $!"; print OUT $content; close OUT; }