繁体   English   中英

如何通过 Java JDK HttpClient 使用 socks 代理

[英]How to use a socks proxy with Java JDK HttpClient

注意:这不是https 代理与 JDK11 客户端的副本,它是关于 HTTP 代理的。 我的问题是关于 socks 代理的,它需要不同的解决方案。 它也不是我如何对 SOCKS 代理使用 HttpClient-4.5 的副本? ,这是关于 Apache HttpClient 而不是 JDK HttpClient。

如何将 socks 5 代理与java.net.http.HttpClient一起使用?

我尝试了下面的代码,但它导致以下异常:

Exception in thread "main" java.io.IOException: HTTP/1.1 header parser received no bytes
    at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:586)

代码:

import java.io.IOException;
import java.net.*;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Collections;
import java.util.List;

public class ProxyApp {
    public static void main(String[] args) throws Exception {
        run1();
    }

    public static void run1() throws Exception {
        HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_1_1)
                .proxy(ProxySelector.of(new InetSocketAddress("localhost", 8181)))
                .build();

        HttpRequest request = HttpRequest
                .newBuilder(new URI("http://example.org/"))
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        String verificationText = "Example Domain";
        // Should print "true" otherwise the request failed
        System.out.println(response.body().contains(verificationText));
    }
}

问题是由java.net.ProxySelector.of(InetSocketAddress)引起的,它没有记录它创建的代理类型。 代理可以是 web (http) 代理或 socks 代理。 ProxySelector.of()的源码显示它创建了一个私有StaticProxySelector object,它创建了一个web代理( Proxy.Type.HTTP Proxy.Type.SOCKS

所以解决方案是创建自己的 ProxySelector。 这显示在下面的解决方案中。

import java.io.IOException;
import java.net.*;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Collections;
import java.util.List;

public class ProxyApp {
    public static void main(String[] args) throws Exception {
        run2();
    }

    public static void run2() throws Exception {
        ProxySelector proxySelector = new ProxySelector() {
            private List<Proxy> proxies;

            {
                Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("localhost", 8181));
                proxies = Collections.singletonList(proxy);
            }

            @Override
            public List<Proxy> select(URI uri) {
                return proxies;
            }

            @Override
            public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
                throw new RuntimeException(ioe);
            }
        };

        HttpClient client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_1_1)
                .proxy(proxySelector)
                .build();

        HttpRequest request = HttpRequest
                .newBuilder(new URI("http://example.org/"))
                .build();
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        String verificationText = "Example Domain";
        // Should print "true" otherwise the request failed
        System.out.println(response.body().contains(verificationText));
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM