ProxySelector 将 URL 的方案从 https:// 更改为 socket://

2023-12-03

我需要访问 Facebook,但所有传出通信都在我们的服务器上被阻止,因此我必须使用代理。

我用以下方法初始化代理:

ProxySelector.setDefault(new ConfigurableProxySelector(mapping));

代理类型是 HTTP,代理主机和端口正在工作(通过简单的 wget 测试确认)。

我正在尝试这样做:

HttpClient httpClient = new HttpClient();
HttpMethod method = new GetMethod("https://graph.facebook.com:443");

int status = httpClient.executeMethod(method);

现在,在我的 ConfigurableProxySelector 类中,我有 select 方法,在该方法上有断点:

public List<Proxy> select(URI uri) {
...
}

因此,我使用 HttpClient 发出一个请求,该请求应该被代理,并且代码在 ConfigurableProxySelector 中的 select() 方法中的断点处停止。

但奇怪的是 uri.scheme = "socket" 和 .toString() 给出的是 "socket://graph.facebook.com:443" 而不是 "https://graph.facebook.com:443"。

因为 ProxySelector 有“https://”的映射,但没有“socket://”的映射,所以它找不到它,并以“连接被拒绝”结束。奇怪的是,在执行以“连接被拒绝”结束之前,select()方法被调用了4次。

任何帮助,将不胜感激。


Apache HTTP Client 3.1 本身不会支持从默认 ProxySelector 或用户实现返回的 HTTP 代理。

ProxySelector 快速总结

ProxySelector 是一个服务类,它根据其方案为给定 URL 选择并返回合适的代理。例如,请求http://somehost如果已定义,将尝试提供 HTTP 代理。默认的ProxySelector可以在运行时使用系统属性进行配置,例如http.proxyHost and http.proxyPort.

HTTPUrl连接

HTTPUrlConnection 的实例将多次检查默认的 ProxySelector:第一次选择http or https,然后当它构建原始 tcp 套接字时,使用socket方案。 SOCKS 代理可用于代理原始 tcp 套接字,但在企业环境中并不常见,因此原始 tcp 套接字通常不会接收代理。

HTTP 客户端 3.1

另一方面,HC 3.1 将永远不要检查默认的 ProxySelectorhttp/https schemes。不过,稍后它会检查socket最终构建原始套接字时的方案 - 这是您看到的请求。这意味着系统属性http.proxyHost and http.proxyPort是无效的。对于大多数只有 HTTP/HTTPS 代理的人来说,这显然并不理想。

要解决此问题,您有两个选择:在每个 HC 3.1 连接上定义代理或实施您自己的 HC 3.1 HTTPConnectionManager。

HTTP连接管理器

HTTPConnectionManager 负责为 HC 3.1 客户端建立连接。

可以扩展默认的 HC 3.1 HTTPConnectionManager,以便在以与 HTTPUrlConnection 相同的方式构建请求时从 ProxySelector(默认或自定义)查找合适的代理:

public class MyHTTPConnectionManager extends SimpleHttpConnectionManager {
@Override
public HttpConnection getConnectionWithTimeout(
        HostConfiguration hostConfiguration, long timeout) {
    HttpConnection hc = super.getConnectionWithTimeout(hostConfiguration, timeout);

    try {
        URI uri = new URI( hostConfiguration.getHostURL());
        List<Proxy> hostProxies =  ProxySelector.getDefault().select(uri);
        Proxy Proxy = hostProxies.get(0);

        InetSocketAddress sa = (InetSocketAddress) Proxy.address();
        hc.setProxyHost(sa.getHostName());
        hc.setProxyPort(sa.getPort());

    } catch (URISyntaxException e) {
        return hc;
    }   
    return hc;
}
}

然后,当您创建 HC 3.1 客户端时,使用新的连接管理器:

HttpClient client = new HttpClient(new MyHTTPConnectionManager() );
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ProxySelector 将 URL 的方案从 https:// 更改为 socket:// 的相关文章

  • python中的编码检测库[重复]

    这个问题在这里已经有答案了 这在某种程度上与我的问题有关here https stackoverflow com questions 2305997 unicodedecodeerror problem with mechanize 我处理
  • 如何创建仅接受字母数字字符的正则表达式? [复制]

    这个问题在这里已经有答案了 可能的重复 字母数字和下划线的正则表达式 https stackoverflow com questions 336210 regular expression for alphanumeric and unde
  • 如何从球衣服务端点发送实体列表?

    我正在从球衣服务器发送实体列表 在客户端 我试图获取这些实体列表 但它给了元帅例外 为什么它在元素名末尾添加 s 即 emps 而不是 emp XmlRootElement public class Emp Server side code
  • 图像在 3D 空间中绕 Y 轴旋转

    我有一个 BufferedImage 我想用 theta 角而不是仿射变换绕 Java 中的 Y 轴旋转图像 图片 旋转将如下图所示 矩形将是图像 我可以通过旋转图像的每个像素并绘制图像来做到这一点 因为我必须旋转很多图像 所以我认为这不是
  • bean 的 CDI @TransactionAttribute

    我正在尝试CDI在测试应用程序上 我有一个DAO它注入一个托管的容器JTA像这样的持久化上下文 public class TestDAO implements Serializable PersistenceContext private
  • Jboss EAP 7 - 如何从部署中排除隐式模块(javax.jms)?

    我没想到我会来到这里 但经过大量 Google 和 StackOverflow 搜索后 我来到了这里 这就是我的确切问题 https www linkedin com pulse tale two jars marco antonio al
  • 基于磁盘的 HashMap [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Java 是否有 或者是否有可用的库 允许我拥有基于磁盘的 HashMap 它不需要是原子的或任何东西
  • 如何在不冒 StackOverflowError 风险的情况下使用 CompletableFuture?

    我想遍历异步函数的搜索空间 我将逻辑编码如下 Assuming that a function maps a range of inputs to the same output value minimizes the input valu
  • 是否有适用于 Java 的 CalDAV 客户端库? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想使用 CalDAV 协议与我的日
  • java内存不足然后退出

    我有一个必须分析大文件的软件 限制输入或提供无限内存都不是一个选择 所以我必须忍受飞行的 OOME 因为 OOME 只杀死线程 所以我的软件运行在一些糟糕的状态 从外面看一切都很好 因为进程正在运行 但在内部却是脑死亡 我想拔掉它的插头 但
  • org.apache.poi 中的异常

    我试图编写一个可以读取和写入的程序 xlsx文件中 下面提供的代码旨在能够编写其第一个 Excel 程序 package excel reader import java io FileOutputStream import java io
  • 用二进制数、常规数字和格雷编码填充矩阵

    我有一个包含 1 s 或 0 s 的矩阵 用于创建二进制数 其宽度为n 对于 n 2 和 n 3 它看起来像 00 000 01 001 10 010 11 011 100 101 110 111 等等 现在我正在使用以下代码来生成它 in
  • 在 Hibernate 的 XML 配置文件中指定默认值

    我通过映射配置文件配置 Hibernate
  • Java泛型类型参数中的问号是什么意思? [复制]

    这个问题在这里已经有答案了 这是取自斯坦福解析器附带的一些示例的一小段代码 我已经用 Java 进行了大约 4 年的开发 但从未对这种风格的代码应该表示什么有非常深入的理解 List
  • 致命异常:OkHttp 调度程序

    我在 Android 应用程序中使用 OkHttp 库向天气 API 发出 Web 请求 我已经实现了我的代码 但在执行请求时遇到了致命异常 我也已经在我的清单中添加了互联网权限 MainActivity java private Curr
  • 如何预先填充 JFileChooser 将“文件名”?

    我打算用数据库中的名称填充 JFileChooser 但使用标准 JFileChooser 对话框进行加载 删除 保存和另存为 我想给用户留下这样的印象 他们正在处理文件系统 而在后端使用数据库来保存更改 用户不应该能够浏览到不同的目录进行
  • 为什么找不到 getservletcontext?

    我正在尝试使用getServletContext getRealPath 但我不断收到此错误 cannot find symbol symbol method getServletContext location interface jav
  • 使用 SimpleDateFormat、Java 进行错误的日期解析

    我需要使用日期模式 yyyy MM dd 解析输入字符串中的日期 如果日期采用任何其他格式 则抛出错误 这是我解析日期的代码 private void validateDate throws MyException Date parsedD
  • 不鼓励在Web应用程序中使用线程吗?

    我们与同事就在 Java 的 Web 应用程序中使用线程进行了激烈的讨论 他们的观点是 不建议在 Java Web 应用程序中使用线程 因为它们不受容器管理 一般来说 我对此表示同意 因为线程可能会干扰容器 但是 如果它不是 Java EE
  • Android NDK - 仅用 C/C++ 编写

    有没有一种可能的方法可以使用 C C 编写整个 NDK 应用程序 而无需像 hello jni 示例项目 HelloJni java 中那样的 Java 入门 类 以某种方式创建一个 HelloJni c 来执行相同的操作 从 Androi

随机推荐