1
0
mirror of https://github.com/square/okhttp.git synced 2026-01-27 04:22:07 +03:00

Merge pull request #103 from square/jwilson/proxy_double_duty

Don't make the 'proxy' field do double-duty.
This commit is contained in:
Marcelo Cortes
2013-02-02 07:08:59 -08:00
3 changed files with 79 additions and 44 deletions

View File

@@ -272,9 +272,8 @@ public class HttpEngine {
if (uriHost == null) {
throw new UnknownHostException(uri.toString());
}
Address address =
new Address(uriHost, getEffectivePort(uri), getSslSocketFactory(), getHostnameVerifier(),
policy.getProxy());
Address address = new Address(uriHost, getEffectivePort(uri), getSslSocketFactory(),
getHostnameVerifier(), policy.requestedProxy);
routeSelector =
new RouteSelector(address, uri, policy.proxySelector, policy.connectionPool, Dns.DEFAULT);
}
@@ -284,10 +283,8 @@ public class HttpEngine {
policy.connectionPool.maybeShare(connection);
}
connected(connection);
Proxy proxy = connection.getProxy();
if (proxy != null) {
policy.setProxy(proxy);
// Add the authority to the request line when we're using a proxy.
if (connection.getProxy() != policy.requestedProxy) {
// Update the request line if the proxy changed; it may need a host name.
requestHeaders.getHeaders().setRequestLine(getRequestLine());
}
}
@@ -574,7 +571,9 @@ public class HttpEngine {
* full URL, even if a proxy is in use.
*/
protected boolean includeAuthorityInRequestLine() {
return policy.usingProxy();
return connection == null
? policy.usingProxy() // A proxy was requested.
: connection.getProxy().type() == Proxy.Type.HTTP; // A proxy was selected.
}
/**

View File

@@ -65,7 +65,9 @@ public class HttpURLConnectionImpl extends HttpURLConnection {
private final int defaultPort;
private Proxy proxy;
/** The proxy requested by the client, or null for a proxy to be selected automatically. */
final Proxy requestedProxy;
final ProxySelector proxySelector;
final CookieHandler cookieHandler;
final ResponseCache responseCache;
@@ -82,7 +84,7 @@ public class HttpURLConnectionImpl extends HttpURLConnection {
CookieHandler cookieHandler, ResponseCache responseCache, ConnectionPool connectionPool) {
super(url);
this.defaultPort = defaultPort;
this.proxy = proxy;
this.requestedProxy = proxy;
this.proxySelector = proxySelector;
this.cookieHandler = cookieHandler;
this.responseCache = responseCache;
@@ -214,18 +216,14 @@ public class HttpURLConnectionImpl extends HttpURLConnection {
}
@Override public final Permission getPermission() throws IOException {
String connectToAddress = getConnectToHost() + ":" + getConnectToPort();
return new SocketPermission(connectToAddress, "connect, resolve");
}
private String getConnectToHost() {
return usingProxy() ? ((InetSocketAddress) proxy.address()).getHostName() : getURL().getHost();
}
private int getConnectToPort() {
int hostPort =
usingProxy() ? ((InetSocketAddress) proxy.address()).getPort() : getURL().getPort();
return hostPort < 0 ? getDefaultPort() : hostPort;
String hostName = getURL().getHost();
int hostPort = Util.getEffectivePort(getURL());
if (usingProxy()) {
InetSocketAddress proxyAddress = (InetSocketAddress) requestedProxy.address();
hostName = proxyAddress.getHostName();
hostPort = proxyAddress.getPort();
}
return new SocketPermission(hostName + ":" + hostPort, "connect, resolve");
}
@Override public final String getRequestProperty(String field) {
@@ -385,15 +383,18 @@ public class HttpURLConnectionImpl extends HttpURLConnection {
* prepare for a follow up request.
*/
private Retry processResponseHeaders() throws IOException {
Proxy selectedProxy = httpEngine.connection != null
? httpEngine.connection.getProxy()
: requestedProxy;
switch (getResponseCode()) {
case HTTP_PROXY_AUTH:
if (!usingProxy()) {
if (selectedProxy.type() != Proxy.Type.HTTP) {
throw new ProtocolException("Received HTTP_PROXY_AUTH (407) code while not using proxy");
}
// fall-through
case HTTP_UNAUTHORIZED:
boolean credentialsFound = HttpAuthenticator.processAuthHeader(getResponseCode(),
httpEngine.getResponseHeaders().getHeaders(), rawRequestHeaders, proxy, url);
httpEngine.getResponseHeaders().getHeaders(), rawRequestHeaders, selectedProxy, url);
return credentialsFound ? Retry.SAME_CONNECTION : Retry.NONE;
case HTTP_MULT_CHOICE:
@@ -441,16 +442,8 @@ public class HttpURLConnectionImpl extends HttpURLConnection {
return chunkLength;
}
final Proxy getProxy() {
return proxy;
}
final void setProxy(Proxy proxy) {
this.proxy = proxy;
}
@Override public final boolean usingProxy() {
return (proxy != null && proxy.type() != Proxy.Type.DIRECT);
return (requestedProxy != null && requestedProxy.type() != Proxy.Type.DIRECT);
}
@Override public String getResponseMessage() throws IOException {

View File

@@ -1557,8 +1557,24 @@ public final class URLConnectionTest {
}
@Test public void redirectToAnotherOriginServer() throws Exception {
MockWebServer server2 = new MockWebServer();
redirectToAnotherOriginServer(false);
}
@Test public void redirectToAnotherOriginServerWithHttps() throws Exception {
redirectToAnotherOriginServer(true);
}
private void redirectToAnotherOriginServer(boolean https) throws Exception {
server2 = new MockWebServer();
if (https) {
server.useHttps(sslContext.getSocketFactory(), false);
server2.useHttps(sslContext.getSocketFactory(), false);
client.setSSLSocketFactory(sslContext.getSocketFactory());
client.setHostnameVerifier(new RecordingHostnameVerifier());
}
server2.enqueue(new MockResponse().setBody("This is the 2nd server!"));
server2.enqueue(new MockResponse().setBody("This is the 2nd server, again!"));
server2.play();
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
@@ -1568,20 +1584,47 @@ public final class URLConnectionTest {
server.play();
URLConnection connection = client.open(server.getUrl("/"));
assertEquals("This is the 2nd server!",
readAscii(connection.getInputStream(), Integer.MAX_VALUE));
assertContent("This is the 2nd server!", connection);
assertEquals(server2.getUrl("/"), connection.getURL());
// make sure the first server was careful to recycle the connection
assertEquals("This is the first server again!",
readAscii(client.open(server.getUrl("/")).getInputStream(), Integer.MAX_VALUE));
assertContent("This is the first server again!", client.open(server.getUrl("/")));
assertContent("This is the 2nd server, again!", client.open(server2.getUrl("/")));
RecordedRequest first = server.takeRequest();
assertContains(first.getHeaders(), "Host: " + hostName + ":" + server.getPort());
RecordedRequest second = server2.takeRequest();
assertContains(second.getHeaders(), "Host: " + hostName + ":" + server2.getPort());
RecordedRequest third = server.takeRequest();
assertEquals("Expected connection reuse", 1, third.getSequenceNumber());
String server1Host = hostName + ":" + server.getPort();
String server2Host = hostName + ":" + server2.getPort();
assertContains(server.takeRequest().getHeaders(), "Host: " + server1Host);
assertContains(server2.takeRequest().getHeaders(), "Host: " + server2Host);
assertEquals("Expected connection reuse", 1, server.takeRequest().getSequenceNumber());
assertEquals("Expected connection reuse", 1, server2.takeRequest().getSequenceNumber());
}
@Test public void redirectWithProxySelector() throws Exception {
final List<URI> proxySelectionRequests = new ArrayList<URI>();
client.setProxySelector(new ProxySelector() {
@Override public List<Proxy> select(URI uri) {
proxySelectionRequests.add(uri);
MockWebServer proxyServer = (uri.getPort() == server.getPort()) ? server : server2;
return Arrays.asList(proxyServer.toProxyAddress());
}
@Override public void connectFailed(URI uri, SocketAddress address, IOException failure) {
throw new AssertionError();
}
});
server2 = new MockWebServer();
server2.enqueue(new MockResponse().setBody("This is the 2nd server!"));
server2.play();
server.enqueue(new MockResponse().setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
.addHeader("Location: " + server2.getUrl("/b").toString())
.setBody("This page has moved!"));
server.play();
assertContent("This is the 2nd server!", client.open(server.getUrl("/a")));
assertEquals(Arrays.asList(server.getUrl("/a").toURI(), server2.getUrl("/b").toURI()),
proxySelectionRequests);
server2.shutdown();
}