You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Eoghan Glynn <eo...@progress.com> on 2008/11/14 16:27:55 UTC

why does the SOAP CheckFaultInterceptor run in the POST_PROTOCOL phase?

Folks,

Is there any reason why the SOAP CheckFaultInterceptor runs in the POST_PROTOCOL phase, as opposed to PRE_PROTOCOL?

The net result is handleFault() is never called for a client-side JAX-WS SOAPHandler, as the CheckFaultInterceptor (which is responbile for determining if a fault is present in the incoming message) is assigned to a phase that runs *after* the PRE_PROTOCOL phase in which the JAX-WS handler chain is traversed. So Handler.handleFault() can never be called, as it isn't yet known that the message actually contains a fault.

So before I go fixing this I wanted to check if this apparent mis-ordering was just an oversight, or whether there's method to the madness :)

Cheers,
Eoghan

RE: why does the SOAP CheckFaultInterceptor run in the POST_PROTOCOL phase?

Posted by Eoghan Glynn <eo...@progress.com>.
Hi Dan,

I'm open to correction on the security stuff, but I think we might still be OK with the re-ordering approach even in the presence of whitespace, as the WS-Sec in-interceptor (at least the WSS4J version anyway) also runs in the PRE-PROTOCOL phase.

So as long as the CheckFaultInterceptor runs near the end of this phase (after the security interceptor has already validated the signature or whatever), then it should be OK to advance the XMLStreamReader over any whitespace preceding the first body element. Assuming there's a test that validates the behaviour on whitespace, I guess this could be easily checked.

However, there is one other case where a simple re-ordering would still seem problematic - if the response is not a fault to begin with, but one of the JAX-WS SOAPHandlers throws a ProtocolException and thus changes it to a fault. In that case I guess we'd need to check again for a fault after the handler chain has been traversed. It might be more straight-forward to just rerun the (very simple) CheckFaultInterceptor at at a second point in the call chain, instead of splitting the (relatively complex) JAX-WS interceptor into two parts.

Does that make sense to you?

Cheers,
Eoghan

-----Original Message-----
From: Daniel Kulp [mailto:dkulp@apache.org]
Sent: Fri 14/11/2008 15:26
To: dev@cxf.apache.org
Cc: Eoghan Glynn
Subject: Re: why does the SOAP CheckFaultInterceptor run in the POST_PROTOCOL phase?
 

Actually, I remember why I put it that late.....

The CheckFaultOut stuff HAS to occur after anything related to SAAJ/DOM is 
done.    When it gets there, the XmlStreamReader sits at the first child of 
the soap:body.   However, that might NOT be an element.   It may be 
whitespace.   However, CheckFaultOut has to advance to the first element to 
see it's a fault.  Thus, that whitespace is lost.   That then invalidates any 
signature that may be on the soap body.  You get signature validation issues.   

Since the JAXWS handler interceptor things builds an SAAJ if there isn't 
already one, the CheckFaultOut cannot run before it or the whitespace is 
lost.  

What MIGHT work would be to split the JAXWS handler thing into two parts.   
One that runs real early in the phase chain and if there are handlers, add 
the SAAJInInerceptor and it's second part that does the real work.   That 
second part could then safely assume the SAAJ model is there.   

Dan


On Friday 14 November 2008 11:39:00 am Eoghan Glynn wrote:
> Thanks for the quick response Dan, some comments inline ...
>
> > > Is there any reason why the SOAP CheckFaultInterceptor runs in the
> > > POST_PROTOCOL phase, as opposed to PRE_PROTOCOL?
> >
> > Well, the basic reason is that to check for a fault, it needs to look at
> > the first element in the body.  The headers and envelop and such are
> > handled in the PROTOCOL phase, thus, it needs to be checked afterword.
>
> Sure, but it could do that equally well near the end of PRE_PROTOCOL phase,
> say if its configured to run after the MustUnderstandInterceptor.
>
> Come to think of it though, the ReadHeadersInterceptor runs in the READ
> phase, so we're gauranteed the headers are out of the way by the time
> PRE_PROTOCOL kicks in.
>
> Also, at least in the 2.0.6.x version I'm looking at, once the
> ReadHeaderInterceptors is done, the <SOAP:Envelope> element has already
> been stripped off the XMLStreamReader. So the CheckFaultInterceptor is
> nicely tee'd up to read off the <Fault> element, whether it runs in
> PRE_PROTOCOL or POST_PROTOCOL.
>
> Of course, another option would be to move the JAX-WS handler interceptors
> to the POST_PROTOCOL phase.
>
> > > The net result is handleFault() is never called for a client-side
> > > JAX-WS SOAPHandler, as the CheckFaultInterceptor (which is responbile
> > > for determining if a fault is present in the incoming message) is
> > > assigned to a phase that runs *after* the PRE_PROTOCOL phase in which
> > > the JAX-WS handler chain is traversed. So Handler.handleFault() can
> > > never be called, as it isn't yet known that the message actually
> > > contains a fault.
> >
> > Which MAY be correct.   I'd need to double check the spec and TCK and
> > such. (before committing any change in this area, let me know and I'll
> > run the tck on it).   The handleFault may be for handling faults that are
> > generated as part of processing the normal message.     I'd need to
> > double check on that.
>
> The JAX-WS 2.0/1 specs seems to say little more than:
>
> "9.3.2.2 handleFault
> Called for fault message processing ..."
>
> which seems to imply that handleFault should should be called for a fault
> message on both the client- & server-sides.
>
> Currently in CXF, handleFault is called on a server-side handler for an
> outgoing fault, but handleMessage is called on a client-side handler for
> that same message when inbound. Seems unlikely that this sort of
> inconsistency would actually be intended by the spec. Though stranger
> things have happened, and obviously you were on the spec EG so you'd have
> deeper knowledge of the spec meant to say ... :)
>
> > > So before I go fixing this I wanted to check if this apparent
> > > mis-ordering was just an oversight, or whether there's method to the
> > > madness :)
> >
> > That all said, I've THOUGHT about adding a HttpErrorCodeInterceptor or
> > something that goes very early in the chain to flip it over to the
> > faultInChain if the response code is 500.  That could be done LONG before
> > any processing of anything else is done.   Obviously only useful for HTTP
> > transport though.     The current implementation means that any stream
> > related things only on the faultInChain wouldn't ever get called.  
> > Flipping over based on response code would fix that.
>
> Yeah, that would work ... but as you point out, the restriction HTTP sortta
> makes it a non-runner in the general case.
>
> Cheers,
> Eoghan



-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog


Re: why does the SOAP CheckFaultInterceptor run in the POST_PROTOCOL phase?

Posted by Daniel Kulp <dk...@apache.org>.
Actually, I remember why I put it that late.....

The CheckFaultOut stuff HAS to occur after anything related to SAAJ/DOM is 
done.    When it gets there, the XmlStreamReader sits at the first child of 
the soap:body.   However, that might NOT be an element.   It may be 
whitespace.   However, CheckFaultOut has to advance to the first element to 
see it's a fault.  Thus, that whitespace is lost.   That then invalidates any 
signature that may be on the soap body.  You get signature validation issues.   

Since the JAXWS handler interceptor things builds an SAAJ if there isn't 
already one, the CheckFaultOut cannot run before it or the whitespace is 
lost.  

What MIGHT work would be to split the JAXWS handler thing into two parts.   
One that runs real early in the phase chain and if there are handlers, add 
the SAAJInInerceptor and it's second part that does the real work.   That 
second part could then safely assume the SAAJ model is there.   

Dan


On Friday 14 November 2008 11:39:00 am Eoghan Glynn wrote:
> Thanks for the quick response Dan, some comments inline ...
>
> > > Is there any reason why the SOAP CheckFaultInterceptor runs in the
> > > POST_PROTOCOL phase, as opposed to PRE_PROTOCOL?
> >
> > Well, the basic reason is that to check for a fault, it needs to look at
> > the first element in the body.  The headers and envelop and such are
> > handled in the PROTOCOL phase, thus, it needs to be checked afterword.
>
> Sure, but it could do that equally well near the end of PRE_PROTOCOL phase,
> say if its configured to run after the MustUnderstandInterceptor.
>
> Come to think of it though, the ReadHeadersInterceptor runs in the READ
> phase, so we're gauranteed the headers are out of the way by the time
> PRE_PROTOCOL kicks in.
>
> Also, at least in the 2.0.6.x version I'm looking at, once the
> ReadHeaderInterceptors is done, the <SOAP:Envelope> element has already
> been stripped off the XMLStreamReader. So the CheckFaultInterceptor is
> nicely tee'd up to read off the <Fault> element, whether it runs in
> PRE_PROTOCOL or POST_PROTOCOL.
>
> Of course, another option would be to move the JAX-WS handler interceptors
> to the POST_PROTOCOL phase.
>
> > > The net result is handleFault() is never called for a client-side
> > > JAX-WS SOAPHandler, as the CheckFaultInterceptor (which is responbile
> > > for determining if a fault is present in the incoming message) is
> > > assigned to a phase that runs *after* the PRE_PROTOCOL phase in which
> > > the JAX-WS handler chain is traversed. So Handler.handleFault() can
> > > never be called, as it isn't yet known that the message actually
> > > contains a fault.
> >
> > Which MAY be correct.   I'd need to double check the spec and TCK and
> > such. (before committing any change in this area, let me know and I'll
> > run the tck on it).   The handleFault may be for handling faults that are
> > generated as part of processing the normal message.     I'd need to
> > double check on that.
>
> The JAX-WS 2.0/1 specs seems to say little more than:
>
> "9.3.2.2 handleFault
> Called for fault message processing ..."
>
> which seems to imply that handleFault should should be called for a fault
> message on both the client- & server-sides.
>
> Currently in CXF, handleFault is called on a server-side handler for an
> outgoing fault, but handleMessage is called on a client-side handler for
> that same message when inbound. Seems unlikely that this sort of
> inconsistency would actually be intended by the spec. Though stranger
> things have happened, and obviously you were on the spec EG so you'd have
> deeper knowledge of the spec meant to say ... :)
>
> > > So before I go fixing this I wanted to check if this apparent
> > > mis-ordering was just an oversight, or whether there's method to the
> > > madness :)
> >
> > That all said, I've THOUGHT about adding a HttpErrorCodeInterceptor or
> > something that goes very early in the chain to flip it over to the
> > faultInChain if the response code is 500.  That could be done LONG before
> > any processing of anything else is done.   Obviously only useful for HTTP
> > transport though.     The current implementation means that any stream
> > related things only on the faultInChain wouldn't ever get called.  
> > Flipping over based on response code would fix that.
>
> Yeah, that would work ... but as you point out, the restriction HTTP sortta
> makes it a non-runner in the general case.
>
> Cheers,
> Eoghan



-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

RE: why does the SOAP CheckFaultInterceptor run in the POST_PROTOCOL phase?

Posted by Eoghan Glynn <eo...@progress.com>.
Thanks for the quick response Dan, some comments inline ...


> > Is there any reason why the SOAP CheckFaultInterceptor runs in the
> > POST_PROTOCOL phase, as opposed to PRE_PROTOCOL?
> 
> Well, the basic reason is that to check for a fault, it needs to look at the 
> first element in the body.  The headers and envelop and such are handled in 
> the PROTOCOL phase, thus, it needs to be checked afterword.


Sure, but it could do that equally well near the end of PRE_PROTOCOL phase, say if its configured to run after the MustUnderstandInterceptor.

Come to think of it though, the ReadHeadersInterceptor runs in the READ phase, so we're gauranteed the headers are out of the way by the time PRE_PROTOCOL kicks in.

Also, at least in the 2.0.6.x version I'm looking at, once the ReadHeaderInterceptors is done, the <SOAP:Envelope> element has already been stripped off the XMLStreamReader. So the CheckFaultInterceptor is nicely tee'd up to read off the <Fault> element, whether it runs in PRE_PROTOCOL or POST_PROTOCOL.

Of course, another option would be to move the JAX-WS handler interceptors to the POST_PROTOCOL phase.

 
> > The net result is handleFault() is never called for a client-side JAX-WS
> > SOAPHandler, as the CheckFaultInterceptor (which is responbile for
> > determining if a fault is present in the incoming message) is assigned to a
> > phase that runs *after* the PRE_PROTOCOL phase in which the JAX-WS handler
> > chain is traversed. So Handler.handleFault() can never be called, as it
> > isn't yet known that the message actually contains a fault.
> 
> Which MAY be correct.   I'd need to double check the spec and TCK and such.  
> (before committing any change in this area, let me know and I'll run the tck 
> on it).   The handleFault may be for handling faults that are generated as 
> part of processing the normal message.     I'd need to double check on that.


The JAX-WS 2.0/1 specs seems to say little more than:

"9.3.2.2 handleFault
Called for fault message processing ..."

which seems to imply that handleFault should should be called for a fault message on both the client- & server-sides. 

Currently in CXF, handleFault is called on a server-side handler for an outgoing fault, but handleMessage is called on a client-side handler for that same message when inbound. Seems unlikely that this sort of inconsistency would actually be intended by the spec. Though stranger things have happened, and obviously you were on the spec EG so you'd have deeper knowledge of the spec meant to say ... :)

 
> > So before I go fixing this I wanted to check if this apparent mis-ordering
> > was just an oversight, or whether there's method to the madness :)
> 
> That all said, I've THOUGHT about adding a HttpErrorCodeInterceptor or 
> something that goes very early in the chain to flip it over to the 
> faultInChain if the response code is 500.  That could be done LONG before any 
> processing of anything else is done.   Obviously only useful for HTTP 
> transport though.     The current implementation means that any stream 
> related things only on the faultInChain wouldn't ever get called.   Flipping 
> over based on response code would fix that.


Yeah, that would work ... but as you point out, the restriction HTTP sortta makes it a non-runner in the general case.

Cheers,
Eoghan

Re: why does the SOAP CheckFaultInterceptor run in the POST_PROTOCOL phase?

Posted by Daniel Kulp <dk...@apache.org>.
Actually, thinking about it some more....

Another fix MAY be to just update the JAXWSHandlerInvoker to look at the 
SOAPMessage (since it had to part the thing into the SAAJ model anyway) and 
have it call handleFault instead of handleMessage if the body contains a 
fault.

Dan



On Friday 14 November 2008 10:39:50 am Daniel Kulp wrote:
> On Friday 14 November 2008 10:27:55 am Eoghan Glynn wrote:
> > Folks,
> >
> > Is there any reason why the SOAP CheckFaultInterceptor runs in the
> > POST_PROTOCOL phase, as opposed to PRE_PROTOCOL?
>
> Well, the basic reason is that to check for a fault, it needs to look at
> the first element in the body.  The headers and envelop and such are
> handled in the PROTOCOL phase, thus, it needs to be checked afterword.
>
> > The net result is handleFault() is never called for a client-side JAX-WS
> > SOAPHandler, as the CheckFaultInterceptor (which is responbile for
> > determining if a fault is present in the incoming message) is assigned to
> > a phase that runs *after* the PRE_PROTOCOL phase in which the JAX-WS
> > handler chain is traversed. So Handler.handleFault() can never be called,
> > as it isn't yet known that the message actually contains a fault.
>
> Which MAY be correct.   I'd need to double check the spec and TCK and such.
> (before committing any change in this area, let me know and I'll run the
> tck on it).   The handleFault may be for handling faults that are generated
> as part of processing the normal message.     I'd need to double check on
> that.
>
> > So before I go fixing this I wanted to check if this apparent
> > mis-ordering was just an oversight, or whether there's method to the
> > madness :)
>
> That all said, I've THOUGHT about adding a HttpErrorCodeInterceptor or
> something that goes very early in the chain to flip it over to the
> faultInChain if the response code is 500.  That could be done LONG before
> any processing of anything else is done.   Obviously only useful for HTTP
> transport though.     The current implementation means that any stream
> related things only on the faultInChain wouldn't ever get called.  
> Flipping over based on response code would fix that.



-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog

Re: why does the SOAP CheckFaultInterceptor run in the POST_PROTOCOL phase?

Posted by Daniel Kulp <dk...@apache.org>.
On Friday 14 November 2008 10:27:55 am Eoghan Glynn wrote:
> Folks,
>
> Is there any reason why the SOAP CheckFaultInterceptor runs in the
> POST_PROTOCOL phase, as opposed to PRE_PROTOCOL?

Well, the basic reason is that to check for a fault, it needs to look at the 
first element in the body.  The headers and envelop and such are handled in 
the PROTOCOL phase, thus, it needs to be checked afterword.


> The net result is handleFault() is never called for a client-side JAX-WS
> SOAPHandler, as the CheckFaultInterceptor (which is responbile for
> determining if a fault is present in the incoming message) is assigned to a
> phase that runs *after* the PRE_PROTOCOL phase in which the JAX-WS handler
> chain is traversed. So Handler.handleFault() can never be called, as it
> isn't yet known that the message actually contains a fault.

Which MAY be correct.   I'd need to double check the spec and TCK and such.  
(before committing any change in this area, let me know and I'll run the tck 
on it).   The handleFault may be for handling faults that are generated as 
part of processing the normal message.     I'd need to double check on that.

> So before I go fixing this I wanted to check if this apparent mis-ordering
> was just an oversight, or whether there's method to the madness :)

That all said, I've THOUGHT about adding a HttpErrorCodeInterceptor or 
something that goes very early in the chain to flip it over to the 
faultInChain if the response code is 500.  That could be done LONG before any 
processing of anything else is done.   Obviously only useful for HTTP 
transport though.     The current implementation means that any stream 
related things only on the faultInChain wouldn't ever get called.   Flipping 
over based on response code would fix that.

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog