防止来自HttpURLConnection的未经请求的CONNECT方法调用

drm*_*wer 6 java android heroku httpurlconnection

我正在使用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;
Run Code Online (Sandbox Code Playgroud)

这很好用,通过strURL返回一个bmp图像来定义url ,并且这个被解码准备好供上面的代码使用.

但是对于一个用户来说,虽然代码可以很好地获取bmp图像,但是在服务器(heroku的node.js服务器)上很明显,CONNECT他们的设备也发送了一个请求.该请求被自动拒绝503响应,所以这不是问题,bmp仍然会被发送到他们的设备,但我想知道为什么CONNECT要发送这些请求,以及如何阻止它们.当然应该只有GET请求吗?

我已经尝试过这个解决方案似乎是一个类似的问题,但对我来说没有任何区别.

请注意,这strURL是一个https服务器,我正在使用HttpURLConnection(不Https) - 不确定是否有任何重要性.

我也不是100%确定CONNECT请求来自上述调用,但它们肯定会在GET提供bmp 的请求的同时发生.也许它可能是由我的代码之外的操作系统生成的?不确定.

如果它有帮助,来自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
Run Code Online (Sandbox Code Playgroud)

编辑:有关设备实际上在彼此的短时间内完成两个独立的GET请求(完全独立和合法的请求)也可能是相关的,但是只有一个CONNECT请求明显(大约与一对GET请求).因此,并不是每个GET都有一个CONNECT.

Dav*_*ock 2

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
Run Code Online (Sandbox Code Playgroud)

.... 要么让你通过 2 个干扰的、无用的上游代理;或者让您只完成实际存在的 1,并从源服务器获得 503 ...因此您将不得不使用一种CONNECT前言方法重复您的请求。

因此,这可以解释迄今为止所看到的行为。

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

它可能是:

  1. 用户代理上的代码(您客户端智能手机上的 Android 应用程序使用HttpUrlConnection或(如果 URL 有方案HttpsUrlConnection则自动使用);openConnection()https://
  2. 用户代理和源服务器之间的任何代理,由于某种原因不信任其上游代理,或者需要通过代理传输 HTTPS,否则该代理仅支持 HTTP(这CONNECT就是用于
  3. 一个被黑客攻击的代理,正在寻找愚蠢的原始服务器来利用……但是为什么要等到有人真正需要东西时才去打扰原始服务器呢?

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

对此无能为力。