Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the WWW-Mechanize CPAN distribution.

Report information
The Basics
Id: 2812
Status: resolved
Priority: 0/
Queue: WWW-Mechanize

People
Owner: Nobody in particular
Requestors: stuart [...] terminus.co.uk
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.44
Fixed in: (no value)



Subject: make redirection of POST requests work the same way that browsers do
WWW-Mechanize-0.44 introduced the behaviour of following redirects after a POST. This is non-RFC compliant, but it's what most browsers do and we're attempting to mimic them so we do the same. However, when browsers do so they also change the method from POST to GET. Not doing so can cause problems with some web-server applications. In order to fix this I have created a patch that overloads redirect_ok() from LWP::UserAgent. I have tested it using perl version v5.6.1 built for sun4-solaris-thread-multi with patch "ActivePerl Build 631" applied, on a SUNW,Ultra-250 running Solaris 8.
914a915,942 > > =head2 redirect_ok($prospective_request) > > An overloaded version of C<redirect_ok()> in L<LWP::UserAgent>. This method is used to determine whether a redirection in the request should be followed. > > This version behaves like the original, except that if the redirection was from a POST it changes the HTTP method to GET. This does not conform with the RFCs, but it is how many browser user agent implementations behave. As we are trying to model them, we must unfortunately mimic their erroneously reaction. See L<http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3> for details on correct behaviour. > > =cut > > sub redirect_ok > { > my($self, $request) = @_; > my $method = $request->method; > return 0 unless grep $_ eq $method, > @{ $self->requests_redirectable || [] }; > > if($request->url->scheme eq 'file') { > LWP::Debug::trace("Can't redirect to a file:// URL!"); > return 0; > } > > # Mimic erroneously browser behaviour. > $request->method("GET") if $request->method eq "POST"; > > # Otherwise it's apparently okay... > return 1; > } >
So should I still do this, make a redirected POST become a GET? What are the pros and cons?
From: stuart [...] terminus.co.uk
[PETDANCE - Mon Jun 23 15:38:44 2003]: Show quoted text
> So should I still do this, make a redirected POST become a GET? What > are the pros and cons?
Yes please! The only con that I am aware of is that this behavior is not compliant with the RFCs. However, that's not really an issue - redirecting a POST at all (whether you change the method or not) is not compliant with the RFCs! All the "main" user agents (ie: the real browsers) behave as I've said: when they receive a redirect following a POST, they follow the redirect, but change the HTTP method to GET. As Mechanize aims to duplicate their behaviour, to do otherwise is IMO a bug. Additionally, I am not aware of any significant user agents that behave as Mechanize currently does - which is both non RFC compliant, and non "industry standard" compliant. There may be some however - I've not investigated thoroughly. The main pro for me personally is that the current Mechanize behaviour causes problems. Some URIs can not accept POST requests. Such a page may be retrieving as the result of a redirect from a page that was POSTed to. Most static content won't care, but some web server applications do. Applying this fix makes Mechanize work for such pages, and won't break pages that are currently being POSTed to (unless they require POSTs, in which case they don't work with common browsers). I have an updated patch against Mechanize-0.48. I shall attach it to this bug tomorrow from work.
From: stuart [...] terminus.co.uk
[guest - Mon Jun 23 17:26:03 2003]: Show quoted text
> I have an updated patch against Mechanize-0.48. I shall attach it to > this bug tomorrow from work.
Here it is as promised. Please note that in addition to fixing the bug described above, this patch also tidies up the doc comments, and implements the checking of requests_redirectable that LWP::UserAgent does (in order to remain compatible with it). Any questions, please ask.
996c996 < =head2 C<< redirect_ok() >> --- > =head2 C<< $a->redirect_ok() >> 998,999c998 < Keep track of the last uri redirected to, and tell our parent that it's < OK to do the redirect. --- > An overloaded version of C<redirect_ok()> in L<LWP::UserAgent>. This method is used to determine whether a redirection in the request should be followed. 1000a1000,1001 > Keep track of the last uri redirected to. Also if the redirection was from a POST change the HTTP method to GET. This does not conform with the RFCs, but it is how many browser user agent implementations behave. As we are trying to model them, we must unfortunately mimic their erroneously reaction. See L<http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3> for details on correct behaviour. > 1004c1005,1008 < $_[0]->{redirected_uri} = $_[1]->uri; --- > my($self, $request) = @_; > my $method = $request->method; > return 0 unless grep $_ eq $method, > @{ $self->requests_redirectable || [] }; 1005a1010,1016 > # Keep track of the last uri redirected to. > $self->{redirected_uri} = $request->uri; > > # Mimic erroneously browser behaviour by changing the method. > $request->method("GET") if $request->method eq "POST"; > > # OK to redirect.
From: stuart [...] terminus.co.uk
[guest - Tue Jun 24 09:54:06 2003]: Show quoted text
> [guest - Mon Jun 23 17:26:03 2003]: >
> > I have an updated patch against Mechanize-0.48. I shall attach it to > > this bug tomorrow from work.
> > Here it is as promised. Please note that in addition to fixing the bug > described above, this patch also tidies up the doc comments, and > implements the checking of requests_redirectable that LWP::UserAgent > does (in order to remain compatible with it).
Sigh, and then I notice 0.49 has been released. Here's a patch against that instead. 0.49 made redirect_ok call the UserAgent method of the same name, so I've removed the checking mentioned above from this patch. Otherwise it's the same. Could this please be applied ASAP (in any case before the next release)?
996c996 < =head2 C<< redirect_ok() >> --- > =head2 C<< $a->redirect_ok() >> 998,999c998 < Keep track of the last uri redirected to, and tell our parent that it's < OK to do the redirect. --- > An overloaded version of C<redirect_ok()> in L<LWP::UserAgent>. This method is used to determine whether a redirection in the request should be followed. 1000a1000,1001 > Keep track of the last uri redirected to. Also if the redirection was from a POST change the HTTP method to GET. This does not conform with the RFCs, but it is how many browser user agent implementations behave. As we are trying to model them, we must unfortunately mimic their erroneously reaction. See L<http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3> for details on correct behaviour. > 1011a1013,1015 > # Mimic erroneously browser behaviour by changing the method. > $prospective_request->method("GET") if $prospective_request->method eq "POST"; >
Fixed in 0.50, which is now out on the CPAN, or making its way....