2012년 4월 23일 월요일

[TechNote] Unable to see SOAP response from HttpURLConnection getInputStream when the server returns an HTTP 500 status code


Unable to see SOAP response from HttpURLConnection getInputStream when the server returns an HTTP 500 status code

Problem(Abstract)

When an input stream is obtained on the connection, an IOException is thrown resulting in an inability to access the response message (i.e SOAP Fault).

In regards to a messaging gateway application which is used to send SOAP messages over HTTPS. The SOAP standard states that in case of a SOAP error while processing the request, the SOAP HTTP server must issue an HTTP 500 "Internal Server Error" response along with a SOAP Fault message. The SOAP 1.1 specification is as follows in this URL:

http://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383526

A SOAP fault issued with a non-standard HTTP 200 status code does not encounter this problem. However, correctly following the SOAP standard and issuing an HTTP 500 does.

Sun reports that this is a known issue with the Sun implementation of JSSE (see document from Sun):
Bug Id: 6400786
Synopsis: HttpURLConnection should be documented to throw IOException on errors >=400
Link: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6400786

Another related issue also reported:
Bug Id: 4160499
Synopsis: sun.net.www.protocol.http.HttpURLConnection error handling
Link: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4160499

Cause

HttpURLConnection class getInputStream () method throws IOException on HTTP status codes >=400

Diagnosing the problem

The issue can manifest itself in the following way: When an input stream is obtained on the connection, an IOException is thrown therefore there is no access to the response message (i.e SOAP Fault). This can be identified in the log as follows:

WARNING: Error on low level HTTP communication streams: Server returned HTTP response code: 500 for URL: https://myserver.com/MsgSvc/Inbox.asmx
Sep 25, 2008 04:20:11 PM com.aon.ade.soap.send.SOAPTransmitBean transmitAttempt
WARNING: Error sending envelope (UUID:
080dfd49-4ca9-11db-90e4-00c0f03d5b7c, TransmitID: 10408) to URL:
https://myserver.com/MsgSvc/Inbox.asmx - java.io.IOException: Server returned HTTP response code: 500 for URL:
https://myserver.com/MsgSvc/Inbox.asmx

This shows the IOException rather than being able to access the error response in the InputStream.

Resolving the problem

The JDK is working as designed, at least in terms of the issue described in the Sun document (4513568). This issue was closed as "not a bug". From the evaluation:

The observed behavior is as expected - if the http server returns an error then getInputStream will throw an IOException.

*Note that this doesn't preclude the application from reading the response. The SOAP example can be modified as follows :-
HttpURLConnection httpConn = (HttpURLConnection)_urlConnection;
InputStream _is;
if (httpConn.getResponseCode() >= 400) {
_is = httpConn.getInputStream();
} else {
/* error from server */
_is = httpConn.getErrorStream();
}

This is not a bug in the http client.

The related bug 6400786 discusses the fact that this behavior should be documented more clearly:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6400786

댓글 없음:

댓글 쓰기