リクエストがあったので。
@xcir
perl版も書いてみた 後でinotify対応のコードを書く Varnishのパージを行うパッケージ(Perl) http://bit.ly/9dfK2s #varnish #varnishjp ... perl版もかいたけどどうかんがえても @mikeda につっこまれそう!
設計やモジュールの書き方はつっこまないことにして・・・
(といいつつ好みでちょこちょこいじってるけど。)
確認プログラム
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; require "purge.pm"; #リクエストを投げたいVarnishサーバの配列 my @v = ("192.168.1.123"); #パージしたいURLの配列 my @u = ("http://blog.xcir.net/test.jpg","http://blog.xcir.net/test2.jpg"); #パージ実行 my %r = Varnish::HTTP::Purge::purge(\@v,\@u); print Data::Dumper::Dumper(\%r);
モジュールのほう
package Varnish::HTTP::Purge; use strict; use warnings; use Net::HTTP; sub purge{ my($varnish, $url, $port) = @_; $port ||= 80; my %ret = (all => 1); foreach my $v(@{$varnish}){ foreach my $u(@{$url}){ $ret{$v}->{$u} = _purge($v, $u, $port); $ret{all} = 0 if $ret{$v}->{$u} != 200; } } return %ret; } sub _purge{ my ($varnish, $url, $port) = @_; my $req=Net::HTTP->new( Host => $varnish, PeerPort => $port, Timeout => 2 ) or die "Can't connect $varnish:$port. $!"; # ) or return 0;; my ($host, $path) = $url =~ m{^http://([^/]+)(/.*)?$}; $path ||= "/"; $req->write_request('PURGE' => $path, Host => $host); my ($code) = $req->read_response_headers; # return $code == 200 ? 1 : 0; return $code; } 1;
ついでにRuby版プロトタイプ
#!/usr/bin/ruby require 'net/http' require 'uri' class Varnish class Net::HTTP class Purge < Net::HTTPRequest METHOD = 'PURGE' REQUEST_HAS_BODY = false RESPONSE_HAS_BODY = true end end def self.purge(varnish, url, port = 80) ret = Hash.new varnish.each do |v| ret[v] ||= Hash.new url.each do |u| ret[v][u] = _purge(v, u, port) end end ret end private def self._purge(varnish, url, port) uri = URI.parse(url) http = Net::HTTP.new(varnish) req = Net::HTTP::Purge.new(uri.path) req["Host"] = uri.host http.request(req).code end end require 'pp' varnish = ["192.168.1.123"] url = [ "http://blog.xcir.net/test.jpg", "http://blog.xcir.net/test2.jpg" ] pp Varnish::purge(varnish, url)