I am using HttpsURLConnection call to get the response from HTTP servlet with message and error code. Following is some code snippet from my code:-
connection = (HttpsURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
// Headers
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-type", "text/xml");
connection.setRequestProperty("Accept", "text/plain");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Authorization", authorization);
connection.connect();
From HTTPServlet side, i am setting statuscode and description:-
response.setStatus(code);
response.getWriter().write(returnDescription);
All the above code is existing code and it is working fine except. It should return status code as response code. But few codes are not working like 1001,1002 or 1003. i.e if i set response.setStatus(1001) it returns -1 as responseCode() at client side with "java.io.IOException: Invalid Http response". For any other integer value like 1101,1102, 1232 etc it works fine. I debugged the code and found servlet is setting correct values but client is not able to parse response. And as you change status code with some other numeric value, it get started working correctly! I am getting same behavior in HTTP as well as with HTTPS. It seems like these non working codes are predefined codes with specific objective and can not be used as status code but i didnt find anything on web. Did anyone experienced the same and what could be the reason.
Thanks in advance! :)
Short version: OpenJDK and others have a parseHttpHeader method that parses exactly three chars of the HTTP status code number, and anything starting with the string '100' is treated as an HTTP continue. The non-continued nature of this servlet conversation confused the client, so it couldn't open the output stream and gave up.
WAAAAY long version:
This one kinda bugged me, because only 100-599 (ish, actually fewer than this) status codes should really work at all. RFC2616 says codes must be three digits and (paraphrasing) you need necessarily only understand the class of the first digit (to allow for extensions).
OpenJDK 6's HttpURLConnection implementation was the first I checked (since you didn't specify) and the code basically does:
GNU Classpath does pretty much the same.
Notably, OpenJDK doesn't particularly vet that against the RFC rules. You could put a billion in there and it would be more-or-less OK with that (at least as far as getResponseCode() cares, anyway...it looks like getInputStream() will barf on any code >=400 in the concrete implementation in sun.net.www.protocol...).
In any case, that didn't answer why you were seeing this oddball behavior for only 100x. OpenJDK looks like it should have thrown IOException of the form "Server returned HTTP 1234...
...or so I thought. HttpURLConnection is abstract, and so a concrete implementation must override at least the abstract methods. Well, the concrete implementation of HttpURLConnection, the abstract's version of getResponseCode() is sorta ignored. Kinda. This implementation calls sun.net.www.http.HttpClient's parseHTTP as part of opening the input stream, which parses out the HTTP/1. and then exactly THREE characters of the code (and then does convoluted things to massage the input stream to having all that stuff retroactively shoved back in in something called an HttpCapture. Yuck.). And if that three chars happens to come out to 100, then the client thinks it has to continue the conversation to get a working InputStream.
Since your servlet is actually done with the transaction already and it's not continuing, the client is getting confused about WTF your servlet is doing and is therefore returning an error (as it should per RFC).
So mystery solved I think. You could put pretty much anything beginning with "100" and get the same behavior (even "100xyz" if your servlet API lets you).
(Android, btw, also does this three-char parse.)
This all technically violates RFC (though, honestly, it's kind of a silly bug). Strictly speaking, only 2xx codes should be treated as totally OK to pass unmolested, but probably you could use a "000" status and pass OK (again, assuming your API lets you put an arbitrary string in there).
Hope that answers your question!