DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16522>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16522

Allow Axis HTTP 1.1 clients to use Keep-Alive

           Summary: Allow Axis HTTP 1.1 clients to use Keep-Alive
           Product: Axis
           Version: 1.1beta
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: Enhancement
          Priority: Other
         Component: Basic Architecture
        AssignedTo: [EMAIL PROTECTED]
        ReportedBy: [EMAIL PROTECTED]


Support for Connection:Keep-Alive has been disabled in HTTPSender.java since 
version 1.67, when code was introduced to always emit Connection:Close
This may have been done to circumvent a hang caused by Xerces trying to read 
more bytes from its InputSource than are available on the InputStream (see 
below). 

This bug report will be updated after posting with a .zip file containing a 
proposed modification to HTTPSender.java developed by Shih-Chang Chen (shih-
[EMAIL PROTECTED]) which I found on the axis-user mailing list and dusted off 
and tested.

Background Info

Here is what I found in looking into this, from the perspective
of using Axis as a client:

1) org.apache.axis.transport.http.HTTPSender.java deliberately generates a
Connection:close header even if HTTP 1.1 is set, which prevents connections
from being maintained. The comment "Force close for now" appears in the code 
and suggests that the author may have introduced this in v1.67 to circumvent 
the hang such as the one I discovered. 

2) HTTPSender.java calls getSocket() for every transaction, which creates a
new SocketFactory for every transaction, which in turn creates a new socket
for each transaction. Obviously this needs to change if connections are to
be maintained across calls. This is simple to do. 

3) If you modify HttpSender.java to correct the above 2 problems, and begin
an HTTP 1.1 session with a non-Axis SOAP server which supports Keep-Alive,
the result is a hang in the Axis client during receipt of the first
response, caused by Xerces trying to read more bytes than are available from
the SocketInputStream it is given as it's input source. Axis clients seem to
depend on the other server closing the connection to prevent this hang.
Although Axis is careful to read exactly the right number of bytes from the
input stream when consuming the headers, and is careful to construct an
inputstream for Xerces that is set up such that the bytes available exactly
equal the Content-Length, Xerces still tries to read more from the input
source, even if it should have seen a complete XML document by the time it
has processed the bytes available. In other words, it seems that an Axis client 
would hang, with Xerces trying to read more than Content-Length bytes from the
inputstream, if the the other side did not close the connection after
sending its response.

4) One can make a temporary fix for the hang by supplying a read method in
org.apache.axis.transport.http.SocketInputStream.java which checks
in.available() before reading from the inputstream, and just reflects EOF to
Xerces by returning -1 if in.available()==0.  Then hang goes away, but the
Socket gets closed when the InputStream gets closed. If you modify the
close() code in org.apache.axis.transport.http.SocketInputStream to
deliberately not close the Socket, then you can successfully maintain an
HTTP 1.1 connection with a non-Axis SOAP server across any number of SOAP
calls. 

The changes just described are admittedly a hack, so I tested Shih-Chang Chen's 
code posted to axis-user on 4/9/2002. This consists of a major modification to 
HTTPSender.java and a new class called HTTPInputStream. It worked for me, with 
both HTTPS and HTTP.  This seems like the right way to go.

Reply via email to