Subject: | check_redirect() is over-protective when it comes to redirect loops |
If you look at the code for check_redirect() in
POE::Component::Client::HTTP::Request, it has this little snippet around
line 436:
my $prev = $self;
my $history = 0;
while ($prev = $prev->[REQ_HISTORY]) {
$history++;
$history = $max + 1 if ($prev->[REQ_REQUEST]->uri eq $new_uri);
last if ($history > $max);
}
This checks for redirect loops. Unfortunately, the line:
$history = $max + 1 if ($prev->[REQ_REQUEST]->uri eq $new_uri);
breaks when CAS authentication is employed by some CAS clients. In such
a case, I might expect the following to happen:
1. I request https://service.example.com/protected.html
2. The service.example.com server wants to verify my identity, so it
redirects me to:
https://sso.example.com/cas/login?service=https://service.example.com/protected.html
3. The CAS server already notes I'm logged in, so it immediately
redirects me back to
https://service.example.com/protected.html?ticket=ST-y329rhoi9ch92...
4. The service server helpfully redirects me one more time to strip
the service ticket from the URL to
https://service.example.com/protected.html
In this case, the snippet is overly defensive and stops one hop short of
the intended final destination.
Commenting that line out in the source resolves issue. I suggest that
either this be removed or an option be added that allows the end-user to
turn it off.