FULL PRODUCT VERSION :
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
EXTRA RELEVANT SYSTEM CONFIGURATION :
You need a webserver returning 301 Moved Permanently to a malformed url
A DESCRIPTION OF THE PROBLEM :
HttpURLConnection follows Location: header with a malformed url resulting in a NullPointerException or IllegalArgumentException error.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
A script on a webserver with output:
HTTP/1.1 301 Moved Permanently
Location: http://
new URL("http://server/script").openStream();
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
throws IOException
ACTUAL -
throws IllegalArgumentException
if Location: http:/ throws NullPointerException
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalArgumentException: protocol = http host = null
at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:146)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:728)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:658)
at sun.net.www.protocol.http.HttpURLConnection.followRedirect(HttpURLConnection.java:1841)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1176)
at java.net.URL.openStream(URL.java:1009)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
/**
* @author Daniel Negrea
*
*/
public class BugDemo {
/**
* @param args none
* @throws IOException not expected
* @throws InterruptedException not expected
*/
public static void main(String[] args) throws IOException, InterruptedException {
// create a simple web server
// find the first free port
ServerSocket serverSocket = new ServerSocket(0);
final URL url = new URL("http://localhost:" + serverSocket.getLocalPort() + '/');
Thread myWebClient = new Thread(new Runnable() {
public void run() {
try {
// the line below throws IllegalArgumentException
url.openStream();
} catch (IOException e) {
// this was is expected
}
}
});
myWebClient.setDaemon(true);
myWebClient.start();
Socket socket = serverSocket.accept();
String request = "";
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
if (line.length() == 0) {
break;
}
request += line + "\n";
}
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
out.write("HTTP/1.1 301 Moved Permanently\r\n");
// out.write("Location: http:/\r\n"); - this generates
// NullPointerException
out.write("Location: http://\r\n");
out.write("\r\n");
out.flush();
out.close();
in.close();
socket.close();
serverSocket.close();
myWebClient.join();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
catch the errors and throw an exception instead
java version "1.6.0_01"
Java(TM) SE Runtime Environment (build 1.6.0_01-b06)
Java HotSpot(TM) Client VM (build 1.6.0_01-b06, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]
EXTRA RELEVANT SYSTEM CONFIGURATION :
You need a webserver returning 301 Moved Permanently to a malformed url
A DESCRIPTION OF THE PROBLEM :
HttpURLConnection follows Location: header with a malformed url resulting in a NullPointerException or IllegalArgumentException error.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
A script on a webserver with output:
HTTP/1.1 301 Moved Permanently
Location: http://
new URL("http://server/script").openStream();
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
throws IOException
ACTUAL -
throws IllegalArgumentException
if Location: http:/ throws NullPointerException
ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalArgumentException: protocol = http host = null
at sun.net.spi.DefaultProxySelector.select(DefaultProxySelector.java:146)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:728)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:658)
at sun.net.www.protocol.http.HttpURLConnection.followRedirect(HttpURLConnection.java:1841)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1176)
at java.net.URL.openStream(URL.java:1009)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
/**
* @author Daniel Negrea
*
*/
public class BugDemo {
/**
* @param args none
* @throws IOException not expected
* @throws InterruptedException not expected
*/
public static void main(String[] args) throws IOException, InterruptedException {
// create a simple web server
// find the first free port
ServerSocket serverSocket = new ServerSocket(0);
final URL url = new URL("http://localhost:" + serverSocket.getLocalPort() + '/');
Thread myWebClient = new Thread(new Runnable() {
public void run() {
try {
// the line below throws IllegalArgumentException
url.openStream();
} catch (IOException e) {
// this was is expected
}
}
});
myWebClient.setDaemon(true);
myWebClient.start();
Socket socket = serverSocket.accept();
String request = "";
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
if (line.length() == 0) {
break;
}
request += line + "\n";
}
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
out.write("HTTP/1.1 301 Moved Permanently\r\n");
// out.write("Location: http:/\r\n"); - this generates
// NullPointerException
out.write("Location: http://\r\n");
out.write("\r\n");
out.flush();
out.close();
in.close();
socket.close();
serverSocket.close();
myWebClient.join();
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
catch the errors and throw an exception instead