Skip to content

Commit

Permalink
improved support for relative redirects in Mojo::UserAgent::Transactor
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Nov 24, 2012
1 parent 1e5af14 commit fa572d6
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 28 deletions.
3 changes: 2 additions & 1 deletion Changes
@@ -1,5 +1,6 @@

3.61 2012-11-23
3.61 2012-11-24
- Improved support for relative redirects in Mojo::UserAgent::Transactor.
- Improved documentation.
- Improved tests.

Expand Down
8 changes: 3 additions & 5 deletions lib/Mojo/UserAgent/Transactor.pm
Expand Up @@ -139,16 +139,14 @@ sub redirect {
# Fix broken location without authority and/or scheme
return unless my $location = $res->headers->location;
$location = Mojo::URL->new($location);
my $req = $old->req;
my $url = $req->url;
$location->authority($url->authority) unless $location->authority;
$location->scheme($url->scheme) unless $location->scheme;
$location = $location->base($old->req->url)->to_abs unless $location->scheme;

# Clone request if necessary
my $new = Mojo::Transaction::HTTP->new;
my $req = $old->req;
my $method = $req->method;
if (grep { $_ eq $code } 301, 307, 308) {
return undef unless $req = $req->clone;
return undef unless my $req = $req->clone;
$new->req($req);
$req->headers->remove('Host')->remove('Cookie')->remove('Referer');
}
Expand Down
76 changes: 54 additions & 22 deletions t/mojo/transactor.t
Expand Up @@ -314,8 +314,8 @@ is $tx->req->headers->proxy_authorization, 'Basic c3JpOnNlY3IzdA==',
is $tx->req->headers->host, '127.0.0.1:3000', 'right "Host" header';

# Simple 302 redirect
$tx
= $t->tx(POST => 'http://mojolico.us/foo' => {Accept => 'application/json'});
$tx = $t->tx(
POST => 'http://mojolicio.us/foo' => {Accept => 'application/json'});
$tx->res->code(302);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
Expand All @@ -330,7 +330,7 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# 302 redirect (dynamic)
$tx = $t->tx(POST => 'http://mojolico.us/foo');
$tx = $t->tx(POST => 'http://mojolicio.us/foo');
$tx->res->code(302);
$tx->res->headers->location('http://kraih.com/bar');
$tx->req->write_chunk('whatever' => sub { shift->finish });
Expand All @@ -344,8 +344,8 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# Simple 303 redirect
$tx
= $t->tx(POST => 'http://mojolico.us/foo' => {Accept => 'application/json'});
$tx = $t->tx(
POST => 'http://mojolicio.us/foo' => {Accept => 'application/json'});
$tx->res->code(303);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
Expand All @@ -360,7 +360,7 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# 303 redirect (dynamic)
$tx = $t->tx(POST => 'http://mojolico.us/foo');
$tx = $t->tx(POST => 'http://mojolicio.us/foo');
$tx->res->code(303);
$tx->res->headers->location('http://kraih.com/bar');
$tx->req->write_chunk('whatever' => sub { shift->finish });
Expand All @@ -375,7 +375,7 @@ is $tx->res->headers->location, undef, 'no "Location" value';

# 303 redirect (additional headers)
$tx = $t->tx(
POST => 'http://mojolico.us/foo' => {
POST => 'http://mojolicio.us/foo' => {
Accept => 'application/json',
Cookie => 'one',
Host => 'two',
Expand All @@ -402,8 +402,8 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# Simple 301 redirect
$tx
= $t->tx(POST => 'http://mojolico.us/foo' => {Accept => 'application/json'});
$tx = $t->tx(
POST => 'http://mojolicio.us/foo' => {Accept => 'application/json'});
$tx->res->code(301);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
Expand All @@ -419,7 +419,7 @@ is $tx->res->headers->location, undef, 'no "Location" value';

# 301 redirect with content
$tx = $t->tx(
POST => 'http://mojolico.us/foo' => {Accept => '*/*'} => 'whatever');
POST => 'http://mojolicio.us/foo' => {Accept => '*/*'} => 'whatever');
$tx->res->code(301);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, '*/*', 'right "Accept" value';
Expand All @@ -434,15 +434,15 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# 301 redirect (dynamic)
$tx = $t->tx(POST => 'http://mojolico.us/foo');
$tx = $t->tx(POST => 'http://mojolicio.us/foo');
$tx->res->code(301);
$tx->res->headers->location('http://kraih.com/bar');
$tx->req->write_chunk('whatever' => sub { shift->finish });
is $t->redirect($tx), undef, 'unsupported redirect';

# Simple 307 redirect
$tx
= $t->tx(POST => 'http://mojolico.us/foo' => {Accept => 'application/json'});
$tx = $t->tx(
POST => 'http://mojolicio.us/foo' => {Accept => 'application/json'});
$tx->res->code(307);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
Expand All @@ -458,7 +458,7 @@ is $tx->res->headers->location, undef, 'no "Location" value';

# 307 redirect with content
$tx = $t->tx(
POST => 'http://mojolico.us/foo' => {Accept => '*/*'} => 'whatever');
POST => 'http://mojolicio.us/foo' => {Accept => '*/*'} => 'whatever');
$tx->res->code(307);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, '*/*', 'right "Accept" value';
Expand All @@ -473,15 +473,15 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# 307 redirect (dynamic)
$tx = $t->tx(POST => 'http://mojolico.us/foo');
$tx = $t->tx(POST => 'http://mojolicio.us/foo');
$tx->res->code(307);
$tx->res->headers->location('http://kraih.com/bar');
$tx->req->write_chunk('whatever' => sub { shift->finish });
is $t->redirect($tx), undef, 'unsupported redirect';

# 307 redirect (additional headers)
$tx = $t->tx(
POST => 'http://mojolico.us/foo' => {
POST => 'http://mojolicio.us/foo' => {
Accept => 'application/json',
Cookie => 'one',
Host => 'two',
Expand All @@ -508,8 +508,8 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# Simple 308 redirect
$tx
= $t->tx(POST => 'http://mojolico.us/foo' => {Accept => 'application/json'});
$tx = $t->tx(
POST => 'http://mojolicio.us/foo' => {Accept => 'application/json'});
$tx->res->code(308);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
Expand All @@ -525,7 +525,7 @@ is $tx->res->headers->location, undef, 'no "Location" value';

# 308 redirect with content
$tx = $t->tx(
POST => 'http://mojolico.us/foo' => {Accept => '*/*'} => 'whatever');
POST => 'http://mojolicio.us/foo' => {Accept => '*/*'} => 'whatever');
$tx->res->code(308);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, '*/*', 'right "Accept" value';
Expand All @@ -540,19 +540,51 @@ is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# 308 redirect (dynamic)
$tx = $t->tx(POST => 'http://mojolico.us/foo');
$tx = $t->tx(POST => 'http://mojolicio.us/foo');
$tx->res->code(308);
$tx->res->headers->location('http://kraih.com/bar');
$tx->req->write_chunk('whatever' => sub { shift->finish });
is $t->redirect($tx), undef, 'unsupported redirect';

# 309 redirect (unsupported)
$tx
= $t->tx(POST => 'http://mojolico.us/foo' => {Accept => 'application/json'});
$tx = $t->tx(
POST => 'http://mojolicio.us/foo' => {Accept => 'application/json'});
$tx->res->code(309);
$tx->res->headers->location('http://kraih.com/bar');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
is $tx->req->body, '', 'no content';
is $t->redirect($tx), undef, 'unsupported redirect';

# 302 redirect (relative path)
$tx = $t->tx(
POST => 'http://mojolicio.us/foo/bar' => {Accept => 'application/json'});
$tx->res->code(302);
$tx->res->headers->location('baz');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
is $tx->req->body, '', 'no content';
$tx = $t->redirect($tx);
is $tx->req->method, 'GET', 'right method';
is $tx->req->url->to_abs, 'http://mojolicio.us/foo/baz', 'right URL';
is $tx->req->headers->accept, undef, 'no "Accept" value';
is $tx->req->headers->location, undef, 'no "Location" value';
is $tx->req->body, '', 'no content';
is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

# 302 redirect (absolute path)
$tx = $t->tx(
POST => 'http://mojolicio.us/foo/bar' => {Accept => 'application/json'});
$tx->res->code(302);
$tx->res->headers->location('/baz');
is $tx->req->headers->accept, 'application/json', 'right "Accept" value';
is $tx->req->body, '', 'no content';
$tx = $t->redirect($tx);
is $tx->req->method, 'GET', 'right method';
is $tx->req->url->to_abs, 'http://mojolicio.us/baz', 'right URL';
is $tx->req->headers->accept, undef, 'no "Accept" value';
is $tx->req->headers->location, undef, 'no "Location" value';
is $tx->req->body, '', 'no content';
is $tx->res->code, undef, 'no status';
is $tx->res->headers->location, undef, 'no "Location" value';

done_testing();

0 comments on commit fa572d6

Please sign in to comment.