glassfish
  1. glassfish
  2. GLASSFISH-20957

CDI is consuming application/x-form-url-encoded entity causing empty input stream in servlet

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Works as designed
    • Affects Version/s: 4.0
    • Fix Version/s: None
    • Component/s: cdi
    • Labels:
      None

      Description

      In case if application/x-form-url-encoded request is sent to a simple servlet with enabled CDI (deployed on GF4) the CDI is consuming entity which disables reading the entity in servlet itself.

      Deploy attached application to GF4/GF4.0.1 and make a request (nothing is returned from servlet):

      $ curl -X POST --data "name=test" http://localhost:8080/form-webapp-1.0-SNAPSHOT/
      
      

      if beans.xml is removed from the app the result is correct (the sent entity is returned to the client):

      $ curl -X POST --data "name=test" http://localhost:8080/form-webapp-1.0-SNAPSHOT/
      name=test
      

      See:

        Issue Links

          Activity

          Hide
          johanvos added a comment -

          It seems Weld requests parameters from the Request during initialization of the request. I added a Thread.dumpStack statement in RequestFacade.getParameter. In case no beans.xml is present, there is no stacktrace. In case beans.xml is added, the StandardHostValve.preInvoke will trigger CDI which will call request.getParameter which will consume the bytes. See stacktraces below.

          What is wrong here?
          1) Weld should not call RequestFacade.getParameter()?
          OR
          2) RequestFacade.getParameter() should not consume the bytes?

          at java.lang.Thread.dumpStack(Thread.java:1364)
          at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:441)
          at org.jboss.weld.servlet.ConversationContextActivator.getConversationId(ConversationContextActivator.java:124)
          at org.jboss.weld.servlet.ConversationContextActivator.activateConversationContext(ConversationContextActivator.java:82)
          at org.jboss.weld.servlet.HttpContextLifecycle.requestInitialized(HttpContextLifecycle.java:157)
          at org.jboss.weld.servlet.WeldInitialListener.requestInitialized(WeldInitialListener.java:108)
          at org.apache.catalina.core.StandardContext.fireRequestInitializedEvent(StandardContext.java:5257)
          at org.apache.catalina.core.StandardHostValve.preInvoke(StandardHostValve.java:655)
          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:166)
          at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415)
          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)

          Show
          johanvos added a comment - It seems Weld requests parameters from the Request during initialization of the request. I added a Thread.dumpStack statement in RequestFacade.getParameter. In case no beans.xml is present, there is no stacktrace. In case beans.xml is added, the StandardHostValve.preInvoke will trigger CDI which will call request.getParameter which will consume the bytes. See stacktraces below. What is wrong here? 1) Weld should not call RequestFacade.getParameter()? OR 2) RequestFacade.getParameter() should not consume the bytes? at java.lang.Thread.dumpStack(Thread.java:1364) at org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:441) at org.jboss.weld.servlet.ConversationContextActivator.getConversationId(ConversationContextActivator.java:124) at org.jboss.weld.servlet.ConversationContextActivator.activateConversationContext(ConversationContextActivator.java:82) at org.jboss.weld.servlet.HttpContextLifecycle.requestInitialized(HttpContextLifecycle.java:157) at org.jboss.weld.servlet.WeldInitialListener.requestInitialized(WeldInitialListener.java:108) at org.apache.catalina.core.StandardContext.fireRequestInitializedEvent(StandardContext.java:5257) at org.apache.catalina.core.StandardHostValve.preInvoke(StandardHostValve.java:655) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:166) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:415) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:282)
          Hide
          johanvos added a comment -

          Adding to this, the parameters that are asked by Weld are "cid", "nocid" and "conversationPropagation"

          Show
          johanvos added a comment - Adding to this, the parameters that are asked by Weld are "cid", "nocid" and "conversationPropagation"
          Hide
          johanvos added a comment -
          Show
          johanvos added a comment - more info on this issue: https://issues.jboss.org/browse/CDI-411 and https://issues.jboss.org/browse/WELD-1549
          Hide
          johanvos added a comment -

          When reading the specifications, this might be not an issue. CDI has to call Request.getParameter(), and the Servlet javadoc states that once request.getParameter(String) has been called, the getInputStream() is unreliable:

          "If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then reading the body directly via getInputStream() or getReader() can interfere with the execution of this method."

          So after all, I don't think this is an issue. As a consequence, though, all code that relies on request.getInputStream() and that also uses CDI is by definition broken. That sounds a bit drastic.

          Show
          johanvos added a comment - When reading the specifications, this might be not an issue. CDI has to call Request.getParameter(), and the Servlet javadoc states that once request.getParameter(String) has been called, the getInputStream() is unreliable: "If the parameter data was sent in the request body, such as occurs with an HTTP POST request, then reading the body directly via getInputStream() or getReader() can interfere with the execution of this method." So after all, I don't think this is an issue. As a consequence, though, all code that relies on request.getInputStream() and that also uses CDI is by definition broken. That sounds a bit drastic.
          Hide
          Miroslav Fuksa added a comment -

          This problem must be solved on the specification level.

          Show
          Miroslav Fuksa added a comment - This problem must be solved on the specification level.

            People

            • Assignee:
              jjsnyder83
              Reporter:
              Michal Gajdos
            • Votes:
              1 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: