メモ的に書きます。ので、やっつけです。
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;
my $headers = $request->headers;
$headers->{'user-agent'} = $self->agent;
my %options = (
timeout => $self->timeout,
headers => $headers,
body => $request->content,
cookie_jar => $jar,
recurse => $self->recurse,
);
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);
$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;
$client->get($response->header('location'), sub {
my $response = shift;
$cv->send;
});
});
$cv->recv;
ただ、これだとたるいので、Tatsumaki::HTTPClient::Custom::request の $headers->{'user-agent'} = $self->agent; の後に delete $headers->{'content-length'} しておけば、recurse => 0 する必要も、再度 get リクエストする必要もないので、たるい時にはそれでいいかもしれないです。