以下代码是否安全:
try {
URL url = new URL(urlRequest);
conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
String encoding = conn.getContentEncoding();
return Utils.wrapCompressedStream(conn.getInputStream(), encoding);
} catch (IOException e) {
if(conn != null) {
conn.getContentEncoding();
conn.getErrorStream();
conn.whateverOtherMethodThere();
...
}
}
特别是,在 InterruptedIOException(比如读取超时)的情况下调用类似的方法是否安全getContentEncoding()
?据我了解,此方法需要实时连接才能读取 HTTP(S) 标头。
更新(附加信息):
这个问题源于一个真实的系统体验。我相信,该系统当时是在 Oracle/Sun JVM 1.6 上运行的。代码几乎相同:
...
} catch (IOException e) {
if(conn != null) {
try {
String response = tryGetResponse(conn);
...
问题发生在tryGetResponse
on HTTPS请求中:
private static String tryGetResponse(HttpURLConnection conn) {
if(conn == null) return "(failed to get)";
InputStream in = null;
try {
InputStream err = conn.getErrorStream();
if (err != null) {
in = Utils.wrapCompressedStream(err, conn.getContentEncoding());
}
return Utils.inputStreamToString(in);
} catch (IOException e) {
return "(failed to get)";
} finally {
Utils.closeQuitely(in);
}
}
调用中的套接字连接(或读取)时系统自发挂起getContentEncoding()
:
in = Utils.wrapCompressedStream(err, conn.getContentEncoding());
恰好在SocketTimeoutException
初始代码中抛出。
因此,似乎getContentEncoding()
尝试(或在 Java 6 中尝试)建立新连接而没有设置超时。