14 Replies Latest reply on Nov 28, 2016 7:08 AM by jaikiran pai

    HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)

    fibonacci.prime Newbie

      Hi all,

       

      We have an application running on WildFly 10.1.0-final, exposing a set of secured REST interfaces distributed across a couple of webapps deployed on a single WildFly instance. SSO is enabled for all webapps running on localhost.

       

      We have a problem with, what seems to be an invalid HTTP response code, for DELETE and PUT requests, made after the session has timed out. As soon as session expires, any DELETE and PUT requests will fail with "JBWEB004248: JSPs only permit GET POST or HEAD". GET and POST requests made after the session has timed out will properly return HTTP 401. Note: DELETE and PUT requests are behaving just fine while session is valid, meaning there is no error in the request URL or something similar.

       

      Any ideas if this is a bug?

        • 1. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
          jaikiran pai Master

          Is it only after session timeouts or do you see the same behaviour when no session has been created in first place and you issue a DELETE or PUT to those URLs?

          • 2. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
            fibonacci.prime Newbie

            It happens also when no session has been created.

            For GET and POST requests made without session being created, I am getting HTTP 401 and a login form, as expected. However, for DELETE and PUT requests I'm getting HTTP 405 with "JBWEB004248: JSPs only permit GET POST or HEAD".

            • 3. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
              fibonacci.prime Newbie

              I just tested this with another application running on WildFly 10.0.0-final, and got the same outcome. Could it be that this slipped through unnoticed on both versions?

              • 4. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                jaikiran pai Master

                We have an application running on WildFly 10.1.0-final,

                 

                We have a problem with, what seems to be an invalid HTTP response code, for DELETE and PUT requests, made after the session has timed out. As soon as session expires, any DELETE and PUT requests will fail with "JBWEB004248: JSPs only permit GET POST or HEAD".

                I had a quick look at the WildFly code and couldn't find any reference to that log message or the log message code. I went back even to 8.x versions. Are you sure you are using WildFly 10.1.0.Final? Are you sure it's undertow subsystem which is managing the web container? Do you have custom changes in your standalone/domain configurations?

                • 5. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                  Tomaz Cerar Master

                  jaikiran pai wrote:

                   

                  We have an application running on WildFly 10.1.0-final,

                   

                  We have a problem with, what seems to be an invalid HTTP response code, for DELETE and PUT requests, made after the session has timed out. As soon as session expires, any DELETE and PUT requests will fail with "JBWEB004248: JSPs only permit GET POST or HEAD".

                  I had a quick look at the WildFly code and couldn't find any reference to that log message or the log message code. I went back even to 8.x versions. Are you sure you are using WildFly 10.1.0.Final? Are you sure it's undertow subsystem which is managing the web container? Do you have custom changes in your standalone/domain configurations?

                  Hmm, it is actually possible

                  This message comes from jastow jastow/JasperMessages.java at master · undertow-io/jastow · GitHub

                  which we should probably fix to use non JBWEB prefix.

                   

                  jamezp wdyt, I think having different prefix would make more sense.

                   

                  But well this is unrelated to this problem.

                  • 6. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                    jaikiran pai Master

                    Tomaz Cerar wrote:

                     

                    jaikiran pai wrote:

                     

                    We have an application running on WildFly 10.1.0-final,

                     

                    We have a problem with, what seems to be an invalid HTTP response code, for DELETE and PUT requests, made after the session has timed out. As soon as session expires, any DELETE and PUT requests will fail with "JBWEB004248: JSPs only permit GET POST or HEAD".

                    I had a quick look at the WildFly code and couldn't find any reference to that log message or the log message code. I went back even to 8.x versions. Are you sure you are using WildFly 10.1.0.Final? Are you sure it's undertow subsystem which is managing the web container? Do you have custom changes in your standalone/domain configurations?

                    Hmm, it is actually possible

                    This message comes from jastow jastow/JasperMessages.java at master · undertow-io/jastow · GitHub

                    Thanks That explains it - I was looking just under the WildFly repos.

                    • 7. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                      fibonacci.prime Newbie

                      jaikiran pai wrote:

                       

                      We have an application running on WildFly 10.1.0-final,

                       

                      We have a problem with, what seems to be an invalid HTTP response code, for DELETE and PUT requests, made after the session has timed out. As soon as session expires, any DELETE and PUT requests will fail with "JBWEB004248: JSPs only permit GET POST or HEAD".

                      I had a quick look at the WildFly code and couldn't find any reference to that log message or the log message code. I went back even to 8.x versions. Are you sure you are using WildFly 10.1.0.Final? Are you sure it's undertow subsystem which is managing the web container? Do you have custom changes in your standalone/domain configurations?

                      Hi Jaikarian! Thanks for replying.

                       

                      I hope that Tomaz's inputs helped to locate the code.

                      I am sure we are using WildFly 10.1.0-final. Also, as described in my previous comment, I got identical behavior on version 10.0.0-final, with another application. On both applications we are using either Apache or Nginx reverse proxy before the WildFly/Undertow, but the web container is managed by Undertow. I think it's clear from the error message (JBWEB004248) that it was produced by Undertow rather than Apache/Nginx.

                       

                      EDIT: I also rerun the test without the reverse proxy Apache configuration, and was getting the same outcome.

                       

                      Regarding your question about customizing standalone.xml, we did made quite some changes (datasource definition, security realm definition, etc.), but the only one related to undertow system is configuration required to serve our sound files compressed.

                       

                      This is our Undertow subsystem configuration:

                       

                      <subsystem xmlns="urn:jboss:domain:undertow:3.1">

                                  <buffer-cache name="default"/>

                                  <server name="default-server">

                                      <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>

                                      <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>

                                      <host name="default-host" alias="localhost">

                                          <location name="/" handler="welcome-content"/>

                                          <location name="/sounds" handler="sounds"/>

                                          <filter-ref name="server-header"/>

                                          <filter-ref name="x-powered-by-header"/>

                                          <filter-ref name="gzipFilter" predicate="regex(pattern='(?:application/javascript|application/json|application/svg|text/css|text/html)(;.*)?', value=%{o,Content-Type}, full-match=false)"/>

                                          <filter-ref name="noCacheFilter" predicate="path-suffix['.html']"/>

                                          <single-sign-on/>

                                      </host>

                                  </server>

                                  <servlet-container name="default">

                                      <jsp-config/>

                                      <websockets/>

                                  </servlet-container>

                                  <handlers>

                                      <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>

                                      <file name="sounds" path="${jboss.home.dir}/mnc/sounds"/>

                                  </handlers>

                                  <filters>

                                      <response-header name="server-header" header-name="Server" header-value="WildFly/10"/>

                                      <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>

                                      <response-header name="noCacheFilter" header-name="Cache-Control" header-value="no-store"/>

                                      <gzip name="gzipFilter"/>

                                  </filters>

                              </subsystem>

                      • 8. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                        jaikiran pai Master

                        I just had a look at the JspServlet which is responsible for serving the content jastow/JspServlet.java at 2.0.1.Final · undertow-io/jastow · GitHub . Clearly, it's been implemented so that the DELETE, PUT HTTP methods aren't served and instead the error is returned. So that explains the error you are seeing.

                         

                        However, you also note that:

                         

                        fibonacci.prime wrote:

                         

                        Note: DELETE and PUT requests are behaving just fine while session is valid, meaning there is no error in the request URL or something similar.

                         

                        This part is odd and looks wrong to me. Can you get the output of :

                         

                        curl -i -X DELETE --cookie "JSESSIONID=TheCookieThatYouGetForAValidSession" <that-jsp-url-of-yours>

                         

                        Essentially, what I want to see is what response code and content gets returned (and by whom) when the session is alive and you issue a DELETE or PUT against that JSP. You can skip curl and use other web/browser tools whichever you are comfortable with to get that data.

                        • 9. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                          fibonacci.prime Newbie

                          Here's the output of successful DELETE request when session is active:

                           

                          HTTP status code 204 (Note: the response code is specified in the application, so this could be anything business logic mandates)

                           

                          Response headers:

                          HTTP/1.1 204 No Content

                          Date: Wed, 23 Nov 2016 16:22:07 GMT

                          Server: WildFly/10

                          Expires: 0

                          Cache-Control: no-cache, no-store, must-revalidate

                          X-Powered-By: Undertow/1

                          Pragma: no-cache

                          Content-Length: 0

                          Connection: close

                          Content-Type: text/plain; charset=UTF-8

                           

                          Let me know if this is OK, or if you need any other info.

                          • 10. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                            James Perkins Master

                            Having a different prefix is fine. I'd encourage each project to use their own prefix for reasons like this. It's possible they were just copied over from JBossWeb which is why they have prefix. Likely for compatibility reasons so we'd need to consider that too.

                             

                            --

                            James R. Perkins

                            • 11. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                              jaikiran pai Master

                              fibonacci.prime wrote:

                               

                              Here's the output of successful DELETE request when session is active:

                               

                              HTTP status code 204 (Note: the response code is specified in the application, so this could be anything business logic mandates)

                               

                              Response headers:

                              HTTP/1.1 204 No Content

                              Date: Wed, 23 Nov 2016 16:22:07 GMT

                              Server: WildFly/10

                              Expires: 0

                              Cache-Control: no-cache, no-store, must-revalidate

                              X-Powered-By: Undertow/1

                              Pragma: no-cache

                              Content-Length: 0

                              Connection: close

                              Content-Type: text/plain; charset=UTF-8

                               

                              Let me know if this is OK, or if you need any other info.

                               

                              What exact URL are you issuing that request to and what client?

                               

                              I gave this a quick test locally by having a test.war with a check-session.jsp and a index.jsp. The check-session.jsp just print the session id:

                              <%
                                  final HttpSession s = request.getSession();
                                  out.println(s.getId());
                              %>
                              

                               

                              and index.jsp is just prints Hello World text.

                               

                              I then used curl to first check the session id (if no session exists, a new one gets created) by issuing a GET request to the check-session.jsp:

                               

                               

                               bin $ curl -i -X GET http://localhost:8080/test/check-session.jspHTTP/1.1 200 OK
                              Connection: keep-alive
                              X-Powered-By: Undertow/1
                              X-Powered-By: JSP/2.3
                              Set-Cookie: JSESSIONID=T4KWXKdlVCx9IkV5F_QtZxGFsgVJl3hRFAzp0DJQ.localhost; path=/test
                              Server: WildFly/10
                              Content-Type: text/html;charset=ISO-8859-1
                              Content-Length: 42
                              Date: Thu, 24 Nov 2016 05:33:06 GMT
                              
                              T4KWXKdlVCx9IkV5F_QtZxGFsgVJl3hRFAzp0DJQ
                              

                               

                               

                              and then issued a DELETE to index.jsp both with and without that JSESSIONID cookie:

                               

                               bin $ curl -i -X DELETE http://localhost:8080/test/index.jsp
                              HTTP/1.1 405 Method Not Allowed
                              Connection: keep-alive
                              X-Powered-By: Undertow/1
                              Server: WildFly/10
                              Content-Type: text/html;charset=UTF-8
                              Content-Length: 105
                              Date: Thu, 24 Nov 2016 05:37:30 GMT
                              
                              <html><head><title>Error</title></head><body>JBWEB004248: JSPs only permit GET POST or HEAD</body></html>
                              

                               

                               

                              curl -i -X DELETE --cookie "JSESSIONID=T4KWXKdlVCx9IkV5F_QtZxGFsgVJl3hRFAzp0DJQ.localhost; path=/test" http://localhost:8080/test/index.jsp
                              HTTP/1.1 405 Method Not Allowed
                              Connection: keep-alive
                              X-Powered-By: Undertow/1
                              Server: WildFly/10
                              Content-Type: text/html;charset=UTF-8
                              Content-Length: 105
                              Date: Thu, 24 Nov 2016 05:38:45 GMT
                              
                              <html><head><title>Error</title></head><body>JBWEB004248: JSPs only permit GET POST or HEAD</body></html>
                              

                               

                               

                              As you can see, without and with the session cookie set (i.e. with or without the session) it returns a 405 as expected.

                               

                              Looking at the output you pasted, the only thing I can guess is perhaps that URL isn't being mapped to a JSP (servlet)? Furthermore the response headers in your case seem to suggest that it wasn't handled as a JSP (missing X-Powered-By: JSP/2.3 and also the header which says the Connection was closed).

                               

                              Is it possible to attach a simple application like the one I just created to demonstrate this?

                              • 12. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                                jaikiran pai Master

                                On a related note, looking at the JspServlet code again in the jastow repo, specifically this if block jastow/JspServlet.java at master · undertow-io/jastow · GitHub  I suspect it's missing a return statement in that if block. Without the return statement, it ends up setting the error code and message but then goes on to compile and even try serving the JSP, which I think isn't probably right. Maybe ctomc or swd847 can confirm.

                                • 13. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                                  fibonacci.prime Newbie

                                  jaikiran pai wrote:

                                   

                                   

                                   

                                  As you can see, without and with the session cookie set (i.e. with or without the session) it returns a 405 as expected.

                                   

                                  Looking at the output you pasted, the only thing I can guess is perhaps that URL isn't being mapped to a JSP (servlet)? Furthermore the response headers in your case seem to suggest that it wasn't handled as a JSP (missing X-Powered-By: JSP/2.3 and also the header which says the Connection was closed).

                                   

                                  Is it possible to attach a simple application like the one I just created to demonstrate this?

                                  Hi Jaikiran,

                                   

                                  In our case its a JAX-RS endpoint rather than JSP, this might explain the lack of "X-Powered-By: JSP/2.3" header.

                                  URL is definitely mapped OK, because I am getting 405 only when making a request without a valid session ID - the identical request, to the same URL, containing a valid session ID in the request header, works just fine.

                                  You can demonstrate the same behavior in the test you created by adding a PUT or DELETE method to your JSP, and trying to invoke it without JSESSIONID cookie. In that case I expect you will receive HTTP 405, even though PUT/DELETE method does exist in your JSP.

                                   

                                  If that's not the case. let me know and I will attach a sample app to demonstrate the behavior we are getting.

                                  • 14. Re: HTTP 405 instad of 401 for PUT and DELETE requests, if session expired (bug?)
                                    jaikiran pai Master

                                    fibonacci.prime wrote:

                                     

                                     

                                    If that's not the case. let me know and I will attach a sample app to demonstrate the behavior we are getting.

                                     

                                    A reproducer would help