cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Glynn, Eoghan" <eoghan.gl...@iona.com>
Subject RE: Identification of Partial Responses
Date Fri, 12 Jan 2007 10:12:54 GMT
 

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 11 January 2007 17:30
> To: cxf-dev@incubator.apache.org
> Subject: Re: Identification of Partial Responses
> 
> On 1/11/07, Glynn, Eoghan <eoghan.glynn@iona.com> wrote:
> >
> >
> > > 1. Remove isPartialResposne from HTTPConduit - this logic isn't 
> > > right as it depends on a certain HTTP response code. I think the 
> > > best way to test to see if we have a response message is to just 
> > > check and see if the contentType is null.
> > > If it isn't, there is a message. If it is null, then there is no 
> > > message.
> >
> > Well, null content-type or zero content-length, not sure 
> which is most 
> > general and reliable indicator.
> >
> > Currently the logic is reponseCode == 202 && contentLenght 
> != 0, so we 
> > could simplify this to contentLenght != 0, or check for 
> null-ness of 
> > the content-type instead as you suggest.
> 
> 
> Content-Length will often times not be set though as many 
> people need to do a chunked responses.

Well I guess it would be legal to chunk a zero-length response, if a bit
non-sensical.

And I think there's at least one more way of the server-side indicating
a zero-length response ... by setting the Connection:close header, and
then closing down the write side of its end of the connection without
writing an entity body.

So to be *absolutely* certain there is no entity-body data on the
back-channel, we'd probably have to be tolerant of the following
unlikely possibilities:
1. response is chunked, but first chunk is zero-length
2. response has connection:close set instead of content-length, but no
content
3. response has non-null content-type, but no content

For #1 & #2 we'd need to peek at the first octet of the input stream, to
check if there's any actual content. 

Remember that in the HTTPconduit, we only need to check for a partial
responses in the oneway case, so the question boils down to "is there a
non-empty entity body in the response".

So we'd end up with something like the following belt'n'braces logic for
HTTPConduit.isPartialResponse():

boolean isPartialResponse(URLConnection connection, Message inMessage) {
    // a null content-type is a definite indication of no entity-body
data
    //
    if (connection.getContentType() == null) {
        return false;
    }

    // content-length if present gives a definite indication of
entity-body 
    // data presence or absence
    //
    if (connection.getContentLenght() != -1) {
        return connection.getContentLenght() > 0;
    }

    // a non-null content-type or unset content-length is not sufficient
to establish
    // an empty entity-body, must peek ahead on response stream if
chunked or
    // connection:close
    //
    if
("chunked".equalsIgnoreCase(connection.getHeaderField("transfer-encoding
"))
        ||
"close".equalsIgnoreCase(connection.getHeaderField("connection"))) {
        InputStream is = connection.getInputStream();
        PushBackInputStream peekIS = new PushBackInputStream(is, 1)
        int c = peekIS.read();
        if (c != -1) {
            peekIS.unread(c);
            inMessage.setContent(InputStream.class, peekIS);
            return true;
        }
    }
    return false;
} 

 
> > 2. RM logic shouldn't need anything special now, just
> > > recognition of a <SequenceAcknowledgement> in response to 
> a one way 
> > > message.
> >
> > Remember the SequenceAcknowledgement could also be in a partial 
> > response to a twoway request (case B as described in an 
> earlier mail 
> > on this thread).
> >
> > 3. Remove isPartialResposne from ClientImpl. This call is
> > > really superflous as we are going to return as soon as 
> the one way 
> > > message is sent anyway - we aren't blocking for a 
> response since we 
> > > check for isOneWay on line 160.  We should also change 
> our logic so 
> > > that we only look for response objects if the call is one way.
> >
> > Are you assuming that partial responses are only sent for oneways?
> >
> > If that were the case, then the full/partial response recognition 
> > issue would indeed go away.
> >
> > But alas, case B requires that twoway requests may also attract 
> > partial responses. In this case, we would indeed be waiting 
> for a full 
> > response in ClientImpl, so we need to be able to make the 
> distinction 
> > between full and partial responses in ClientImpl, so I 
> can't see how 
> > the
> > ClientImpl.isPartialResponse() logic is superfluous.
> >
> > Recall the issue that got this whole discussion started ...
> > distinguishing a partial and full response to a bare 
> doc/lit *twoway* 
> > operation with void return type. The <SOAP:Body/> is empty in both 
> > responses, hence the need to distinguish in some other way.
> 
> 
> 
> Ah shit, forgot about the two way case.
> 
> *heads back to drawing board*

Trust me, we've returned to the drawing board many times on this one :)
And we keep coming to the same conclusion, that partial responses in
some form are required, and these must be distinguishable from full
responses.

/Eoghan

Mime
View raw message