Skip to content

Commit e5f50b5

Browse files
authored
Fix MockWebServer handling of 'Expect: 100 Continue' (square#3563)
Previously we'd skip the request body unless the socket policy was EXPECT_CONTINUE. Closes: square#3498
1 parent 207f557 commit e5f50b5

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

mockwebserver/src/main/java/okhttp3/mockwebserver/MockWebServer.java

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ private RecordedRequest readRequest(Socket socket, BufferedSource source, Buffer
581581
Headers.Builder headers = new Headers.Builder();
582582
long contentLength = -1;
583583
boolean chunked = false;
584-
boolean readBody = true;
584+
boolean expectContinue = false;
585585
String header;
586586
while ((header = source.readUtf8LineStrict()).length() != 0) {
587587
Internal.instance.addLenient(headers, header);
@@ -595,25 +595,22 @@ private RecordedRequest readRequest(Socket socket, BufferedSource source, Buffer
595595
}
596596
if (lowercaseHeader.startsWith("expect:")
597597
&& lowercaseHeader.substring(7).trim().equalsIgnoreCase("100-continue")) {
598-
readBody = false;
598+
expectContinue = true;
599599
}
600600
}
601601

602-
if (!readBody && dispatcher.peek().getSocketPolicy() == EXPECT_CONTINUE) {
602+
if (expectContinue && dispatcher.peek().getSocketPolicy() == EXPECT_CONTINUE) {
603603
sink.writeUtf8("HTTP/1.1 100 Continue\r\n");
604604
sink.writeUtf8("Content-Length: 0\r\n");
605605
sink.writeUtf8("\r\n");
606606
sink.flush();
607-
readBody = true;
608607
}
609608

610609
boolean hasBody = false;
611610
TruncatingBuffer requestBody = new TruncatingBuffer(bodyLimit);
612611
List<Integer> chunkSizes = new ArrayList<>();
613612
MockResponse policy = dispatcher.peek();
614-
if (!readBody) {
615-
// Don't read the body unless we've invited the client to send it.
616-
} else if (contentLength != -1) {
613+
if (contentLength != -1) {
617614
hasBody = contentLength > 0;
618615
throttledTransfer(policy, socket, source, Okio.buffer(requestBody), contentLength, true);
619616
} else if (chunked) {

mockwebserver/src/test/java/okhttp3/mockwebserver/MockWebServerTest.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@
2323
import java.io.OutputStream;
2424
import java.net.ConnectException;
2525
import java.net.HttpURLConnection;
26-
import java.net.InetAddress;
2726
import java.net.ProtocolException;
2827
import java.net.SocketTimeoutException;
2928
import java.net.URL;
3029
import java.net.URLConnection;
30+
import java.nio.charset.StandardCharsets;
3131
import java.util.ArrayList;
3232
import java.util.Arrays;
3333
import java.util.List;
@@ -439,4 +439,21 @@ private List<String> headersToList(MockResponse response) {
439439
assertEquals("/a/deep/path", requestUrl.encodedPath());
440440
assertEquals("foo bar", requestUrl.queryParameter("key"));
441441
}
442+
443+
@Test public void http100Continue() throws Exception {
444+
server.enqueue(new MockResponse().setBody("response"));
445+
446+
URL url = server.url("/").url();
447+
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
448+
connection.setDoOutput(true);
449+
connection.setRequestProperty("Expect", "100-Continue");
450+
connection.getOutputStream().write("request".getBytes(StandardCharsets.UTF_8));
451+
452+
InputStream in = connection.getInputStream();
453+
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
454+
assertEquals("response", reader.readLine());
455+
456+
RecordedRequest request = server.takeRequest();
457+
assertEquals("request", request.getBody().readUtf8());
458+
}
442459
}

okhttp-tests/src/test/java/okhttp3/internal/http/RecordingProxySelector.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,8 @@ public void assertRequests(URI... expectedUris) {
4545

4646
@Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
4747
InetSocketAddress socketAddress = (InetSocketAddress) sa;
48-
failures.add(
49-
Util.format("%s %s:%d %s", uri, socketAddress.getHostName(), socketAddress.getPort(),
50-
ioe.getMessage()));
48+
failures.add(Util.format("%s %s:%d %s",
49+
uri, socketAddress, socketAddress.getPort(), ioe.getMessage()));
5150
}
5251

5352
@Override public String toString() {

0 commit comments

Comments
 (0)