返信用

リクエストがあったので。
@

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)