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