【问题标题】:Prevent unsolicited CONNECT method calls from HttpURLConnection防止来自 HttpURLConnection 的未经请求的 CONNECT 方法调用
【发布时间】:2016-01-27 00:44:38
【问题描述】:

我使用HttpURLConnection 的方式如下:

String strURL = "https://example.herokuapp.com";
Bitmap bmImage = null;
HttpURLConnection connection = null;
InputStream in = null;
showMessage(context.getString(R.string.message_preparing));
try {
    int timeoutMS = 15000;
    URL url = new URL(strURL);
    connection = (HttpURLConnection) url.openConnection();
    connection.setDoInput(true);
    connection.setConnectTimeout(timeoutMS);
    connection.setReadTimeout(timeoutMS);
    connection.connect();
    in = connection.getInputStream();
    BitmapFactory.Options options = new BitmapFactory.Options();
    bmImage = BitmapFactory.decodeStream(in, null, options);
} catch (Exception e) {
    e.printStackTrace();
} finally {
    if (connection != null)
        connection.disconnect();
    if (in != null) {
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

return bmImage;

这很好用,strURL 定义的 url 返回一个 bmp 图像,并且被解码以供上述代码使用。

但特别是对于一个用户,虽然代码可以正常获取 bmp 图像,但在服务器(heroku 的 node.js 服务器)上,显然他们的设备也在发送CONNECT 请求。该请求会自动以 503 响应被拒绝,因此这不是问题,并且 bmp 仍会发送到他们的设备,但我想知道为什么要发送那些 CONNECT 请求,以及如何发送阻止他们。除了GET 请求之外应该什么都没有?

我已经尝试this solution 来解决类似的问题,但这对我来说没有任何区别。

请注意,strURL 是一个 https 服务器,我使用的是HttpURLConnection(不是Https)——不确定这是否有任何意义。

我也不能 100% 确定 CONNECT 请求源自上述调用,但它们肯定与传递 bmp 的 GET 请求同时发生。也许它可以由操作系统以某种方式在我的代码之外生成?不确定。

如果有帮助,heroku 响应 CONNECT 请求之一的示例日志消息如下:

Oct 27 14:14:25 example heroku/router: at=error code=H13 desc="Connection closed without response" method=CONNECT path="example.herokuapp.com:443" host=example.herokuapp.com request_id=353e623x-dec4-42x5-bcfb-452add02ecef fwd="111.22.333.4" dyno=web.1 connect=0ms service=1ms status=503 bytes=0

编辑:相关设备实际上在很短的时间内发出两个独立的 GET 请求(完全独立且合法的请求)也可能是相关的,但只有一个明显的 CONNECT 请求(大约相同时间作为 GET 请求对)。所以并不是每个 GET 都有一个 CONNECT。

【问题讨论】:

  • 这是有意使用代理的样子:stackoverflow.com/questions/15927079/…
  • 当我的代码中没有任何代理内容时,是否可以尝试使用代理?
  • 我没听说过。我同意,这没有意义。而且由于它仅限于一小部分客户,并且只能在野外观察到,所以它非常神秘。我怀疑是特定于版本的行为或错误。即时请求是否告诉您有关用户代理的任何信息?或者您是否可以添加代码来收集有关操作系统和硬件的信息,并将其传递到 GET 请求的自定义标头中?
  • 是的,已经有了这些信息:samsung、m0xx、GT-I9300、Android 4.3、启动器 com.hola.launcher。撇开启动器不谈,有很多其他用户使用完全相同的组合,没有任何奇怪的 CONNECT,还有很多使用该启动器的用户,同样没有任何 CONNECT。
  • 远射,但要考虑的另一个变量是连接是否来自受限网络,这可能会强制通过代理进行出站连接。

标签: java android heroku httpurlconnection


【解决方案1】:

CONNECT 方法可以在对 HTTP 服务器(代理服务器或源服务器)的请求前加上,它的基本意思是:

“顺便说一句,老伙计,你不会介意转发我说的这些东西 我碰巧提到的主机/端口“逐字”,你会吗? 没必要真正注意我在说什么,真的。”

通常这将是对代理的指示,“让开”,并让请求者(可能是用户代理或另一个代理)直接与上游服务器对话。

如果在您和原始服务器之间存在不合作(可能已过时)的代理,这是一个很好的工具。如果您是一名黑客并且想要一个错误配置的源服务器来轻松地帮助您进入内部网络,这也很方便。

但是,除非您完全了解网络并且“知道”在您的路径中只有一个代理,否则您需要“堆叠”CONNECT 标头,直到您被拒绝。

例如:

CONNECT site.example.com 80 HTTP/1.1
CONNECT site.example.com 80 HTTP/1.1
GET /foo HTTP/1.1
Host: site.example.com

.... 要么让你通过 2 个干扰的、没用的上游代理;或者让您通过实际存在的 1,并从原始服务器为您赢得 503 ......然后您将不得不使用 ONE FEWER CONNECT preface-methods 重复您的请求。

所以这可以解释目前看到的行为。

但是,不清楚是谁在添加CONNECT 前言?!为什么他们不喜欢代理?

可能是:

  1. User-Agent 上的代码(您的 Android 应用在客户端智能手机上使用 HttpUrlConnectionHttpsUrlConnection(如果 URL 具有 https:// 方案,则由 openConnection() 自动使用);
  2. User-Agent 和源服务器之间的任何代理,由于某种原因不信任其上游代理或需要通过仅支持 HTTP 的代理来隧道 HTTPS(这就是CONNECT
  3. 一个被黑客入侵的代理,正在寻找愚蠢的源服务器来利用......但是为什么要等到有人真正需要东西时才去麻烦源服务器呢?

CONNECT 方法的完整内容以及数据包的源 IP 会很有趣。不过,我打赌 #2,并预测如果您通过 http:// URL 访问该站点,您将看不到 CONNECT

对此无能为力。

【讨论】:

  • 惊人的答案,而且都非常合理。到目前为止,我只是将它留给节点应用程序来拒绝 CONNECT 请求,这似乎是通过 503 响应自动完成的。根据您的回答,以便我可以检查 CONNECT 请求的标头,我现在向 node.js 服务器添加了一个方法(请求由 express 模块处理)来处理 CONNECTs,不过只是将标头转储到控制台并发送503 响应。而且我还在等待CONNECT...我想知道这是一个被监视的锅永远不会沸腾的情况...还是薛定谔的猫...
  • 看起来我实际上无法检查这些 CONNECT 请求,因为它们在我的应用程序之外被 heroku 服务器捕获。所以我可能无法了解更多关于它们的信息,但了解可能的原因确实非常有用。所以谢谢你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-18
  • 2011-01-11
  • 2017-03-28
相关资源
最近更新 更多