HttpClient 使用socks代理
2012/05/13
by Rover12421
0 comments
HttpClient使用HTTP代理很简单,但是用socks代理就稍微复杂点。下面是参考HttpClient官方的例子,在其基础上增加了代理验证。
import java.io.IOException;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;public class SocksProxy {
public static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
try {
Authenticator.setDefault(new SocksAuthenticator("user", "pwd"));
httpclient.getParams().setParameter("socks.host", "socksHost");
httpclient.getParams().setParameter("socks.port", sockPort);
httpclient.getConnectionManager().getSchemeRegistry().register(
new Scheme("http", 80, new SocksSchemeSocketFactory()));
HttpGet get = new HttpGet("http://city.ip138.com/city.asp");
HttpResponse rsp = httpclient.execute(get);
HttpEntity entity = rsp.getEntity();
System.out.println(rsp.getStatusLine());
Header[] headers = rsp.getAllHeaders();
for (int i = 0; i < headers.length; i++) {
System.out.println(headers[i]);
}
System.out.println("——————————");
if (entity != null) {
System.out.println(EntityUtils.toString(entity, "gb2312"));
}
} finally {
httpclient.getConnectionManager().shutdown();
}
}
static class SocksSchemeSocketFactory implements SchemeSocketFactory {@Override
public Socket connectSocket(final Socket socket, final InetSocketAddress remoteAddress,
final InetSocketAddress localAddress, final HttpParams params) throws IOException,
UnknownHostException, ConnectTimeoutException {
// TODO Auto-generated method stub
if (remoteAddress == null) {
throw new IllegalArgumentException("Remote address may not be null");
}
if (params == null) {
throw new IllegalArgumentException("HTTP parameters may not be null");
}
Socket sock;
if (socket != null) {
sock = socket;
} else {
sock = createSocket(params);
}
if (localAddress != null) {
sock.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params));
sock.bind(localAddress);
}
int timeout = HttpConnectionParams.getConnectionTimeout(params);
try {
sock.connect(remoteAddress, timeout);
} catch (SocketTimeoutException ex) {
throw new ConnectTimeoutException("Connect to " + remoteAddress.getHostName() + "/" + remoteAddress.getAddress() + " time out");
}
return sock;
}@Override
public Socket createSocket(final HttpParams params) throws IOException {
// TODO Auto-generated method stub
if (params == null) {
throw new IllegalArgumentException("Http parameters may not be null");
}
String proxyHost = (String) params.getParameter("socks.host");
Integer proxyPort = (Integer) params.getParameter("socks.port");
InetSocketAddress socksAddr = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksAddr);
return new Socket(proxy);
}@Override
public boolean isSecure(final Socket sock) throws IllegalArgumentException {
// TODO Auto-generated method stub
return false;
}
}
static class SocksAuthenticator extends Authenticator {
private String username;
private String password;public SocksAuthenticator(final String user, final String pass) {
username = user;
password = pass;
}protected PasswordAuthentication getPasswordAuthentication() {
if (username != null && password != null) {
return new PasswordAuthentication(username, password.toCharArray());
}
else {
return null;
}
}
}
}
Socks验证使用的方式和使用Java全局的Socks代理验证方式是一样的。
