aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2013-07-23 08:47:04 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2013-07-23 08:47:04 +0000
commit527ea78938a49edc4532186a869ad528b1fbf73e (patch)
tree38df6e3e81537b1908d00d69187570cca182b1d8
parent4d31eb4667a86cca81ecf5943b0b61cd1e8d1fae (diff)
parentfb0eb65be9f50e75fa37c250e97914252c587caf (diff)
downloadokhttp-jb-mr1.1-dev-plus-aosp.tar.gz
Merge "Update OkHttp to commit cc4633943800572673c03b32d0b2bc9a08ae184d"jb-mr1.1-dev-plus-aosp
-rw-r--r--README.md39
-rw-r--r--pom.xml2
-rw-r--r--src/main/java/com/squareup/okhttp/Connection.java34
-rw-r--r--src/main/java/com/squareup/okhttp/ConnectionPool.java4
-rw-r--r--src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java2
-rw-r--r--src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java38
-rw-r--r--src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java36
-rw-r--r--src/main/java/com/squareup/okhttp/internal/http/RouteSelector.java10
-rw-r--r--src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java1
-rw-r--r--src/test/java/com/squareup/okhttp/ConnectionPoolTest.java3
-rw-r--r--src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java2
-rw-r--r--src/test/java/com/squareup/okhttp/internal/http/RouteSelectorTest.java92
-rw-r--r--src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java8
-rw-r--r--src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java21
14 files changed, 165 insertions, 127 deletions
diff --git a/README.md b/README.md
index c3a44ee..e206f23 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,46 @@
OkHttp
======
-An HTTP+SPDY client for Android and Java applications.
+An HTTP & SPDY client for Android and Java applications.
+
+For more information please see [the website][1].
+
Download
--------
-Downloadable .jars can be found on the [GitHub download page][1].
-
-You can also depend on the .jar through Maven:
+Download [the latest JAR][2] or grab via Maven:
```xml
<dependency>
- <groupId>com.squareup</groupId>
+ <groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>(insert latest version)</version>
</dependency>
```
-Known Issues
-------------
-
-OkHttp uses the platform's [ProxySelector][2]. Prior to Android 4.0, `ProxySelector` didn't honor the `proxyHost` and `proxyPort` system properties for HTTPS connections. Work around this by specifying the `https.proxyHost` and `https.proxyPort` system properties when using a proxy with HTTPS.
-
-OkHttp's test suite creates an in-process HTTPS server. Prior to Android 2.3, SSL server sockets were broken, and so HTTPS tests will time out when run on such devices.
-
-
Building
--------
### On the Desktop
-Run OkHttp tests on the desktop with Maven. Running SPDY tests on the desktop uses [Jetty-NPN](http://wiki.eclipse.org/Jetty/Feature/NPN) which requires OpenJDK 7+.
+
+Run OkHttp tests on the desktop with Maven. Running SPDY tests on the desktop uses
+[Jetty-NPN][3] which requires OpenJDK 7+.
+
```
mvn clean test
```
### On a Device
-Test on a USB-attached Android using [Vogar](https://code.google.com/p/vogar/). Unfortunately `dx` requires that you build with Java 6, otherwise the test class will be silently omitted from the `.dex` file.
+
+OkHttp's test suite creates an in-process HTTPS server. Prior to Android 2.3, SSL server sockets
+were broken, and so HTTPS tests will time out when run on such devices.
+
+Test on a USB-attached Android using [Vogar][4]. Unfortunately `dx` requires that you build with
+Java 6, otherwise the test class will be silently omitted from the `.dex` file.
+
```
mvn clean
mvn package -DskipTests
@@ -67,5 +69,8 @@ License
- [1]: http://github.com/square/okhttp/downloads
- [2]: http://developer.android.com/reference/java/net/ProxySelector.html
+
+ [1]: http://square.github.io/okhttp
+ [2]: http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.squareup.okhttp&a=okhttp&v=LATEST
+ [3]: http://wiki.eclipse.org/Jetty/Feature/NPN
+ [4]: https://code.google.com/p/vogar/
diff --git a/pom.xml b/pom.xml
index a36c2e6..853f0b9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>com.squareup.okhttp</groupId>
<artifactId>parent</artifactId>
- <version>1.0.3-SNAPSHOT</version>
+ <version>1.1.2-SNAPSHOT</version>
</parent>
<artifactId>okhttp</artifactId>
diff --git a/src/main/java/com/squareup/okhttp/Connection.java b/src/main/java/com/squareup/okhttp/Connection.java
index 73c4b56..cfda281 100644
--- a/src/main/java/com/squareup/okhttp/Connection.java
+++ b/src/main/java/com/squareup/okhttp/Connection.java
@@ -31,6 +31,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.Proxy;
import java.net.Socket;
+import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.Arrays;
import javax.net.ssl.SSLSocket;
@@ -192,6 +193,39 @@ public final class Connection implements Closeable {
return !socket.isClosed() && !socket.isInputShutdown() && !socket.isOutputShutdown();
}
+ /**
+ * Returns true if we are confident that we can read data from this
+ * connection. This is more expensive and more accurate than {@link
+ * #isAlive()}; callers should check {@link #isAlive()} first.
+ */
+ public boolean isReadable() {
+ if (!(in instanceof BufferedInputStream)) {
+ return true; // Optimistic.
+ }
+ if (isSpdy()) {
+ return true; // Optimistic. We can't test SPDY because its streams are in use.
+ }
+ BufferedInputStream bufferedInputStream = (BufferedInputStream) in;
+ try {
+ int readTimeout = socket.getSoTimeout();
+ try {
+ socket.setSoTimeout(1);
+ bufferedInputStream.mark(1);
+ if (bufferedInputStream.read() == -1) {
+ return false; // Stream is exhausted; socket is closed.
+ }
+ bufferedInputStream.reset();
+ return true;
+ } finally {
+ socket.setSoTimeout(readTimeout);
+ }
+ } catch (SocketTimeoutException ignored) {
+ return true; // Read timed out; socket is good.
+ } catch (IOException e) {
+ return false; // Couldn't read; socket is closed.
+ }
+ }
+
public void resetIdleStartTime() {
if (spdyConnection != null) {
throw new IllegalStateException("spdyConnection != null");
diff --git a/src/main/java/com/squareup/okhttp/ConnectionPool.java b/src/main/java/com/squareup/okhttp/ConnectionPool.java
index 009f025..42b70b9 100644
--- a/src/main/java/com/squareup/okhttp/ConnectionPool.java
+++ b/src/main/java/com/squareup/okhttp/ConnectionPool.java
@@ -216,8 +216,6 @@ public class ConnectionPool {
* <p>It is an error to use {@code connection} after calling this method.
*/
public void recycle(Connection connection) {
- executorService.submit(connectionsCleanupCallable);
-
if (connection.isSpdy()) {
return;
}
@@ -240,6 +238,8 @@ public class ConnectionPool {
connections.addFirst(connection);
connection.resetIdleStartTime();
}
+
+ executorService.submit(connectionsCleanupCallable);
}
/**
diff --git a/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java b/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java
index 51fd2a7..d6b6001 100644
--- a/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java
+++ b/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java
@@ -286,7 +286,7 @@ public class HttpEngine {
routeSelector = new RouteSelector(address, uri, client.getProxySelector(),
client.getConnectionPool(), Dns.DEFAULT, client.getRoutesDatabase());
}
- connection = routeSelector.next();
+ connection = routeSelector.next(method);
if (!connection.isConnected()) {
connection.connect(client.getConnectTimeout(), client.getReadTimeout(), getTunnelConfig());
client.getConnectionPool().maybeShare(connection);
diff --git a/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java b/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java
index e8c198f..214f25a 100644
--- a/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java
+++ b/src/main/java/com/squareup/okhttp/internal/http/HttpURLConnectionImpl.java
@@ -19,8 +19,6 @@ package com.squareup.okhttp.internal.http;
import com.squareup.okhttp.Connection;
import com.squareup.okhttp.OkHttpClient;
-import com.squareup.okhttp.internal.AbstractOutputStream;
-import com.squareup.okhttp.internal.FaultRecoveringOutputStream;
import com.squareup.okhttp.internal.Platform;
import com.squareup.okhttp.internal.Util;
import java.io.FileNotFoundException;
@@ -69,20 +67,12 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
*/
private static final int MAX_REDIRECTS = 20;
- /**
- * The minimum number of request body bytes to transmit before we're willing
- * to let a routine {@link IOException} bubble up to the user. This is used to
- * size a buffer for data that will be replayed upon error.
- */
- private static final int MAX_REPLAY_BUFFER_LENGTH = 8192;
-
final OkHttpClient client;
private final RawHeaders rawRequestHeaders = new RawHeaders();
/** Like the superclass field of the same name, but a long and available on all platforms. */
private long fixedContentLength = -1;
private int redirectionCount;
- private FaultRecoveringOutputStream faultRecoveringRequestBody;
protected IOException httpEngineFailure;
protected HttpEngine httpEngine;
@@ -212,22 +202,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
throw new ProtocolException("cannot write request body after response has been read");
}
- if (faultRecoveringRequestBody == null) {
- faultRecoveringRequestBody = new FaultRecoveringOutputStream(MAX_REPLAY_BUFFER_LENGTH, out) {
- @Override protected OutputStream replacementStream(IOException e) throws IOException {
- if (httpEngine.getRequestBody() instanceof AbstractOutputStream
- && ((AbstractOutputStream) httpEngine.getRequestBody()).isClosed()) {
- return null; // Don't recover once the underlying stream has been closed.
- }
- if (handleFailure(e)) {
- return httpEngine.getRequestBody();
- }
- return null; // This is a permanent failure.
- }
- };
- }
-
- return faultRecoveringRequestBody;
+ return out;
}
@Override public final Permission getPermission() throws IOException {
@@ -393,8 +368,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
OutputStream requestBody = httpEngine.getRequestBody();
boolean canRetryRequestBody = requestBody == null
- || requestBody instanceof RetryableOutputStream
- || (faultRecoveringRequestBody != null && faultRecoveringRequestBody.isRecoverable());
+ || requestBody instanceof RetryableOutputStream;
if (routeSelector == null && httpEngine.connection == null // No connection.
|| routeSelector != null && !routeSelector.hasNext() // No more routes to attempt.
|| !isRecoverable(e)
@@ -404,15 +378,9 @@ public class HttpURLConnectionImpl extends HttpURLConnection implements Policy {
}
httpEngine.release(true);
- RetryableOutputStream retryableOutputStream = requestBody instanceof RetryableOutputStream
- ? (RetryableOutputStream) requestBody
- : null;
+ RetryableOutputStream retryableOutputStream = (RetryableOutputStream) requestBody;
httpEngine = newHttpEngine(method, rawRequestHeaders, null, retryableOutputStream);
httpEngine.routeSelector = routeSelector; // Keep the same routeSelector.
- if (faultRecoveringRequestBody != null && faultRecoveringRequestBody.isRecoverable()) {
- httpEngine.sendRequest();
- faultRecoveringRequestBody.replaceStream(httpEngine.getRequestBody());
- }
return true;
}
diff --git a/src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java b/src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java
index e5abd2c..e1fdcf4 100644
--- a/src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java
+++ b/src/main/java/com/squareup/okhttp/internal/http/RawHeaders.java
@@ -123,23 +123,6 @@ public final class RawHeaders {
this.httpMinorVersion = httpMinorVersion;
}
- public void computeResponseStatusLineFromSpdyHeaders() throws IOException {
- String status = null;
- String version = null;
- for (int i = 0; i < namesAndValues.size(); i += 2) {
- String name = namesAndValues.get(i);
- if (":status".equals(name)) {
- status = namesAndValues.get(i + 1);
- } else if (":version".equals(name)) {
- version = namesAndValues.get(i + 1);
- }
- }
- if (status == null || version == null) {
- throw new ProtocolException("Expected ':status' and ':version' headers not present");
- }
- setStatusLine(version + " " + status);
- }
-
/**
* @param method like "GET", "POST", "HEAD", etc.
* @param path like "/foo/bar.html"
@@ -425,10 +408,13 @@ public final class RawHeaders {
return result;
}
- public static RawHeaders fromNameValueBlock(List<String> nameValueBlock) {
+ /** Returns headers for a name value block containing a SPDY response. */
+ public static RawHeaders fromNameValueBlock(List<String> nameValueBlock) throws IOException {
if (nameValueBlock.size() % 2 != 0) {
throw new IllegalArgumentException("Unexpected name value block: " + nameValueBlock);
}
+ String status = null;
+ String version = null;
RawHeaders result = new RawHeaders();
for (int i = 0; i < nameValueBlock.size(); i += 2) {
String name = nameValueBlock.get(i);
@@ -438,11 +424,21 @@ public final class RawHeaders {
if (end == -1) {
end = values.length();
}
- result.namesAndValues.add(name);
- result.namesAndValues.add(values.substring(start, end));
+ String value = values.substring(start, end);
+ if (":status".equals(name)) {
+ status = value;
+ } else if (":version".equals(name)) {
+ version = value;
+ } else {
+ result.namesAndValues.add(name);
+ result.namesAndValues.add(value);
+ }
start = end + 1;
}
}
+ if (status == null) throw new ProtocolException("Expected ':status' header not present");
+ if (version == null) throw new ProtocolException("Expected ':version' header not present");
+ result.setStatusLine(version + " " + status);
return result;
}
}
diff --git a/src/main/java/com/squareup/okhttp/internal/http/RouteSelector.java b/src/main/java/com/squareup/okhttp/internal/http/RouteSelector.java
index bab9df2..1055e4f 100644
--- a/src/main/java/com/squareup/okhttp/internal/http/RouteSelector.java
+++ b/src/main/java/com/squareup/okhttp/internal/http/RouteSelector.java
@@ -102,11 +102,11 @@ public final class RouteSelector {
*
* @throws NoSuchElementException if there are no more routes to attempt.
*/
- public Connection next() throws IOException {
+ public Connection next(String method) throws IOException {
// Always prefer pooled connections over new connections.
- Connection pooled = pool.get(address);
- if (pooled != null) {
- return pooled;
+ for (Connection pooled; (pooled = pool.get(address)) != null; ) {
+ if (method.equals("GET") || pooled.isReadable()) return pooled;
+ pooled.close();
}
// Compute the next route to attempt.
@@ -131,7 +131,7 @@ public final class RouteSelector {
postponedRoutes.add(route);
// We will only recurse in order to skip previously failed routes. They will be
// tried last.
- return next();
+ return next(method);
}
return new Connection(route);
diff --git a/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java b/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java
index daa4e80..a37a91c 100644
--- a/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java
+++ b/src/main/java/com/squareup/okhttp/internal/http/SpdyTransport.java
@@ -69,7 +69,6 @@ public final class SpdyTransport implements Transport {
@Override public ResponseHeaders readResponseHeaders() throws IOException {
List<String> nameValueBlock = stream.getResponseHeaders();
RawHeaders rawHeaders = RawHeaders.fromNameValueBlock(nameValueBlock);
- rawHeaders.computeResponseStatusLineFromSpdyHeaders();
httpEngine.receiveHeaders(rawHeaders);
ResponseHeaders headers = new ResponseHeaders(httpEngine.uri, rawHeaders);
diff --git a/src/test/java/com/squareup/okhttp/ConnectionPoolTest.java b/src/test/java/com/squareup/okhttp/ConnectionPoolTest.java
index e26e563..6820b43 100644
--- a/src/test/java/com/squareup/okhttp/ConnectionPoolTest.java
+++ b/src/test/java/com/squareup/okhttp/ConnectionPoolTest.java
@@ -395,7 +395,8 @@ public final class ConnectionPoolTest {
Util.closeQuietly(httpA); // Include a closed connection in the pool.
pool.recycle(httpB);
pool.maybeShare(spdyA);
- assertEquals(3, pool.getConnectionCount());
+ int connectionCount = pool.getConnectionCount();
+ assertTrue(connectionCount == 2 || connectionCount == 3);
pool.evictAll();
assertEquals(0, pool.getConnectionCount());
diff --git a/src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java b/src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java
index 474e507..7d8ecf3 100644
--- a/src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java
+++ b/src/test/java/com/squareup/okhttp/internal/http/RawHeadersTest.java
@@ -23,7 +23,7 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
public final class RawHeadersTest {
- @Test public void parseNameValueBlock() {
+ @Test public void parseNameValueBlock() throws IOException {
List<String> nameValueBlock =
Arrays.asList("cache-control", "no-cache, no-store", "set-cookie", "Cookie1\u0000Cookie2",
":status", "200 OK");
diff --git a/src/test/java/com/squareup/okhttp/internal/http/RouteSelectorTest.java b/src/test/java/com/squareup/okhttp/internal/http/RouteSelectorTest.java
index 1cdcb1d..a92db9e 100644
--- a/src/test/java/com/squareup/okhttp/internal/http/RouteSelectorTest.java
+++ b/src/test/java/com/squareup/okhttp/internal/http/RouteSelectorTest.java
@@ -88,12 +88,13 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 1);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext());
try {
- routeSelector.next();
+ routeSelector.next("GET");
fail();
} catch (NoSuchElementException expected) {
}
@@ -106,14 +107,15 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 1);
- Connection connection = routeSelector.next();
+ Connection connection = routeSelector.next("GET");
RouteDatabase routeDatabase = new RouteDatabase();
routeDatabase.failed(connection.getRoute(), new IOException());
routeSelector = new RouteSelector(address, uri, proxySelector, pool, dns, routeDatabase);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
assertFalse(routeSelector.hasNext());
try {
- routeSelector.next();
+ routeSelector.next("GET");
fail();
} catch (NoSuchElementException expected) {
}
@@ -126,9 +128,9 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 2);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[0], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[0], proxyAPort,
false);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[1], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[1], proxyAPort,
false);
assertFalse(routeSelector.hasNext());
@@ -144,8 +146,10 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 2);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[1], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[1], uriPort,
+ false);
assertFalse(routeSelector.hasNext());
dns.assertRequests(uri.getHost());
@@ -162,7 +166,8 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 1);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext());
@@ -175,8 +180,10 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 2);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[1], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[1], uriPort,
+ false);
assertFalse(routeSelector.hasNext());
dns.assertRequests(uri.getHost());
@@ -195,23 +202,24 @@ public final class RouteSelectorTest {
// First try the IP addresses of the first proxy, in sequence.
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 2);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[0], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[0], proxyAPort,
false);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[1], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[1], proxyAPort,
false);
dns.assertRequests(proxyAHost);
// Next try the IP address of the second proxy.
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(254, 1);
- assertConnection(routeSelector.next(), address, proxyB, dns.inetAddresses[0], proxyBPort,
+ assertConnection(routeSelector.next("GET"), address, proxyB, dns.inetAddresses[0], proxyBPort,
false);
dns.assertRequests(proxyBHost);
// Finally try the only IP address of the origin server.
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(253, 1);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext());
@@ -228,7 +236,8 @@ public final class RouteSelectorTest {
// Only the origin server will be attempted.
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 1);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext());
@@ -246,14 +255,14 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 1);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[0], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[0], proxyAPort,
false);
dns.assertRequests(proxyAHost);
assertTrue(routeSelector.hasNext());
dns.inetAddresses = null;
try {
- routeSelector.next();
+ routeSelector.next("GET");
fail();
} catch (UnknownHostException expected) {
}
@@ -261,13 +270,14 @@ public final class RouteSelectorTest {
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(255, 1);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[0], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[0], proxyAPort,
false);
dns.assertRequests(proxyAHost);
assertTrue(routeSelector.hasNext());
dns.inetAddresses = makeFakeAddresses(254, 1);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
dns.assertRequests(uriHost);
assertFalse(routeSelector.hasNext());
@@ -281,7 +291,7 @@ public final class RouteSelectorTest {
routeDatabase);
dns.inetAddresses = makeFakeAddresses(255, 1);
- Connection connection = routeSelector.next();
+ Connection connection = routeSelector.next("GET");
routeSelector.connectFailed(connection, new IOException("Non SSL exception"));
assertTrue(routeDatabase.failedRoutesCount() == 2);
}
@@ -294,7 +304,7 @@ public final class RouteSelectorTest {
routeDatabase);
dns.inetAddresses = makeFakeAddresses(255, 1);
- Connection connection = routeSelector.next();
+ Connection connection = routeSelector.next("GET");
routeSelector.connectFailed(connection, new SSLHandshakeException("SSL exception"));
assertTrue(routeDatabase.failedRoutesCount() == 1);
}
@@ -309,31 +319,39 @@ public final class RouteSelectorTest {
// Proxy A
dns.inetAddresses = makeFakeAddresses(255, 2);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[0], proxyAPort, true);
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[0], proxyAPort,
+ true);
dns.assertRequests(proxyAHost);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[0], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[0], proxyAPort,
false);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[1], proxyAPort, true);
- assertConnection(routeSelector.next(), address, proxyA, dns.inetAddresses[1], proxyAPort,
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[1], proxyAPort,
+ true);
+ assertConnection(routeSelector.next("GET"), address, proxyA, dns.inetAddresses[1], proxyAPort,
false);
// Proxy B
dns.inetAddresses = makeFakeAddresses(254, 2);
- assertConnection(routeSelector.next(), address, proxyB, dns.inetAddresses[0], proxyBPort, true);
+ assertConnection(routeSelector.next("GET"), address, proxyB, dns.inetAddresses[0], proxyBPort,
+ true);
dns.assertRequests(proxyBHost);
- assertConnection(routeSelector.next(), address, proxyB, dns.inetAddresses[0], proxyBPort,
+ assertConnection(routeSelector.next("GET"), address, proxyB, dns.inetAddresses[0], proxyBPort,
false);
- assertConnection(routeSelector.next(), address, proxyB, dns.inetAddresses[1], proxyBPort, true);
- assertConnection(routeSelector.next(), address, proxyB, dns.inetAddresses[1], proxyBPort,
+ assertConnection(routeSelector.next("GET"), address, proxyB, dns.inetAddresses[1], proxyBPort,
+ true);
+ assertConnection(routeSelector.next("GET"), address, proxyB, dns.inetAddresses[1], proxyBPort,
false);
// Origin
dns.inetAddresses = makeFakeAddresses(253, 2);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, true);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ true);
dns.assertRequests(uriHost);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[0], uriPort, false);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[1], uriPort, true);
- assertConnection(routeSelector.next(), address, NO_PROXY, dns.inetAddresses[1], uriPort, false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[0], uriPort,
+ false);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[1], uriPort,
+ true);
+ assertConnection(routeSelector.next("GET"), address, NO_PROXY, dns.inetAddresses[1], uriPort,
+ false);
assertFalse(routeSelector.hasNext());
}
@@ -350,7 +368,7 @@ public final class RouteSelectorTest {
// Extract the regular sequence of routes from selector.
List<Connection> regularRoutes = new ArrayList<Connection>();
while (routeSelector.hasNext()) {
- regularRoutes.add(routeSelector.next());
+ regularRoutes.add(routeSelector.next("GET"));
}
// Check that we do indeed have more than one route.
@@ -362,7 +380,7 @@ public final class RouteSelectorTest {
List<Connection> routesWithFailedRoute = new ArrayList<Connection>();
while (routeSelector.hasNext()) {
- routesWithFailedRoute.add(routeSelector.next());
+ routesWithFailedRoute.add(routeSelector.next("GET"));
}
assertEquals(regularRoutes.get(0).getRoute(),
diff --git a/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java b/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java
index 29b5cab..5abe477 100644
--- a/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java
+++ b/src/test/java/com/squareup/okhttp/internal/http/URLConnectionTest.java
@@ -2282,7 +2282,7 @@ public final class URLConnectionTest {
}
// This test is ignored because we don't (yet) reliably recover for large request bodies.
- @Test @Ignore public void postFailsWithBufferedRequestForLargeRequest() throws Exception {
+ @Test public void postFailsWithBufferedRequestForLargeRequest() throws Exception {
reusedConnectionFailsWithPost(TransferKind.END_OF_STREAM, 16384);
}
@@ -2290,8 +2290,7 @@ public final class URLConnectionTest {
reusedConnectionFailsWithPost(TransferKind.CHUNKED, 1024);
}
- // This test is ignored because we don't (yet) reliably recover for large request bodies.
- @Test @Ignore public void postFailsWithChunkedRequestForLargeRequest() throws Exception {
+ @Test public void postFailsWithChunkedRequestForLargeRequest() throws Exception {
reusedConnectionFailsWithPost(TransferKind.CHUNKED, 16384);
}
@@ -2299,8 +2298,7 @@ public final class URLConnectionTest {
reusedConnectionFailsWithPost(TransferKind.FIXED_LENGTH, 1024);
}
- // This test is ignored because we don't (yet) reliably recover for large request bodies.
- @Test @Ignore public void postFailsWithFixedLengthRequestForLargeRequest() throws Exception {
+ @Test public void postFailsWithFixedLengthRequestForLargeRequest() throws Exception {
reusedConnectionFailsWithPost(TransferKind.FIXED_LENGTH, 16384);
}
diff --git a/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java b/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java
index 5970088..e17a120 100644
--- a/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java
+++ b/src/test/java/com/squareup/okhttp/internal/spdy/HttpOverSpdyTest.java
@@ -90,12 +90,14 @@ public final class HttpOverSpdyTest {
}
@Test public void get() throws Exception {
- MockResponse response = new MockResponse().setBody("ABCDE");
+ MockResponse response = new MockResponse().setBody("ABCDE").setStatus("HTTP/1.1 200 Sweet");
server.enqueue(response);
server.play();
HttpURLConnection connection = client.open(server.getUrl("/foo"));
assertContent("ABCDE", connection, Integer.MAX_VALUE);
+ assertEquals(200, connection.getResponseCode());
+ assertEquals("Sweet", connection.getResponseMessage());
RecordedRequest request = server.takeRequest();
assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
@@ -211,6 +213,23 @@ public final class HttpOverSpdyTest {
assertEquals(2, cache.getHitCount());
}
+ @Test public void conditionalCache() throws IOException {
+ client.setResponseCache(cache);
+
+ server.enqueue(new MockResponse().addHeader("ETag: v1").setBody("A"));
+ server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_NOT_MODIFIED));
+ server.play();
+
+ assertContent("A", client.open(server.getUrl("/")), Integer.MAX_VALUE);
+ assertEquals(1, cache.getRequestCount());
+ assertEquals(1, cache.getNetworkCount());
+ assertEquals(0, cache.getHitCount());
+ assertContent("A", client.open(server.getUrl("/")), Integer.MAX_VALUE);
+ assertEquals(2, cache.getRequestCount());
+ assertEquals(2, cache.getNetworkCount());
+ assertEquals(1, cache.getHitCount());
+ }
+
@Test public void acceptAndTransmitCookies() throws Exception {
CookieManager cookieManager = new CookieManager();
client.setCookieHandler(cookieManager);