HTTPURLConnection 不遵循从 HTTP 到 HTTPS 的重定向 [英] HTTPURLConnection Doesn't Follow Redirect from HTTP to HTTPS

查看:39
本文介绍了HTTPURLConnection 不遵循从 HTTP 到 HTTPS 的重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白为什么 Java 的 HttpURLConnection 不遵循从 HTTP 到 HTTPS URL 的 HTTP 重定向.我使用以下代码获取位于 https://httpstat.us/ 的页面:

import java.net.URL;导入 java.net.HttpURLConnection;导入 java.io.InputStream;公共课测试员{public static void main(String argv[]) 抛出异常{输入流是 = null;尝试 {String httpUrl = "http://httpstat.us/301";URL resourceUrl = 新 URL(httpUrl);HttpURLConnection conn = (HttpURLConnection)resourceUrl.openConnection();conn.setConnectTimeout(15000);conn.setReadTimeout(15000);conn.connect();is = conn.getInputStream();System.out.println("原文地址:"+httpUrl);System.out.println("连接到:"+conn.getURL());System.out.println("收到的HTTP响应码:"+conn.getResponseCode());System.out.println("收到HTTP响应消息:"+conn.getResponseMessage());} 最后 {if (is != null) is.close();}}}

这个程序的输出是:

<前>原文网址:http://httpstat.us/301连接到:http://httpstat.us/301收到的 HTTP 响应代码:301收到 HTTP 响应消息:永久移动

http://httpstat.us/301 的请求返回以下(缩短的)响应(这似乎是绝对正确!):

HTTP/1.1 301 永久移动缓存控制:私有内容长度:21内容类型:文本/纯文本;字符集=utf-8位置:https://httpstat.us

不幸的是,Java 的 HttpURLConnection 没有遵循重定向!

请注意,如果您将原始网址更改为 HTTPS(https://httpstat.us/301),Java按照预期跟随重定向!?

解决方案

仅当重定向使用相同的协议时才会被遵循.(见 源码中的 followRedirect() 方法.)没有办法禁用这个检查.

尽管我们知道它反映了 HTTP,但从 HTTP 协议的角度来看,HTTPS 只是其他一些完全不同的未知协议.在没有用户批准的情况下跟踪重定向是不安全的.

例如,假设应用程序设置为自动执行客户端身份验证.用户希望匿名上网,因为他使用的是 HTTP.但如果他的客户端不经询问就使用 HTTPS,他的身份就会暴露给服务器.

I can't understand why Java's HttpURLConnection does not follow an HTTP redirect from an HTTP to an HTTPS URL. I use the following code to get the page at https://httpstat.us/:

import java.net.URL;
import java.net.HttpURLConnection;
import java.io.InputStream;

public class Tester {

    public static void main(String argv[]) throws Exception{
        InputStream is = null;

        try {
            String httpUrl = "http://httpstat.us/301";
            URL resourceUrl = new URL(httpUrl);
            HttpURLConnection conn = (HttpURLConnection)resourceUrl.openConnection();
            conn.setConnectTimeout(15000);
            conn.setReadTimeout(15000);
            conn.connect();
            is = conn.getInputStream();
            System.out.println("Original URL: "+httpUrl);
            System.out.println("Connected to: "+conn.getURL());
            System.out.println("HTTP response code received: "+conn.getResponseCode());
            System.out.println("HTTP response message received: "+conn.getResponseMessage());
       } finally {
            if (is != null) is.close();
        }
    }
}

The output of this program is:

Original URL: http://httpstat.us/301
Connected to: http://httpstat.us/301
HTTP response code received: 301
HTTP response message received: Moved Permanently

A request to http://httpstat.us/301 returns the following (shortened) response (which seems absolutely right!):

HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Location: https://httpstat.us

Unfortunately, Java's HttpURLConnection does not follow the redirect!

Note that if you change the original URL to HTTPS (https://httpstat.us/301), Java will follow the redirect as expected!?

解决方案

Redirects are followed only if they use the same protocol. (See the followRedirect() method in the source.) There is no way to disable this check.

Even though we know it mirrors HTTP, from the HTTP protocol point of view, HTTPS is just some other, completely different, unknown protocol. It would be unsafe to follow the redirect without user approval.

For example, suppose the application is set up to perform client authentication automatically. The user expects to be surfing anonymously because he's using HTTP. But if his client follows HTTPS without asking, his identity is revealed to the server.

这篇关于HTTPURLConnection 不遵循从 HTTP 到 HTTPS 的重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆