Skip to content

Commit

Permalink
Fix MockWebServer handling of 'Expect: 100 Continue' (square#3563)
Browse files Browse the repository at this point in the history
Previously we'd skip the request body unless the socket policy was
EXPECT_CONTINUE.

Closes: square#3498
  • Loading branch information
swankjesse authored Aug 31, 2017
1 parent 207f557 commit e5f50b5
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ private RecordedRequest readRequest(Socket socket, BufferedSource source, Buffer
Headers.Builder headers = new Headers.Builder();
long contentLength = -1;
boolean chunked = false;
boolean readBody = true;
boolean expectContinue = false;
String header;
while ((header = source.readUtf8LineStrict()).length() != 0) {
Internal.instance.addLenient(headers, header);
Expand All @@ -595,25 +595,22 @@ private RecordedRequest readRequest(Socket socket, BufferedSource source, Buffer
}
if (lowercaseHeader.startsWith("expect:")
&& lowercaseHeader.substring(7).trim().equalsIgnoreCase("100-continue")) {
readBody = false;
expectContinue = true;
}
}

if (!readBody && dispatcher.peek().getSocketPolicy() == EXPECT_CONTINUE) {
if (expectContinue && dispatcher.peek().getSocketPolicy() == EXPECT_CONTINUE) {
sink.writeUtf8("HTTP/1.1 100 Continue\r\n");
sink.writeUtf8("Content-Length: 0\r\n");
sink.writeUtf8("\r\n");
sink.flush();
readBody = true;
}

boolean hasBody = false;
TruncatingBuffer requestBody = new TruncatingBuffer(bodyLimit);
List<Integer> chunkSizes = new ArrayList<>();
MockResponse policy = dispatcher.peek();
if (!readBody) {
// Don't read the body unless we've invited the client to send it.
} else if (contentLength != -1) {
if (contentLength != -1) {
hasBody = contentLength > 0;
throttledTransfer(policy, socket, source, Okio.buffer(requestBody), contentLength, true);
} else if (chunked) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.ProtocolException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -439,4 +439,21 @@ private List<String> headersToList(MockResponse response) {
assertEquals("/a/deep/path", requestUrl.encodedPath());
assertEquals("foo bar", requestUrl.queryParameter("key"));
}

@Test public void http100Continue() throws Exception {
server.enqueue(new MockResponse().setBody("response"));

URL url = server.url("/").url();
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Expect", "100-Continue");
connection.getOutputStream().write("request".getBytes(StandardCharsets.UTF_8));

InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
assertEquals("response", reader.readLine());

RecordedRequest request = server.takeRequest();
assertEquals("request", request.getBody().readUtf8());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,8 @@ public void assertRequests(URI... expectedUris) {

@Override public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
InetSocketAddress socketAddress = (InetSocketAddress) sa;
failures.add(
Util.format("%s %s:%d %s", uri, socketAddress.getHostName(), socketAddress.getPort(),
ioe.getMessage()));
failures.add(Util.format("%s %s:%d %s",
uri, socketAddress, socketAddress.getPort(), ioe.getMessage()));
}

@Override public String toString() {
Expand Down

0 comments on commit e5f50b5

Please sign in to comment.