Bit.lyでのURL圧縮

http://search.cpan.org/~pjain/WWW-Shorten-Bitly/
eqbot@Twitterで使うURLの圧縮をTinyURL.comからBit.lyに切り替えましたが、WWW::Shorten::Bitlyでは適切なURLエンコードを行わずにAPIへ引数を渡そうとするため、一部のアドレスを正しく変換できないようです。

--- WWW-Shorten-Bitly-1.06/lib/WWW/Shorten/Bitly.pm	2009-03-06 06:32:32.000000000 +0900
+++ WWW-Shorten-Bitly-1.06-mod/lib/WWW/Shorten/Bitly.pm	2009-06-06 10:17:36.000000000 +0900
@@ -133,8 +133,13 @@
     my $bitly;
     $bitly->{json}     = JSON::Any->new;
     $bitly->{xml}   = new XML::Simple(SuppressEmpty => 1);
-    my $biturl = "http://api.bit.ly/shorten?history=1&version=2.0.1&longUrl=" . $url . "&login=" . $user . "&apiKey=" . $apikey;
-    $bitly->{response} = $ua->get($biturl);
+    $bitly->{response} = $ua->post('http://api.bit.ly/shorten', [
+        'history' => '1',
+        'version' => '2.0.1',
+        'longUrl' => $url,
+        'login' => $user,
+        'apiKey' => $apikey,
+    ]);
     $bitly->{bitlyurl} = $bitly->{json}->jsonToObj($bitly->{response}->{_content})->{results}->{$url}->{shortUrl};
     return unless $bitly->{response}->is_success;
     return $bitly->{bitlyurl};
@@ -160,8 +165,12 @@
     my @foo = split(/\//, $url);
     $bitly->{json}     = JSON::Any->new;
     $bitly->{xml}   = new XML::Simple(SuppressEmpty => 1);
-    my $biturl = URI->new('http://api.bit.ly/expand?version=2.0.1&shortUrl=' . $url . '&login=' . $user . '&apiKey=' . $apikey);
-    $bitly->{response} = $ua->get($biturl);
+    $bitly->{response} = $ua->post('http://api.bit.ly/expand', [
+        'version' => '2.0.1',
+        'shortUrl' => $url,
+        'login' => $user,
+        'apiKey' => $apikey,
+    ]);
     $bitly->{longurl} = $bitly->{json}->jsonToObj($bitly->{response}->{_content})->{results}->{$foo[3]}->{longUrl};
     return undef unless $bitly->{response}->is_success;
     my $content = $bitly->{response}->content;
@@ -190,8 +199,13 @@
         croak("URL is required.\n");
         return -1;
     }
-    $self->{short}   = "http://api.bit.ly/shorten?history=1&version=2.0.1&longUrl=" . $args{URL} ."&login=" . $self->{USER} . "&apiKey=" . $self->{APIKEY};
-    $self->{response} = $self->{browser}->get($self->{short});
+    $self->{response} = $self->{browser}->post('http://api.bit.ly/shorten', [
+        'history' => '1',
+        'version' => '2.0.1',
+        'longUrl' => $args{URL},
+        'login' => $self->{USER},
+        'apiKey' => $self->{APIKEY},
+    ]);
     return undef if ( $self->{json}->jsonToObj($self->{response}->{_content})->{errorCode} != 0 );
     $self->{bitlyurl} = $self->{json}->jsonToObj($self->{response}->{_content})->{results}->{$args{URL}}->{shortUrl};
     return $self->{bitlyurl} if ( $self->{json}->jsonToObj($self->{response}->{_content})->{errorCode} == 0 );
@@ -210,8 +224,13 @@
         return -1;
     }
     my @foo = split(/\//, $args{URL});
-    $self->{short}   = "http://api.bit.ly/expand?history=1&version=2.0.1&shortUrl=" . $args{URL} ."&login=" . $self->{USER} . "&apiKey=" . $self->{APIKEY};
-    $self->{response} = $self->{browser}->get($self->{short});
+    $self->{response} = $self->{browser}->get('http://api.bit.ly/expand', [
+        'history' => '1',
+        'version' => '2.0.1',
+        'shortUrl' => $args{URL},
+        'login' => $self->{USER},
+        'apiKey' => $self->{APIKEY},
+    ]);
     return undef if ( $self->{json}->jsonToObj($self->{response}->{_content})->{errorCode} != 0 );
     $self->{longurl} = $self->{json}->jsonToObj($self->{response}->{_content})->{results}->{$foo[3]}->{longUrl};
     return $self->{longurl} if ( $self->{json}->jsonToObj($self->{response}->{_content})->{errorCode} == 0 );
@@ -233,8 +252,13 @@
 
 sub info {
     my $self = shift;
-    my $base = "http://api.bit.ly/info?format=xml&version=2.0.1&shortUrl=" . $self->{bitlyurl} . "&login=" . $self->{USER} . "&apiKey=" . $self->{APIKEY};
-    $self->{response} = $self->{browser}->get($base);
+    $self->{response} = $self->{browser}->post('http://api.bit.ly/info', [
+        'format' => 'xml',
+        'version' => '2.0.1',
+        'shortUrl' => $self->{bitlyurl},
+        'login' => $self->{USER},
+        'apiKey' => $self->{APIKEY},
+    ]);
     $self->{$self->{bitlyurl}}->{content} = $self->{xml}->XMLin($self->{response}->{_content});
     $self->{$self->{bitlyurl}}->{errorCode} = $self->{$self->{bitlyurl}}->{content}->{errorCode};
     if ($self->{$self->{bitlyurl}}->{errorCode} == 0 ) {
@@ -259,8 +283,13 @@
 
 sub clicks {
     my $self = shift;
-    my $base = "http://api.bit.ly/stats?format=xml&version=2.0.1&shortUrl=" . $self->{bitlyurl} . "&login=" . $self->{USER} . "&apiKey=" . $self->{APIKEY};
-    $self->{response} = $self->{browser}->get($base);
+    $self->{response} = $self->{browser}->post('http://api.bit.ly/stats', [
+        'format' => 'xml',
+        'version' => '2.0.1',
+        'shortUrl' => $self->{bitlyurl},
+        'login' => $self->{USER},
+        'apiKey' => $self->{APIKEY},
+    ]);
     $self->{$self->{bitlyurl}}->{content} = $self->{xml}->XMLin($self->{response}->{_content});
     $self->{$self->{bitlyurl}}->{errorCode} = $self->{$self->{bitlyurl}}->{content}->{errorCode};
     if ($self->{$self->{bitlyurl}}->{errorCode} == 0 ) {
@@ -277,8 +306,11 @@
 
 sub errors {
     my $self = shift;
-    my $base = "http://api.bit.ly/errors?version=2.0.1&login=" . $self->{USER} . "&apiKey=" . $self->{APIKEY};
-    $self->{response} = $self->{browser}->get($base);
+    $self->{response} = $self->{browser}->post('http://api.bit.ly/errors', [
+        'version' => '2.0.1',
+        'login' => $self->{USER},
+        'apiKey' => $self->{APIKEY},
+    ]);
     $self->{$self->{bitlyurl}}->{content} = $self->{xml}->XMLin($self->{response}->{_content});
     $self->{$self->{bitlyurl}}->{errorCode} = $self->{$self->{bitlyurl}}->{content}->{errorCode};
     if ($self->{$self->{bitlyurl}}->{errorCode} == 0 ) {

とりあえず対策してみました。(GETからPOSTに変更、エスケープ処理等はLWPに丸投げ)

$ perl -e 'use WWW::Shorten::Bitly;print makeashorterlink(qq{http://www.kyoshin.bosai.go.jp/cgi-bin/kyoshin/avidisp.cgi?0+20090606055046},q{bitlyapidemo},q{R_0da49e0a9118ff35f52f629d2d71bf07}),qq{\n}'
http://bit.ly/OvCKZ