Export to GitHub

mockwebserver - issue #6

SocketTimeoutException when using Expect 100-continue


Posted on Mar 1, 2013 by Swift Cat

Having trouble getting to the bottom of why my test fails with SocketTimeoutException unless I remove Expect 100-continue header. Any ideas?

java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:152) at java.net.SocketInputStream.read(SocketInputStream.java:122) at java.io.BufferedInputStream.fill(BufferedInputStream.java:235) at java.io.BufferedInputStream.read1(BufferedInputStream.java:275) at java.io.BufferedInputStream.read(BufferedInputStream.java:334) at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:677) at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:623) at sun.net.www.protocol.http.HttpURLConnection.expect100Continue(HttpURLConnection.java:1020) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1105)

Code:

public void testExpect100() throws Exception {
    MockWebServer server = new MockWebServer();
    server.enqueue(new MockResponse().setBody("hello world"));
    server.play();

    URL url = server.getUrl("/");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setConnectTimeout(1000);
    connection.setReadTimeout(1000);
    connection.setAllowUserInteraction(false);
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Expect", "100-continue"); // << comment this and it will pass
    connection.setRequestProperty(CONTENT_LENGTH, "4");
    connection.setFixedLengthStreamingMode(4);
    connection.setDoOutput(true);
    connection.getOutputStream().write(new byte [] {1, 2, 3, 4});

    InputStream in = connection.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode());
    assertEquals("hello world", reader.readLine());

    RecordedRequest request = server.takeRequest();
    assertEquals("POST / HTTP/1.1", request.getRequestLine());
}

Comment #1

Posted on Mar 1, 2013 by Swift Cat

this is annoying and the fault of the java impl. In looking at the stack inside sun.net, there's goofy timeout logic when expect100Continue is used. A workaround is to change my test case to explicitly set read timeout to zero. I'm fine with the workaround, so feel free to take action or close this out.

    connection.setReadTimeout(0);

Comment #2

Posted on Mar 3, 2013 by Massive Bear

(No comment was entered for this change.)

Comment #3

Posted on Apr 12, 2013 by Massive Bear

The workaround for this (setting the read timeout to 0) causes empty PUTs to hang: issue 8

Status: WontFix

Labels:
Type-Defect Priority-Medium