Tatsumaki::HTTPClient で Pixivにログインする
メモ的に書きます。ので、やっつけです。
AnyEvent::HTTP で pixivにログインしようとする際に recurse を指定しておかないと、/login.php にデータをポストした後、自動的に Loation ヘッダが示すURLに移動しようとします。
が、Content-Lenghtなど を保持したまま移動しようしているようで、そのままでは上手く移動できません。なので、recurse => 0 指定して、レスポンスが帰って来たら Locationが示すURLに移動するなどします。
が、Tatsumaki::HTTPClient では recurse 指定する方法がありません。なので Tatsumaki::HTTPClient を拡張して使えるようにしてみます。
package Tatsumaki::HTTPClient::Custom; use Tatsumaki; use AnyEvent::HTTP; use Moo; use MooX::late; extends qw(Tatsumaki::HTTPClient); has jar => (is => 'rw', isa => 'HashRef', default => sub { +{version => 1} }); has recurse => (is => 'rw', isa => 'Num', default => $AnyEvent::HTTP::MAX_RECURSE); has agent => (is => 'rw', isa => 'Str', default => sub { join '/', __PACKAGE__, $Tatsumaki::VERSION }); sub request { my($self, $request, $cb) = @_; my $jar = $self->jar; # add my $headers = $request->headers; $headers->{'user-agent'} = $self->agent; ### delete $headers->{'content-length'}; ### my %options = ( timeout => $self->timeout, headers => $headers, body => $request->content, cookie_jar => $jar, # add recurse => $self->recurse, #add ); AnyEvent::HTTP::http_request $request->method, $request->uri, %options, sub { my($body, $header) = @_; my $res = HTTP::Response->new($header->{Status}, $header->{Reason}, [ %$header ], $body); $self->jar($jar); # add $cb->($res); }; } package main; use strict; use warnings; use AE; my $login_php = 'http://www.pixiv.net/login.php'; my %query = (mode => 'login', pixiv_id => 'foo', pass => 'bar'); my $client = Tatsumaki::HTTPClient::Custom->new(recurse => 0); my $cv = AE::cv; $client->post($login_php => \%query, sub { my $response = shift; ### Tatsumaki::HTTPClient::Custom::request で delete $headers->{'content-length'} しておくと ### 以降のリクエストは AnyEvent::HTTP がめんどうみてくれる $client->get($response->header('location'), sub { my $response = shift; # some work ... $cv->send; }); }); $cv->recv;
ただ、これだとたるいので、Tatsumaki::HTTPClient::Custom::request の $headers->{'user-agent'} = $self->agent; の後に delete $headers->{'content-length'} しておけば、recurse => 0 する必要も、再度 get リクエストする必要もないので、たるい時にはそれでいいかもしれないです。