Shc*_*ein 92 java https redirect httpurlconnection http-redirect
我无法理解为什么Java HttpURLConnection不遵循重定向.我使用以下代码来获取此页面:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
而且,我收到以下回复(看起来绝对正确!):
Original URL: http://httpstat.us/301 Connected to: http://httpstat.us/301 HTTP response code received: 301 HTTP response message received: Moved Permanently
不幸的是,HttpURLConnection变量包含相同的URL,并且流包含以下内容(显然,Java HttpURLConnection不遵循重定向!):
HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Location: https://httpstat.us
Run Code Online (Sandbox Code Playgroud)
eri*_*son 112
我认为它不会自动从HTTP重定向到HTTPS(反之亦然).
尽管我们知道它反映了HTTP,但从HTTP协议的角度来看,HTTPS只是其他一些完全不同的未知协议.未经用户批准,遵循重定向是不安全的.
例如,假设应用程序设置为自动执行客户端身份验证.用户希望匿名冲浪,因为他正在使用HTTP.但如果他的客户端在没有询问的情况下跟踪HTTPS,则会向服务器显示其身份.
Nat*_*han 50
设计中的 HttpURLConnection 不会自动从HTTP重定向到HTTPS(反之亦然).重定向后可能会产生严重的安全后果.SSL(因此HTTPS)创建一个对用户唯一的会话.此会话可以重复用于多个请求.因此,服务器可以跟踪从单个人做出的所有请求.这是一种弱的身份形式,可以利用.此外,SSL握手可以请求客户端的证书.如果发送到服务器,则将客户端的标识提供给服务器.
正如erickson指出的那样,假设应用程序已设置为自动执行客户端身份验证.用户希望匿名冲浪,因为他正在使用HTTP.但如果他的客户端在没有询问的情况下跟踪HTTPS,则会向服务器显示其身份.
有了这个,这里的代码将遵循重定向.
URL resourceUrl, base, next;
Map<String, Integer> visited;
HttpURLConnection conn;
String location;
int times;
...
visited = new HashMap<>();
while (true)
{
times = visited.compute(url, (key, count) -> count == null ? 1 : count + 1);
if (times > 3)
throw new IOException("Stuck in redirect loop");
resourceUrl = new URL(url);
conn = (HttpURLConnection) resourceUrl.openConnection();
conn.setConnectTimeout(15000);
conn.setReadTimeout(15000);
conn.setInstanceFollowRedirects(false); // Make the logic below easier to detect redirections
conn.setRequestProperty("User-Agent", "Mozilla/5.0...");
switch (conn.getResponseCode())
{
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
location = conn.getHeaderField("Location");
location = URLDecoder.decode(location, "UTF-8");
base = new URL(url);
next = new URL(base, location); // Deal with relative URLs
url = next.toExternalForm();
continue;
}
break;
}
is = conn.openStream();
...
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 26
什么事情HttpURLConnection.setFollowRedirects(false)有机会?
你总是可以打电话
conn.setInstanceFollowRedirects(true);
Run Code Online (Sandbox Code Playgroud)
如果您想确保不影响应用程序的其余行为.
小智 6
正如上面的一些人所提到的,setFollowRedirect和setInstanceFollowRedirects仅在重定向协议相同时自动工作.即从http到http和https到https.
setFolloRedirect处于一流水平,并将此的URL连接的所有实例,而setInstanceFollowRedirects是只在一定的实例.这样我们就可以为不同的实例提供不同的行为.
我在这里找到了一个很好的例子 http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
另一种选择是使用Apache HttpComponents Client:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
示例代码:
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("https://media-hearth.cursecdn.com/avatars/330/498/212.png");
CloseableHttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
77856 次 |
| 最近记录: |