Skip to content

Commit 9e12e21

Browse files
committed
AsyncSocketMiddleware: add support for CONNECT directive to proxy SSL connections.
1 parent dfd41ef commit 9e12e21

2 files changed

Lines changed: 76 additions & 6 deletions

File tree

AndroidAsync/src/com/koushikdutta/async/http/AsyncSSLSocketMiddleware.java

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
package com.koushikdutta.async.http;
22

3+
import android.text.TextUtils;
4+
5+
import com.koushikdutta.async.AsyncSSLException;
36
import com.koushikdutta.async.AsyncSSLSocketWrapper;
47
import com.koushikdutta.async.AsyncSocket;
8+
import com.koushikdutta.async.LineEmitter;
9+
import com.koushikdutta.async.Util;
10+
import com.koushikdutta.async.callback.CompletedCallback;
511
import com.koushikdutta.async.callback.ConnectCallback;
12+
import com.koushikdutta.async.http.libcore.RawHeaders;
613

714
import javax.net.ssl.HostnameVerifier;
815
import javax.net.ssl.SSLContext;
916
import javax.net.ssl.TrustManager;
17+
18+
import java.io.IOException;
1019
import java.net.URI;
1120

1221
public class AsyncSSLSocketMiddleware extends AsyncSocketMiddleware {
@@ -33,12 +42,70 @@ public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
3342
}
3443

3544
@Override
36-
protected ConnectCallback wrapCallback(final ConnectCallback callback, final URI uri, final int port) {
45+
protected ConnectCallback wrapCallback(final ConnectCallback callback, final URI uri, final int port, final boolean proxied) {
3746
return new ConnectCallback() {
3847
@Override
39-
public void onConnectCompleted(Exception ex, AsyncSocket socket) {
48+
public void onConnectCompleted(Exception ex, final AsyncSocket socket) {
4049
if (ex == null) {
41-
callback.onConnectCompleted(ex, new AsyncSSLSocketWrapper(socket, uri.getHost(), port, sslContext, trustManagers, hostnameVerifier, true));
50+
if (!proxied) {
51+
callback.onConnectCompleted(null, new AsyncSSLSocketWrapper(socket, uri.getHost(), port, sslContext, trustManagers, hostnameVerifier, true));
52+
}
53+
else {
54+
System.out.println("requsting SSL PROXY: " + uri.getHost());
55+
RawHeaders connect = new RawHeaders();
56+
connect.setStatusLine(String.format("CONNECT %s:%s HTTP/1.1", uri.getHost(), port));
57+
Util.writeAll(socket, connect.toHeaderString().getBytes(), new CompletedCallback() {
58+
@Override
59+
public void onCompleted(Exception ex) {
60+
if (ex != null) {
61+
callback.onConnectCompleted(ex, socket);
62+
return;
63+
}
64+
65+
LineEmitter liner = new LineEmitter();
66+
liner.setLineCallback(new LineEmitter.StringCallback() {
67+
String statusLine;
68+
@Override
69+
public void onStringAvailable(String s) {
70+
if (statusLine == null) {
71+
statusLine = s;
72+
if (statusLine.length() > 128 || !statusLine.contains("200")) {
73+
socket.setDataCallback(null);
74+
socket.setEndCallback(null);
75+
callback.onConnectCompleted(new IOException("non 200 status line"), socket);
76+
}
77+
}
78+
else {
79+
socket.setDataCallback(null);
80+
socket.setEndCallback(null);
81+
if (TextUtils.isEmpty(s.trim())) {
82+
callback.onConnectCompleted(null, new AsyncSSLSocketWrapper(socket, uri.getHost(), port, sslContext, trustManagers, hostnameVerifier, true));
83+
}
84+
else {
85+
callback.onConnectCompleted(new IOException("unknown second status line"), socket);
86+
}
87+
}
88+
}
89+
});
90+
91+
socket.setDataCallback(liner);
92+
93+
socket.setEndCallback(new CompletedCallback() {
94+
@Override
95+
public void onCompleted(Exception ex) {
96+
if (!socket.isOpen())
97+
ex = new IOException("socket closed before proxy connect response");
98+
callback.onConnectCompleted(ex, socket);
99+
}
100+
});
101+
102+
// AsyncSocket wrapper = socket;
103+
// if (ex == null)
104+
// wrapper = new AsyncSSLSocketWrapper(socket, uri.getHost(), port, sslContext, trustManagers, hostnameVerifier, true);
105+
// callback.onConnectCompleted(ex, wrapper);
106+
}
107+
});
108+
}
42109
}
43110
else {
44111
callback.onConnectCompleted(ex, socket);

AndroidAsync/src/com/koushikdutta/async/http/AsyncSocketMiddleware.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public AsyncSocketMiddleware(AsyncHttpClient client) {
5151

5252
AsyncHttpClient mClient;
5353

54-
protected ConnectCallback wrapCallback(ConnectCallback callback, URI uri, int port) {
54+
protected ConnectCallback wrapCallback(ConnectCallback callback, URI uri, int port, boolean proxied) {
5555
return callback;
5656
}
5757

@@ -166,23 +166,26 @@ public Cancellable getSocket(final GetSocketData data) {
166166
data.request.logd("Connecting socket");
167167
String unresolvedHost;
168168
int unresolvedPort;
169+
boolean proxied = false;
169170
if (data.request.getProxyHost() != null) {
170171
unresolvedHost = data.request.getProxyHost();
171172
unresolvedPort = data.request.getProxyPort();
172173
// set the host and port explicitly for proxied connections
173174
data.request.getHeaders().getHeaders().setStatusLine(data.request.getProxyRequestLine().toString());
175+
proxied = true;
174176
}
175177
else if (proxyHost != null) {
176178
unresolvedHost = proxyHost;
177179
unresolvedPort = proxyPort;
178180
// set the host and port explicitly for proxied connections
179181
data.request.getHeaders().getHeaders().setStatusLine(data.request.getProxyRequestLine().toString());
182+
proxied = true;
180183
}
181184
else {
182185
unresolvedHost = uri.getHost();
183186
unresolvedPort = port;
184187
}
185-
return mClient.getServer().connectSocket(unresolvedHost, unresolvedPort, wrapCallback(data.connectCallback, uri, port));
188+
return mClient.getServer().connectSocket(unresolvedHost, unresolvedPort, wrapCallback(data.connectCallback, uri, port, proxied));
186189
}
187190

188191
// try to connect to everything...
@@ -241,7 +244,7 @@ public void onConnectCompleted(Exception ex, AsyncSocket socket) {
241244
data.connectCallback.onConnectCompleted(ex, socket);
242245
}
243246
}
244-
}, uri, port));
247+
}, uri, port, false));
245248
}
246249
});
247250
}

0 commit comments

Comments
 (0)