use URI ();
use URI::http;
use URI::https;
+use HTML::Entities;
use Tree::Simple qw/use_weak_refs/;
use Tree::Simple::Visitor::FindByUID;
use Class::C3::Adopt::NEXT;
if ( !$response->has_body ) {
# Add a default body if none is already present
+ my $encoded_location = encode_entities($location);
$response->body(<<"EOF");
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<title>Moved</title>
</head>
<body>
- <p>This item has moved <a href="$location">here</a>.</p>
+ <p>This item has moved <a href="$encoded_location">here</a>.</p>
</body>
</html>
EOF
$c->res->redirect('/go_here');
}
+sub test_redirect_uri_for :Global {
+ my ($self, $c) = @_;
+ # Don't set content_type
+ # Don't set body
+ $c->res->redirect($c->uri_for('/go_here'));
+}
+
sub test_redirect_with_contenttype :Global {
my ($self, $c) = @_;
# set content_type but don't set body
like( $response->content, qr/kind sir/, 'Content contains content set by the Controller' );
}
+# test redirect with dodgy host
+{
+ local $Catalyst::Test::default_host = "-->\">'>'\"<sfi000003v407412>";
+ my $request =
+ HTTP::Request->new( GET => 'http://localhost:3000/test_redirect_uri_for');
+
+ ok( my $response = request($request), 'Request' );
+ is( $response->code, 302, 'Response Code' );
+
+ # When no body and no content_type has been set, redirecting should set both.
+ is( $response->header( 'Content-Type' ), 'text/html; charset=utf-8', 'Content Type' );
+ like( $response->content, qr/<body>/, 'Content contains HTML body' );
+ like( $response->content, qr/href="[^"]+">here<\/a>/, 'link doesn\'t have xss' );
+}
+
done_testing;