-
Bug
-
Resolution: Incomplete
-
P4
-
None
-
8, 9
-
generic
-
generic
FULL PRODUCT VERSION :
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10586]
A DESCRIPTION OF THE PROBLEM :
When using HttpUrlConnection to send any HTTP request it always adds an invalid ': null' to the end of the request line. Most servers seem to treat this leniently, but we're calling a particular government web service that treats this as an error and returns a 400 Bad Request response.
Looking at the code for sun.net.www.protocol.http.HttpUrlConnection, it's clear where this ': null' string is coming from.
# In writeRequests (line 510 in the version I'm looking at), you have:
requests.prepend(method + " " + getRequestURI()+" " +
httpVersion, null);
# The prepend method in sun.net.www.MessageHeader looks like this (so values[0] gets set to null for the request line:
public synchronized void prepend(String k, String v) {
grow();
for (int i = nkeys; i > 0; i--) {
keys[i] = keys[i-1];
values[i] = values[i-1];
}
keys[0] = k;
values[0] = v;
nkeys++;
}
# So when the request line gets generated, it gets treated as just another message header, and you end up with:
POST <path> HTTP/1.1: null
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use java.net.HttpUrlConnection to send any GET or POST request, and set logging for sun.net.www.protocol.http.HttpsURLConnection.level to ALL, so that you can see the message headers being sent out.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the request line of a GET request to look like this:
GET <path> HTTP/1.1
ACTUAL -
The actual request line looks like this:
GET <path> HTTP/1.1: null
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.logging.Logger;
import java.util.Map;
import java.util.Set;
import java.util.Date;
public class TestHttpUrlConnection {
private final static Logger log = Logger.getLogger(TestHttpUrlConnection.class.getName());
public static void main(String[] args) throws IOException {
sendRequest();
}
public static void sendRequest() throws IOException {
log.severe("This is a severe message");
log.warning("This is a warning message");
log.info("This is an info message");
log.fine("This is a fine message");
log.finer("This is a finer message");
log.finest("This is a finest message");
URL url = new URL("http://www.w3schools.com/tags/ref_httpmethods.asp");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Cache-control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
con.setRequestProperty("Date", df.format(new Date()));
con.setInstanceFollowRedirects(true);
con.setDoInput(true);
int code = con.getResponseCode(); // 200 = HTTP_OK
System.out.println("Response (Code): " + code);
System.out.println("Response (Message): " + con.getResponseMessage());
Map<String, List<String>> hdrs = con.getHeaderFields();
Set<String> hdrKeys = hdrs.keySet();
System.out.println("");
for (String k : hdrKeys) {
System.out.println("Key: " + k + " Value: " + hdrs.get(k));
}
}
}
---------- END SOURCE ----------
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.10586]
A DESCRIPTION OF THE PROBLEM :
When using HttpUrlConnection to send any HTTP request it always adds an invalid ': null' to the end of the request line. Most servers seem to treat this leniently, but we're calling a particular government web service that treats this as an error and returns a 400 Bad Request response.
Looking at the code for sun.net.www.protocol.http.HttpUrlConnection, it's clear where this ': null' string is coming from.
# In writeRequests (line 510 in the version I'm looking at), you have:
requests.prepend(method + " " + getRequestURI()+" " +
httpVersion, null);
# The prepend method in sun.net.www.MessageHeader looks like this (so values[0] gets set to null for the request line:
public synchronized void prepend(String k, String v) {
grow();
for (int i = nkeys; i > 0; i--) {
keys[i] = keys[i-1];
values[i] = values[i-1];
}
keys[0] = k;
values[0] = v;
nkeys++;
}
# So when the request line gets generated, it gets treated as just another message header, and you end up with:
POST <path> HTTP/1.1: null
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use java.net.HttpUrlConnection to send any GET or POST request, and set logging for sun.net.www.protocol.http.HttpsURLConnection.level to ALL, so that you can see the message headers being sent out.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would expect the request line of a GET request to look like this:
GET <path> HTTP/1.1
ACTUAL -
The actual request line looks like this:
GET <path> HTTP/1.1: null
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.HttpURLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.logging.Logger;
import java.util.Map;
import java.util.Set;
import java.util.Date;
public class TestHttpUrlConnection {
private final static Logger log = Logger.getLogger(TestHttpUrlConnection.class.getName());
public static void main(String[] args) throws IOException {
sendRequest();
}
public static void sendRequest() throws IOException {
log.severe("This is a severe message");
log.warning("This is a warning message");
log.info("This is an info message");
log.fine("This is a fine message");
log.finer("This is a finer message");
log.finest("This is a finest message");
URL url = new URL("http://www.w3schools.com/tags/ref_httpmethods.asp");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("Cache-control", "no-cache");
con.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
con.setRequestProperty("Date", df.format(new Date()));
con.setInstanceFollowRedirects(true);
con.setDoInput(true);
int code = con.getResponseCode(); // 200 = HTTP_OK
System.out.println("Response (Code): " + code);
System.out.println("Response (Message): " + con.getResponseMessage());
Map<String, List<String>> hdrs = con.getHeaderFields();
Set<String> hdrKeys = hdrs.keySet();
System.out.println("");
for (String k : hdrKeys) {
System.out.println("Key: " + k + " Value: " + hdrs.get(k));
}
}
}
---------- END SOURCE ----------