Saya tidak mengerti mengapa Java HttpURLConnection
tidak mengikuti pengalihan HTTP dari HTTP ke URL HTTPS. Saya menggunakan kode berikut untuk mendapatkan halaman di 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();
}
}
}
Output dari program ini adalah:
URL Asli: http://httpstat.us/301 Terhubung ke: http://httpstat.us/301 Kode tanggapan HTTP diterima: 301 Pesan tanggapan HTTP diterima: Dipindahkan Secara Permanen
Permintaan ke http://httpstat.us/301 mengembalikan respons (dipersingkat) berikut (yang tampaknya benar!):
HTTP/1.1 301 Moved Permanently
Cache-Control: private
Content-Length: 21
Content-Type: text/plain; charset=utf-8
Location: https://httpstat.us
Sayangnya, Java HttpURLConnection
tidak mengikuti pengalihan!
Perhatikan bahwa jika Anda mengubah URL asli ke HTTPS ( https://httpstat.us/301 ), Java akan mengikuti pengalihan seperti yang diharapkan !?
java
redirect
https
httpurlconnection
http-redirect
Shcheklein
sumber
sumber
Jawaban:
Pengalihan diikuti hanya jika mereka menggunakan protokol yang sama. (Lihat yang
followRedirect()
metode dalam sumber.) Tidak ada cara untuk menonaktifkan cek ini.Meskipun kita tahu itu mencerminkan HTTP, dari sudut pandang protokol HTTP, HTTPS hanyalah beberapa protokol lain yang sama sekali berbeda dan tidak dikenal. Tidak aman untuk mengikuti pengalihan tanpa persetujuan pengguna.
Misalnya, aplikasi disiapkan untuk melakukan otentikasi klien secara otomatis. Pengguna mengharapkan untuk menjelajah secara anonim karena dia menggunakan HTTP. Tetapi jika kliennya mengikuti HTTPS tanpa bertanya, identitasnya akan diungkapkan ke server.
sumber
HttpURLConnection
tidak akan secara otomatis mengikuti pengalihan ke protokol yang berbeda, meskipun bendera pengalihan disetel.HttpURLConnection menurut desain tidak akan secara otomatis mengalihkan dari HTTP ke HTTPS (atau sebaliknya). Mengikuti pengalihan mungkin memiliki konsekuensi keamanan yang serius. SSL (karenanya HTTPS) membuat sesi yang unik untuk pengguna. Sesi ini dapat digunakan kembali untuk beberapa permintaan. Dengan demikian, server dapat melacak semua permintaan yang dibuat dari satu orang. Ini adalah bentuk identitas yang lemah dan dapat dieksploitasi. Juga, jabat tangan SSL dapat meminta sertifikat klien. Jika dikirim ke server, maka identitas klien diberikan ke server.
Seperti yang ditunjukkan oleh erickson , misalkan aplikasi diatur untuk melakukan otentikasi klien secara otomatis. Pengguna mengharapkan untuk menjelajah secara anonim karena dia menggunakan HTTP. Tetapi jika kliennya mengikuti HTTPS tanpa bertanya, identitasnya akan diungkapkan ke server.
Pemrogram harus mengambil langkah ekstra untuk memastikan bahwa kredensial, sertifikat klien, atau id sesi SSL tidak akan dikirim sebelum mengalihkan dari HTTP ke HTTPS. Defaultnya adalah mengirim ini. Jika pengalihan merugikan pengguna, jangan ikuti pengalihan. Inilah mengapa pengalihan otomatis tidak didukung.
Dengan memahami itu, inilah kode yang akan mengikuti pengalihan.
sumber
location = URLDecoder.decode(location...
bagiannya. Ini menerjemahkan bagian relatif yang dikodekan yang berfungsi (dengan spasi = + dalam kasus saya) menjadi yang tidak berfungsi. Setelah saya menghapusnya, tidak masalah bagi saya.Apakah ada yang menelepon
HttpURLConnection.setFollowRedirects(false)
secara kebetulan?Anda selalu bisa menelepon
jika Anda ingin memastikan bahwa Anda tidak memengaruhi perilaku aplikasi lainnya.
sumber
setFollowRedirects
tipe,setInstanceFollowRedirects
merupakan metode instan dan tidak bisa dipanggil pada tipe.Seperti yang disebutkan oleh beberapa dari Anda di atas, setFollowRedirect dan setInstanceFollowRedirects hanya bekerja secara otomatis jika protokol yang dialihkan sama. yaitu dari http ke http dan https ke https.
setFolloRedirect berada di tingkat kelas dan menyetelnya untuk semua instance koneksi url, sedangkan setInstanceFollowRedirects hanya untuk instance tertentu. Dengan cara ini kita dapat memiliki perilaku yang berbeda untuk contoh yang berbeda.
Saya menemukan contoh yang sangat bagus di sini http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/
sumber
Pilihan lainnya adalah menggunakan Apache HttpComponents Client :
Kode sampel:
sumber
HTTPUrlConnection tidak bertanggung jawab untuk menangani respons objek. Ini adalah kinerja seperti yang diharapkan, ini mengambil konten dari URL yang diminta. Terserah Anda pengguna fungsi tersebut untuk menafsirkan respons. Itu tidak dapat membaca maksud pengembang tanpa spesifikasi.
sumber