Skip to content

Commit 5468a73

Browse files
committed
Merge pull request square#972 from square/jwilson_0628_move_connect
Move connect to be closer to connection.
2 parents 2cf3885 + 7bb06e7 commit 5468a73

File tree

8 files changed

+250
-266
lines changed

8 files changed

+250
-266
lines changed

okhttp-tests/src/test/java/com/squareup/okhttp/OkHttpClientTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,14 @@ public final class OkHttpClientTest {
108108

109109
// Values should be non-null.
110110
OkHttpClient a = client.clone().copyWithDefaults();
111-
assertNotNull(a.getRoutesDatabase());
111+
assertNotNull(a.routeDatabase());
112112
assertNotNull(a.getDispatcher());
113113
assertNotNull(a.getConnectionPool());
114114
assertNotNull(a.getSslSocketFactory());
115115

116116
// Multiple clients share the instances.
117117
OkHttpClient b = client.clone().copyWithDefaults();
118-
assertSame(a.getRoutesDatabase(), b.getRoutesDatabase());
118+
assertSame(a.routeDatabase(), b.routeDatabase());
119119
assertSame(a.getDispatcher(), b.getDispatcher());
120120
assertSame(a.getConnectionPool(), b.getConnectionPool());
121121
assertSame(a.getSslSocketFactory(), b.getSslSocketFactory());

okhttp-tests/src/test/java/com/squareup/okhttp/internal/http/RouteSelectorTest.java

Lines changed: 134 additions & 138 deletions
Large diffs are not rendered by default.

okhttp/src/main/java/com/squareup/okhttp/Address.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import com.squareup.okhttp.internal.Util;
1919
import java.net.Proxy;
20-
import java.net.UnknownHostException;
2120
import java.util.List;
2221
import javax.net.SocketFactory;
2322
import javax.net.ssl.HostnameVerifier;
@@ -47,8 +46,7 @@ public final class Address {
4746

4847
public Address(String uriHost, int uriPort, SocketFactory socketFactory,
4948
SSLSocketFactory sslSocketFactory, HostnameVerifier hostnameVerifier,
50-
Authenticator authenticator, Proxy proxy, List<Protocol> protocols)
51-
throws UnknownHostException {
49+
Authenticator authenticator, Proxy proxy, List<Protocol> protocols) {
5250
if (uriHost == null) throw new NullPointerException("uriHost == null");
5351
if (uriPort <= 0) throw new IllegalArgumentException("uriPort <= 0: " + uriPort);
5452
if (authenticator == null) throw new IllegalArgumentException("authenticator == null");

okhttp/src/main/java/com/squareup/okhttp/Connection.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import java.net.URL;
3131
import javax.net.ssl.SSLSocket;
3232

33+
import static com.squareup.okhttp.internal.Util.getDefaultPort;
34+
import static com.squareup.okhttp.internal.Util.getEffectivePort;
3335
import static java.net.HttpURLConnection.HTTP_OK;
3436
import static java.net.HttpURLConnection.HTTP_PROXY_AUTH;
3537

@@ -155,6 +157,59 @@ void connect(int connectTimeout, int readTimeout, int writeTimeout, Request tunn
155157
connected = true;
156158
}
157159

160+
/**
161+
* Connects this connection if it isn't already. This creates tunnels, shares
162+
* the connection with the connection pool, and configures timeouts.
163+
*/
164+
void connectAndSetOwner(OkHttpClient client, Object owner, Request request) throws IOException {
165+
setOwner(owner);
166+
167+
if (!isConnected()) {
168+
Request tunnelRequest = tunnelRequest(request);
169+
connect(client.getConnectTimeout(), client.getReadTimeout(),
170+
client.getWriteTimeout(), tunnelRequest);
171+
if (isSpdy()) {
172+
client.getConnectionPool().share(this);
173+
}
174+
client.routeDatabase().connected(getRoute());
175+
}
176+
177+
setTimeouts(client.getReadTimeout(), client.getWriteTimeout());
178+
}
179+
180+
/**
181+
* Returns a request that creates a TLS tunnel via an HTTP proxy, or null if
182+
* no tunnel is necessary. Everything in the tunnel request is sent
183+
* unencrypted to the proxy server, so tunnels include only the minimum set of
184+
* headers. This avoids sending potentially sensitive data like HTTP cookies
185+
* to the proxy unencrypted.
186+
*/
187+
private Request tunnelRequest(Request request) throws IOException {
188+
if (!route.requiresTunnel()) return null;
189+
190+
String host = request.url().getHost();
191+
int port = getEffectivePort(request.url());
192+
String authority = (port == getDefaultPort("https")) ? host : (host + ":" + port);
193+
Request.Builder result = new Request.Builder()
194+
.url(new URL("https", host, port, "/"))
195+
.header("Host", authority)
196+
.header("Proxy-Connection", "Keep-Alive"); // For HTTP/1.0 proxies like Squid.
197+
198+
// Copy over the User-Agent header if it exists.
199+
String userAgent = request.header("User-Agent");
200+
if (userAgent != null) {
201+
result.header("User-Agent", userAgent);
202+
}
203+
204+
// Copy over the Proxy-Authorization header if it exists.
205+
String proxyAuthorization = request.header("Proxy-Authorization");
206+
if (proxyAuthorization != null) {
207+
result.header("Proxy-Authorization", proxyAuthorization);
208+
}
209+
210+
return result.build();
211+
}
212+
158213
/**
159214
* Create an {@code SSLSocket} and perform the TLS handshake and certificate
160215
* validation.

okhttp/src/main/java/com/squareup/okhttp/OkHttpClient.java

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ public final class OkHttpClient implements Cloneable {
6767
return connection.recycleCount();
6868
}
6969

70-
@Override public Object getOwner(Connection connection) {
71-
return connection.getOwner();
72-
}
73-
7470
@Override public void setProtocol(Connection connection, Protocol protocol) {
7571
connection.setProtocol(protocol);
7672
}
@@ -79,24 +75,6 @@ public final class OkHttpClient implements Cloneable {
7975
connection.setOwner(httpEngine);
8076
}
8177

82-
@Override public void connect(Connection connection, int connectTimeout, int readTimeout,
83-
int writeTimeout, Request request) throws IOException {
84-
connection.connect(connectTimeout, readTimeout, writeTimeout, request);
85-
}
86-
87-
@Override public boolean isConnected(Connection connection) {
88-
return connection.isConnected();
89-
}
90-
91-
@Override public boolean isSpdy(Connection connection) {
92-
return connection.isSpdy();
93-
}
94-
95-
@Override public void setTimeouts(Connection connection, int readTimeout, int writeTimeout)
96-
throws IOException {
97-
connection.setTimeouts(readTimeout, writeTimeout);
98-
}
99-
10078
@Override public boolean isReadable(Connection pooled) {
10179
return pooled.isReadable();
10280
}
@@ -117,13 +95,14 @@ public final class OkHttpClient implements Cloneable {
11795
pool.recycle(connection);
11896
}
11997

120-
@Override public void share(ConnectionPool connectionPool, Connection connection) {
121-
connectionPool.share(connection);
122-
}
123-
12498
@Override public RouteDatabase routeDatabase(OkHttpClient client) {
12599
return client.routeDatabase;
126100
}
101+
102+
@Override public void connectAndSetOwner(OkHttpClient client, Connection connection,
103+
HttpEngine owner, Request request) throws IOException {
104+
connection.connectAndSetOwner(client, owner, request);
105+
}
127106
};
128107
}
129108

@@ -385,7 +364,7 @@ public boolean getFollowRedirects() {
385364
return followRedirects;
386365
}
387366

388-
RouteDatabase getRoutesDatabase() {
367+
RouteDatabase routeDatabase() {
389368
return routeDatabase;
390369
}
391370

okhttp/src/main/java/com/squareup/okhttp/internal/Internal.java

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,10 @@ public abstract Transport newTransport(Connection connection, HttpEngine httpEng
4242

4343
public abstract int recycleCount(Connection connection);
4444

45-
public abstract Object getOwner(Connection connection);
46-
4745
public abstract void setProtocol(Connection connection, Protocol protocol);
4846

4947
public abstract void setOwner(Connection connection, HttpEngine httpEngine);
5048

51-
public abstract void connect(Connection connection,
52-
int connectTimeout, int readTimeout, int writeTimeout, Request request) throws IOException;
53-
54-
public abstract boolean isConnected(Connection connection);
55-
56-
public abstract boolean isSpdy(Connection connection);
57-
58-
public abstract void setTimeouts(Connection connection, int readTimeout, int writeTimeout)
59-
throws IOException;
60-
6149
public abstract boolean isReadable(Connection pooled);
6250

6351
public abstract void addLine(Headers.Builder builder, String line);
@@ -68,7 +56,8 @@ public abstract void setTimeouts(Connection connection, int readTimeout, int wri
6856

6957
public abstract void recycle(ConnectionPool pool, Connection connection);
7058

71-
public abstract void share(ConnectionPool connectionPool, Connection connection);
72-
7359
public abstract RouteDatabase routeDatabase(OkHttpClient client);
60+
61+
public abstract void connectAndSetOwner(OkHttpClient client, Connection connection,
62+
HttpEngine owner, Request request) throws IOException;
7463
}

okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpEngine.java

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
package com.squareup.okhttp.internal.http;
1919

20-
import com.squareup.okhttp.Address;
2120
import com.squareup.okhttp.Connection;
2221
import com.squareup.okhttp.Headers;
2322
import com.squareup.okhttp.MediaType;
@@ -38,14 +37,11 @@
3837
import java.net.ProtocolException;
3938
import java.net.Proxy;
4039
import java.net.URL;
41-
import java.net.UnknownHostException;
4240
import java.security.cert.CertificateException;
4341
import java.util.Date;
4442
import java.util.List;
4543
import java.util.Map;
46-
import javax.net.ssl.HostnameVerifier;
4744
import javax.net.ssl.SSLHandshakeException;
48-
import javax.net.ssl.SSLSocketFactory;
4945
import okio.Buffer;
5046
import okio.BufferedSink;
5147
import okio.BufferedSource;
@@ -241,11 +237,6 @@ public void sendRequest() throws IOException {
241237
connect(networkRequest);
242238
}
243239

244-
// Blow up if we aren't the current owner of the connection.
245-
if (Internal.instance.getOwner(connection) != this && !Internal.instance.isSpdy(connection)) {
246-
throw new AssertionError();
247-
}
248-
249240
transport = Internal.instance.newTransport(connection, this);
250241

251242
// Create a request body if we don't have one already. We'll already have
@@ -297,35 +288,10 @@ private void connect(Request request) throws IOException {
297288
if (connection != null) throw new IllegalStateException();
298289

299290
if (routeSelector == null) {
300-
String uriHost = request.url().getHost();
301-
if (uriHost == null || uriHost.length() == 0) {
302-
throw new UnknownHostException(request.url().toString());
303-
}
304-
SSLSocketFactory sslSocketFactory = null;
305-
HostnameVerifier hostnameVerifier = null;
306-
if (request.isHttps()) {
307-
sslSocketFactory = client.getSslSocketFactory();
308-
hostnameVerifier = client.getHostnameVerifier();
309-
}
310-
Address address = new Address(uriHost, getEffectivePort(request.url()),
311-
client.getSocketFactory(), sslSocketFactory, hostnameVerifier, client.getAuthenticator(),
312-
client.getProxy(), client.getProtocols());
313-
routeSelector = new RouteSelector(address, request.uri(), client.getProxySelector(),
314-
client.getConnectionPool(), Dns.DEFAULT, Internal.instance.routeDatabase(client));
291+
routeSelector = RouteSelector.get(request, client, Dns.DEFAULT);
315292
}
316293

317-
connection = routeSelector.next(request.method());
318-
Internal.instance.setOwner(connection, this);
319-
320-
if (!Internal.instance.isConnected(connection)) {
321-
Internal.instance.connect(connection, client.getConnectTimeout(), client.getReadTimeout(),
322-
client.getWriteTimeout(), tunnelRequest(connection, request));
323-
if (Internal.instance.isSpdy(connection)) {
324-
Internal.instance.share(client.getConnectionPool(), connection);
325-
}
326-
Internal.instance.routeDatabase(client).connected(connection.getRoute());
327-
}
328-
Internal.instance.setTimeouts(connection, client.getReadTimeout(), client.getWriteTimeout());
294+
connection = routeSelector.next(this);
329295
route = connection.getRoute();
330296
}
331297

@@ -780,39 +746,6 @@ private static Headers combine(Headers cachedHeaders, Headers networkHeaders) th
780746
return result.build();
781747
}
782748

783-
/**
784-
* Returns a request that creates a TLS tunnel via an HTTP proxy, or null if
785-
* no tunnel is necessary. Everything in the tunnel request is sent
786-
* unencrypted to the proxy server, so tunnels include only the minimum set of
787-
* headers. This avoids sending potentially sensitive data like HTTP cookies
788-
* to the proxy unencrypted.
789-
*/
790-
private Request tunnelRequest(Connection connection, Request request) throws IOException {
791-
if (!connection.getRoute().requiresTunnel()) return null;
792-
793-
String host = request.url().getHost();
794-
int port = getEffectivePort(request.url());
795-
String authority = (port == getDefaultPort("https")) ? host : (host + ":" + port);
796-
Request.Builder result = new Request.Builder()
797-
.url(new URL("https", host, port, "/"))
798-
.header("Host", authority)
799-
.header("Proxy-Connection", "Keep-Alive"); // For HTTP/1.0 proxies like Squid.
800-
801-
// Copy over the User-Agent header if it exists.
802-
String userAgent = request.header("User-Agent");
803-
if (userAgent != null) {
804-
result.header("User-Agent", userAgent);
805-
}
806-
807-
// Copy over the Proxy-Authorization header if it exists.
808-
String proxyAuthorization = request.header("Proxy-Authorization");
809-
if (proxyAuthorization != null) {
810-
result.header("Proxy-Authorization", proxyAuthorization);
811-
}
812-
813-
return result.build();
814-
}
815-
816749
public void receiveHeaders(Headers headers) throws IOException {
817750
CookieHandler cookieHandler = client.getCookieHandler();
818751
if (cookieHandler != null) {

0 commit comments

Comments
 (0)