Monday March 16, 2009 | Jean-Christophe Collet's Weblog Jean-Christophe Collet's Weblog |
|
HttpURLConnection and 100-Continue According to RFC 2616 section 8.2.3 a client can use the 'Expect: 100-continue' request header to make sure the server will accept the 'PUT' or 'POST' operation before actually sending the request body. This is particularly useful when said body is of a significant size, like when uploading a file. Indeed, if the request is denied by the server for any reason, checking this before sending the body can save a lot of bandwidth. Unfortunately, at the moment, the HTTP protocol handler doesn't implement this correctly. There is code that is basically here to ignore the 100-continue response if it is ever returned by the HTTP server. CR #6726695 has been filed against this and I just wanted to post a quick note as to how we intend to fix this in JDK 7. In a effort to limit bloat, instead of introducing a specific API (new methods typically) we're planning on using the existing setRequestProperty() method. Basically if the applications sets the "Expect: 100-Continue" header, then the protocol handler will wait for a 100-Continue response code. When the application calls getOutputStream() it will throw a ProtocolException if the server rejected the request (i.e. returned something else than 100-Continue). A typical usage would be something like: URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection) con;
http.setRequestMethod("POST");
http.setRequestProperty("Expect", "100-Continue");
http.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
http.setDoOutput(true);
int l = data.length() + (boundary.length()*2) + 14 + dispo.length() + ctype.length();
http.setFixedLengthStreamingMode(l);
OutputStream out = null;
try {
out = http.getOutputStream();
} catch (ProtocolException e) {
System.err.println("Server rejected the request. Code = " + http.getResponseCode());
return;
}
Note that getResponseCode() will provide the actual code returned. IF 100-continue was received then the application can proceed providing the request body by writing to the OutputStream. The response code will then be updated with the one sent by the server after the POST (or PUT). Hopefully a 200-OK. E.g (as a followup of code above): BufferedWriter outs = new BufferedWriter(new OutputStreamWriter(out));
outs.write("--" + boundary + "\r\n");
outs.write(dispo);
outs.write(ctype);
outs.write("\r\n");
outs.write(data);
outs.write("\r\n--" + boundary + "--\r\n");
outs.flush();
InputStream in = http.getInputStream();
System.err.println("Response code is " + http.getResponseCode());
BufferedReader ins = new BufferedReader(new InputStreamReader(in));
String line = ins.readLine();
while (line != null) {
System.err.println(line);
line = ins.readLine();
}
ins.close();
outs.close();
Let me know what you think of this. Unless there are serious objections to this solution, I intend to push the fix into JDK 7 master in a week or two. (2009-03-16 06:07:10.0) Permalink Comments [3] Post a Comment: Comments are closed for this entry. |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Wouldn't the smart think be to always throw an IllegalStateException if you used setRequestProperty("Expect", "100-Continue") and call getOutputStream() before the getResponseCode(), regardless of the response code.
That way, the developer won't be surprised if his code seems to work during testing, but fails in a real life scenario.
Posted by Roel Spilker on March 17, 2009 at 01:18 PM CET #
For a number of reasons, including backward compatibility, it's not that easy. But your point is well taken that some matter of documentation of this behavior should be addressed.
Thanks.
Posted by Jean-Christophe Collet on March 17, 2009 at 04:23 PM CET #
Hello,
Please add your site at http://www.sweebs.com. Sweebs.com is a place where other people can find you among the best sites on the internet!
Its just started and we are collecting the best found on the net! We will be delighted to have you in the sweebs listings.
Regards
Kris
Posted by Kris on March 19, 2009 at 07:23 PM CET #