JDK-8170305 : URLConnection doesn't handle HTTP/1.1 1xx (informational) messages
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 8,9,11,17
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2016-11-08
  • Updated: 2022-09-19
  • Resolved: 2022-09-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 20
20 b15Fixed
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b15, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 10.0.14393]

A DESCRIPTION OF THE PROBLEM :
URLConnection() doesn't handle unknown status codes in the informational range (100-199).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run test code.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Infomational response should be consumed and skipped.

See "MUST" level requirement in <https://greenbytes.de/tech/webdav/rfc7231.html#rfc.section.6.2.p.2> (and the obsoleted spec: <https://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.10.1.p.2>)
ACTUAL -
Informational message is treated as final response; consequently, the final message is returned as payload.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;

public class Test103 {

    public static void main(String[] args) throws IOException {
        Runnable server = new Runnable() {
            @Override
            public void run() {
                ServerSocket serverSocket = null;

                try {
                    serverSocket = new ServerSocket(8080);
                    String crlf = String.format("%c%c", 13, 10);
                    String payload = "Hello, world.";
                    byte[] message = ("HTTP/1.1 103 Hint" + crlf + "Link: </p>; rel=prefetch" + crlf + crlf
                            + "HTTP/1.1 200 OK" + crlf + "Content-Type: text/plain" + crlf + "Content-Length: " + payload.length()
                            + crlf + crlf + payload).getBytes();
                    // System.out.println(new String(message));
                    while (true) {
                        System.err.println("waiting");
                        Socket clientSocket = serverSocket.accept();
                        System.err.println("accepted");
                        clientSocket.getOutputStream().write(message);
                        clientSocket.close();
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                } finally {
                    if (serverSocket != null) {
                        try {
                            serverSocket.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
        };
        Thread t = new Thread(server);
        t.start();
        java();
    }

    private static void java() throws IOException {
        URL test = new URL("http://localhost:8080");
        HttpURLConnection c = (HttpURLConnection) test.openConnection();
        System.out.println("Status: " + c.getResponseCode() + " "  + c.getResponseMessage());
        InputStream is = c.getInputStream();
        byte[] bytes = readFully(is);
        System.out.println("Body: " + new String(bytes));
    }

    public static byte[] readFully(InputStream is) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[16384];

        while ((nRead = is.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }

        buffer.flush();

        return buffer.toByteArray();
    }
}

---------- END SOURCE ----------


Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk19u/pull/27 Date: 2022-09-18 15:24:03 +0000
18-09-2022

Changeset: 8bd79d3e Author: Jaikiran Pai <jpai@openjdk.org> Date: 2022-09-13 05:08:05 +0000 URL: https://git.openjdk.org/jdk/commit/8bd79d3efdcab5997056675467aac70895903d33
13-09-2022

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/10229 Date: 2022-09-09 11:21:51 +0000
09-09-2022

To reproduce the issue run the attached test case. Following are the results: JDK 8 - Fail JDK 8u122ea - fail JDK 9-ea + 141 - Fail Following is the output : java version "9-ea" Java(TM) SE Runtime Environment (build 9-ea+141) Java HotSpot(TM) 64-Bit Server VM (build 9-ea+141, mixed mode) waiting accepted waiting Status: 103 Hint Body: HTTP/1.1 200 OK Content-Type: text/plain Content-Length: 13 Hello, world.
24-11-2016