You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Rich Giuli <ri...@sri.com> on 2006/05/16 19:05:11 UTC
GET redirect from a POST
Hi all,
I am using the latest stable version of Tomcat Embedded. I have a
question regarding how redirect works for a servlet.
My servlet mapping name is "RexaRetrieval". The basic problem I was
having is that when I send a POST request, the HttpServletRequest always
says it is a GET.
If the URL I put in is:
"http://localhost:8081/RexaRetrieval"
This causes a redirect to a GET request.
If the URL is:
"http://localhost:8081/RexaRetrieval/"
This works. The only difference is the trailing '/' character.
Resin does not have this problem. When I deploy the same war, both POST
requests work.
The relevant source code is in org.apache.tomcat.util.http.mapper.Mapper
line 641:
1 boolean noServletPath = false;
2
3 int length = context.name.length();
4 if (length != (pathEnd - pathOffset)) {
5 servletPath = pathOffset + length;
6 } else {
7 noServletPath = true;
8 path.append('/');
9 pathOffset = path.getOffset();
10 pathEnd = path.getEnd();
11 servletPath = pathOffset+length;
12 }
Note the !=. This means if a trailing forward slash is missing,
"noServletPath" is true.
The in Mapper line 688:
1 if(mappingData.wrapper == null && noServletPath) {
2 // The path is empty, redirect to "/"
3 mappingData.redirectPath.setChars
4 (path.getBuffer(), pathOffset, pathEnd);
5 path.setEnd(pathEnd - 1);
6 return;
7 }
Another related question: how is this redirect suposed to work? The
original method was POST. Does it always redirect to GET when there is a
servlet path? What if I were to post to a URL like
"http://localhost:8081/RexaRetrieval/foo". I am guessing the correct
action here would be that this redirects to a GET because posting to
such a URL doesn't make sense.
Thanks,
Rich
Re: GET redirect from a POST
Posted by Rich Giuli <ri...@sri.com>.
One final thing in case anyone else is interested... it looks like Java
does the wrong thing and converts POST to GET on a redirect by default.
However, you can set the system property "http.strictPostRedirect" in
Java and then this will use POST for a redirect.
Rich
Rich Giuli wrote:
> Hi Bill,
>
> Thanks! I can see why this shouldn't be changed because it will break
> a lot of apps.
>
> I am using a Java URL, so it appears that Java isn't redirecting with
> the same method! I tested from Firefox and it redirects correctly.
> This isn't an issue for me anymore because I actually do not want the
> redirect, but happened to stumble across the fact that Tomcat and
> other servlet containers (ex: Resin) behave differently in this regard.
>
> Thanks,
> Rich
>
> Bill Barker wrote:
>
>> It's a well-known bug with most browsers. RFC 2616 actually states
>> that the browser should respond to a 302 redirect with the same
>> method as the original request, but most browser implementations
>> ignore this. Complain to the browser vendor ;-).
>>
>> You don't say what your servlet-mapping is. If it is '/', then, yes
>> you are going to see this. If it is '/*', then Tomcat should pass it
>> to your Servlet.
>>
>> Your research into this problem is admirable, but it has been
>> discussed at great length on dev@tomcat, so don't waste your time
>> posting to BZ: It will be immediately closed as WONTFIX, since doing
>> what you want would break very many more apps.
>> "Rich Giuli" <ri...@sri.com> wrote in message
>> news:446A0647.7000205@sri.com...
>> Hi all,
>>
>> I am using the latest stable version of Tomcat Embedded. I have a
>> question regarding how redirect works for a servlet.
>>
>> My servlet mapping name is "RexaRetrieval". The basic problem I was
>> having is that when I send a POST request, the HttpServletRequest
>> always says it is a GET.
>> If the URL I put in is: "http://localhost:8081/RexaRetrieval"
>> This causes a redirect to a GET request.
>> If the URL is: "http://localhost:8081/RexaRetrieval/" This
>> works. The only difference is the trailing '/' character.
>> Resin does not have this problem. When I deploy the same war, both
>> POST requests work.
>>
>> The relevant source code is in
>> org.apache.tomcat.util.http.mapper.Mapper line 641:
>>
>> 1 boolean noServletPath = false;
>> 2 3 int length = context.name.length();
>> 4 if (length != (pathEnd - pathOffset)) {
>> 5 servletPath = pathOffset + length;
>> 6 } else {
>> 7 noServletPath = true;
>> 8 path.append('/');
>> 9 pathOffset = path.getOffset();
>> 10 pathEnd = path.getEnd();
>> 11 servletPath = pathOffset+length;
>> 12 }
>> Note the !=. This means if a trailing forward slash is missing,
>> "noServletPath" is true.
>>
>> The in Mapper line 688:
>>
>> 1 if(mappingData.wrapper == null && noServletPath) {
>> 2 // The path is empty, redirect to "/"
>> 3 mappingData.redirectPath.setChars
>> 4 (path.getBuffer(), pathOffset, pathEnd);
>> 5 path.setEnd(pathEnd - 1);
>> 6 return;
>> 7 }
>> Another related question: how is this redirect suposed to work? The
>> original method was POST. Does it always redirect to GET when there
>> is a servlet path? What if I were to post to a URL like
>> "http://localhost:8081/RexaRetrieval/foo". I am guessing the correct
>> action here would be that this redirects to a GET because posting to
>> such a URL doesn't make sense.
>>
>> Thanks,
>> Rich
>>
>>
>>
>
Re: GET redirect from a POST
Posted by Rich Giuli <ri...@sri.com>.
Hi Bill,
Thanks! I can see why this shouldn't be changed because it will break a
lot of apps.
I am using a Java URL, so it appears that Java isn't redirecting with
the same method! I tested from Firefox and it redirects correctly. This
isn't an issue for me anymore because I actually do not want the
redirect, but happened to stumble across the fact that Tomcat and other
servlet containers (ex: Resin) behave differently in this regard.
Thanks,
Rich
Bill Barker wrote:
>It's a well-known bug with most browsers. RFC 2616 actually states that the browser should respond to a 302 redirect with the same method as the original request, but most browser implementations ignore this. Complain to the browser vendor ;-).
>
>You don't say what your servlet-mapping is. If it is '/', then, yes you are going to see this. If it is '/*', then Tomcat should pass it to your Servlet.
>
>Your research into this problem is admirable, but it has been discussed at great length on dev@tomcat, so don't waste your time posting to BZ: It will be immediately closed as WONTFIX, since doing what you want would break very many more apps.
> "Rich Giuli" <ri...@sri.com> wrote in message news:446A0647.7000205@sri.com...
> Hi all,
>
> I am using the latest stable version of Tomcat Embedded. I have a question regarding how redirect works for a servlet.
>
> My servlet mapping name is "RexaRetrieval". The basic problem I was having is that when I send a POST request, the HttpServletRequest always says it is a GET.
>
> If the URL I put in is:
> "http://localhost:8081/RexaRetrieval"
> This causes a redirect to a GET request.
>
> If the URL is:
> "http://localhost:8081/RexaRetrieval/"
> This works. The only difference is the trailing '/' character.
>
> Resin does not have this problem. When I deploy the same war, both POST requests work.
>
> The relevant source code is in org.apache.tomcat.util.http.mapper.Mapper line 641:
>
> 1 boolean noServletPath = false;
> 2
> 3 int length = context.name.length();
> 4 if (length != (pathEnd - pathOffset)) {
> 5 servletPath = pathOffset + length;
> 6 } else {
> 7 noServletPath = true;
> 8 path.append('/');
> 9 pathOffset = path.getOffset();
> 10 pathEnd = path.getEnd();
> 11 servletPath = pathOffset+length;
> 12 }
> Note the !=. This means if a trailing forward slash is missing, "noServletPath" is true.
>
> The in Mapper line 688:
>
> 1 if(mappingData.wrapper == null && noServletPath) {
> 2 // The path is empty, redirect to "/"
> 3 mappingData.redirectPath.setChars
> 4 (path.getBuffer(), pathOffset, pathEnd);
> 5 path.setEnd(pathEnd - 1);
> 6 return;
> 7 }
> Another related question: how is this redirect suposed to work? The original method was POST. Does it always redirect to GET when there is a servlet path? What if I were to post to a URL like "http://localhost:8081/RexaRetrieval/foo". I am guessing the correct action here would be that this redirects to a GET because posting to such a URL doesn't make sense.
>
> Thanks,
> Rich
>
>
>
Re: GET redirect from a POST
Posted by Bill Barker <wb...@wilshire.com>.
It's a well-known bug with most browsers. RFC 2616 actually states that the browser should respond to a 302 redirect with the same method as the original request, but most browser implementations ignore this. Complain to the browser vendor ;-).
You don't say what your servlet-mapping is. If it is '/', then, yes you are going to see this. If it is '/*', then Tomcat should pass it to your Servlet.
Your research into this problem is admirable, but it has been discussed at great length on dev@tomcat, so don't waste your time posting to BZ: It will be immediately closed as WONTFIX, since doing what you want would break very many more apps.
"Rich Giuli" <ri...@sri.com> wrote in message news:446A0647.7000205@sri.com...
Hi all,
I am using the latest stable version of Tomcat Embedded. I have a question regarding how redirect works for a servlet.
My servlet mapping name is "RexaRetrieval". The basic problem I was having is that when I send a POST request, the HttpServletRequest always says it is a GET.
If the URL I put in is:
"http://localhost:8081/RexaRetrieval"
This causes a redirect to a GET request.
If the URL is:
"http://localhost:8081/RexaRetrieval/"
This works. The only difference is the trailing '/' character.
Resin does not have this problem. When I deploy the same war, both POST requests work.
The relevant source code is in org.apache.tomcat.util.http.mapper.Mapper line 641:
1 boolean noServletPath = false;
2
3 int length = context.name.length();
4 if (length != (pathEnd - pathOffset)) {
5 servletPath = pathOffset + length;
6 } else {
7 noServletPath = true;
8 path.append('/');
9 pathOffset = path.getOffset();
10 pathEnd = path.getEnd();
11 servletPath = pathOffset+length;
12 }
Note the !=. This means if a trailing forward slash is missing, "noServletPath" is true.
The in Mapper line 688:
1 if(mappingData.wrapper == null && noServletPath) {
2 // The path is empty, redirect to "/"
3 mappingData.redirectPath.setChars
4 (path.getBuffer(), pathOffset, pathEnd);
5 path.setEnd(pathEnd - 1);
6 return;
7 }
Another related question: how is this redirect suposed to work? The original method was POST. Does it always redirect to GET when there is a servlet path? What if I were to post to a URL like "http://localhost:8081/RexaRetrieval/foo". I am guessing the correct action here would be that this redirects to a GET because posting to such a URL doesn't make sense.
Thanks,
Rich