4 Replies Latest reply on Aug 3, 2009 1:16 PM by tfennelly

    HTTPUnMarshaller and InvocationResponse objects

    tfennelly

      Hi there.

      We encountered something that appears to be a bug when using JBR client to a JBR Server (http).

      In the above scenario, the JBR server returns an InvocationResponse to the JBR client (if the user-agent starts with "JBossRemoting"). Everything works fine if we don't set a Content-Type header in the response metadata (or we set it to a binary type). If it's set to a non-binary type however (e.g. text/xml), we get an error on the client side because the HTTPUnMarshaller only decodes the response stream as an InvocationResponse for non binary content types.

      Could be wrong (of course), but the mechanism seems flawed. If the HTTPMarshaller is going to wrap the response object payload in an InvocationResponse, then is it not effectively changing the content type? In this situation, should it not be reseting the content type to octet-stream (or whatever) and storing the wrapped payload type (e.g. "text/xml") on the InvocationResponse. Then on the client side, the HTTPUnMarshaller will decode the InvocationResponse properly and can reverse the Content-Type on the response metadata it receives before returning the wrapped payload etc etc

        • 1. Re: HTTPUnMarshaller and InvocationResponse objects
          ron_sigal

          Hi Tom,

          HTTPMarshaller and HTTPUnMarshaller include special handling for strings in order to avoid serialization. The problem is that old test for "string" or "not string", which worked prior to JBREM-653 "allow user to set content-type for http responses" is no longer appropriate.

          I'm thinking that anything with a content-type starting with "text/" should be read as a string by HTTPUnMarshaller. That means that an org.jboss.remoting.ServerInvocationHandler should set the content-type to something starting "text/" only if it returns a response of Java type String.

          Does that sound reasonable to you?

          -Ron

          • 2. Re: HTTPUnMarshaller and InvocationResponse objects
            tfennelly

            Hey Ron, sorry for not replying to this.... I got distracted after your email and forgot to come back to it then :)

            Anway... not sure I follow :)

            As I see it, the issue on the client side will not be with "text/*" mime types since it seems to me that the issue is that the "text/*" types are coming back "wrapped" as a binary type in an InvocationResponse and the fact that it's "text/plain" underneath has been lost. I hope that makes sense :)

            So it seems to me like the Server to Client Marshal/Unmarshal process is missing a piece of info and an additional client side step. From memory, I think the http jbrserver-to-jbrclient response process for e.g. "text/plain" is as follows:

            1. [serverapp] return a String ("text/plain") response payload
             2. [jbrserver] wrap "text/plain" response payload in an InvocationResponse (serialized String I think)
             3. [jbrserver] change content-type to "application/something" because it's an InvocationResponse.
             4. [jbrserver] marshal response to client
             5. [jbrclient] unmarshal response from server
             6. [jbrclient] return payload from InvocationResponse - content-type is "application/something"
             7. [clientapp] Use binary response (serialized String I think)???
            


            So I was thinking there was a piece of info missing in the InvocationResponse that tells the JBR Client that the payload is actually a serialized object and the base content type is "text/plain".

            1. [serverapp] return a String ("text/plain") response payload
             2. [jbrserver] wrap "text/plain" response payload in an InvocationResponse
             3. [jbrserver] change content-type to "application/something" because it's an InvocationResponse - store "base-content-type" = "text/plain".
             4. [jbrserver] marshal response to client
             5. [jbrclient] unmarshal response from server
             6. [jbrclient] extract payload from InvocationResponse - it's a serialized object... base-content-type = "text/plain"
             7. [jbrclient] Deserialize payload to String - set response content-type back to "text/plain"
            8. [clientapp] Use String response ("text/plain")
            


            Hope I'm making sense Ron :)

            • 3. Re: HTTPUnMarshaller and InvocationResponse objects
              ron_sigal

              Hi Tom,

              Yeah, sorry for the confusion. I can't reconstruct what I was thinking, but I probably forgot about the fact, even though you mentioned it, that CoyoteInvoker is wrapping the result in an InvocationResponse.

              I think

              1. the content-type returned by the ServerInvoctionHandler should be preserved and sent back to the client, but

              2. HTTPUnMarshaller shouldn't be using the value of content-type.

              Maybe Remoting should send a new metadata value, say 'remoting-type', to be used by HTTPUnmarshaller, which would then remove it from the metadata map before it gets back to the client.

              I've created JBREM-1145 "HTTPUnMarshaller shouldn't use the value of content-type to determine the type of an object".

              Now it makes sense?

              -Ron

              • 4. Re: HTTPUnMarshaller and InvocationResponse objects
                tfennelly

                Yep.. that makes sense to me Ron :)