HTTPURL সংযোগ HTTP থেকে HTTPS এ পুনঃনির্দেশ অনুসরণ করে না


99

আমি বুঝতে পারি না যে জাভা কেন HttpURLConnectionকোনও HTTP থেকে কোনও HTTP থেকে কোনও HTTPS ইউআরএলকে পুনর্নির্দেশ করে না? 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();
        }
    }
}

এই প্রোগ্রামটির ফলাফল:

আসল ইউআরএল: http://httpstat.us/301
এর সাথে সংযুক্ত: http://httpstat.us/301
এইচটিটিপি প্রতিক্রিয়া কোড পেয়েছে: 301
এইচটিটিপি প্রতিক্রিয়া বার্তা পেয়েছে: স্থায়ীভাবে সরানো হয়েছে

Http://httpstat.us/301 এর কাছে একটি অনুরোধ নিম্নলিখিত (সংক্ষিপ্ত) প্রতিক্রিয়া (যা একেবারে ঠিক বলে মনে হচ্ছে!) প্রদান করে:

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

দুর্ভাগ্যক্রমে, জাভা এর HttpURLConnectionপুনর্নির্দেশ অনুসরণ করে না!

মনে রাখবেন যদি আপনি আসল করে (HTTPS থেকে URL পরিবর্তন https://httpstat.us/301 ), জাভা হবে পুনর্নির্দেশ আশানুরূপ অনুসরণ !?


4
হাই, আমি আপনার প্রশ্নটি স্পষ্টতার জন্য সম্পাদনা করেছি এবং এইচটিটিপিএসে পুনর্নির্দেশটি নির্দিষ্ট করে চিহ্নিত করা সমস্যা। এছাড়াও, আমি বিট.ইল ডোমেনকে অন্য একটিতে পরিবর্তন করেছি, কারণ বিট.ইল ব্যবহারের প্রশ্নগুলিতে কালো তালিকাভুক্ত। আশা করি আপনার আপত্তি নেই, পুনরায় সম্পাদনা করতে দ্বিধা বোধ করবেন।
সেলেসকে

উত্তর:


120

পুনর্নির্দেশগুলি কেবল তখনই অনুসরণ করা হয় যদি তারা একই প্রোটোকল ব্যবহার করে। (দেখুন পদ্ধতি সোর্সে।) এই চেক নিষ্ক্রিয় করতে কোনো উপায় নেই।followRedirect()

যদিও আমরা জানি এটি HTTP আয়না করে, HTTP প্রোটোকল দৃষ্টিকোণ থেকে, এইচটিটিপিএস হ'ল অন্য কিছু, সম্পূর্ণ ভিন্ন, অজানা প্রোটোকল। ব্যবহারকারীর অনুমোদন ছাড়াই পুনর্নির্দেশটি অনুসরণ করা নিরাপদ হবে।

উদাহরণস্বরূপ, ধরুন অ্যাপ্লিকেশনটি স্বয়ংক্রিয়ভাবে ক্লায়েন্ট প্রমাণীকরণ সম্পাদনের জন্য সেট আপ করা হয়েছে। ব্যবহারকারী এইচটিটিপি ব্যবহার করছেন বলে বেনামে সার্ফিং করবেন বলে প্রত্যাশা করা হয়েছে। তবে যদি তার ক্লায়েন্ট জিজ্ঞাসা না করে এইচটিটিপিএস অনুসরণ করে তবে তার পরিচয় সার্ভারের কাছে প্রকাশিত হবে।


60
ধন্যবাদ আমি সবেমাত্র নিশ্চিতকরণ পেয়েছি: bugs.sun.com/bugdatedia/view_bug.do?bug_id=4620571 । যথা: "জাভা নেটওয়ার্কিং ইঞ্জিনিয়ারদের মধ্যে আলোচনার পরে, অনুভূত হয় যে আমরা একটি প্রোটোকল থেকে অন্যটিতে স্বয়ংক্রিয়ভাবে পুনঃনির্দেশ অনুসরণ করা উচিত নয়, উদাহরণস্বরূপ, HTTP থেকে https এবং vise বিপরীতে, এর ফলে গুরুতর সুরক্ষা পরিণতি হতে পারে Thus সুতরাং সমাধানটি হ'ল পুনর্নির্দেশের জন্য সার্ভারের প্রতিক্রিয়াগুলি ফেরত দিতে red পুনঃনির্দেশিত তথ্যের জন্য প্রতিক্রিয়া কোড এবং অবস্থানের শিরোনাম ক্ষেত্রের মানটি পরীক্ষা করে দেখুন the পুনঃনির্দেশ অনুসরণ করা অ্যাপ্লিকেশনটির দায়িত্ব ""
শ্লেক্লেইন

4
তবে এটি কি এইচটিপি থেকে এইচটিপি বা https এ https এ পুনঃনির্দেশ অনুসরণ করে? এমনকি যে ভুল হবে। তাই না?
সুদর্শন ভাট

7
@ জোশুয়াডাভিস হ্যাঁ, এটি কেবল একই প্রোটোকলে পুনঃনির্দেশের ক্ষেত্রে প্রযোজ্য। একটি HttpURLConnectionস্বয়ংক্রিয়ভাবে একটি ভিন্ন প্রটোকল রিডাইরেক্ট অনুসরণ করবে না, এমনকি যদি পুনর্নির্দেশ পতাকা সেট করা হয়।
এরিকসন

8
জাভা নেটওয়ার্কিং ইঞ্জিনিয়াররা একটি সেটফলো ট্রান্সপ্রোটোকল (সত্য) বিকল্পটি দিতে পারে কারণ আমাদের যদি এটি প্রয়োজন হয় তবে আমরা এটি যেভাবেই প্রোগ্রাম করব। এফওয়াইআই ওয়েব ব্রাউজারগুলি কার্ল এবং উইজেট এবং আরও HTTP থেকে এইচটিটিপিএস এবং তদ্বিপরীত থেকে পুনঃনির্দেশগুলি অনুসরণ করতে পারে।
সুপারকোবার

18
কেউ এইচটিটিপিএস-এ স্বয়ংক্রিয়-লগইন সেট আপ করে না এবং তারপরে এইচটিটিপি "বেনামে" থাকার প্রত্যাশা করে। এটা অযৌক্তিক। HTTP থেকে HTTPS- এ পুনঃনির্দেশগুলি অনুসরণ করা পুরোপুরি নিরাপদ এবং স্বাভাবিক (অন্যভাবে নয়) perfectly এটি কেবলমাত্র একটি সাধারণ জাভা এপিআই।
গ্লেন মেইনার্ড

55

এইচটিপিআরএল সংযোগ ডিজাইন দ্বারা স্বয়ংক্রিয়ভাবে এইচটিটিপি থেকে এইচটিটিপিএসে পুনঃনির্দেশ করা হবে না (বা বিপরীতে)। পুনঃনির্দেশ অনুসরণ করা গুরুতর সুরক্ষা পরিণতি হতে পারে। এসএসএল (অতএব এইচটিটিপিএস) একটি সেশন তৈরি করে যা ব্যবহারকারীর কাছে অনন্য। একাধিক অনুরোধের জন্য এই সেশনটি পুনরায় ব্যবহার করা যেতে পারে। সুতরাং, সার্ভারটি কোনও একক ব্যক্তির থেকে করা সমস্ত অনুরোধ ট্র্যাক করতে পারে। এটি পরিচয়ের দুর্বল রূপ এবং এটি শোষণযোগ্য। এছাড়াও, এসএসএল হ্যান্ডশেক ক্লায়েন্টের শংসাপত্রের জন্য জিজ্ঞাসা করতে পারে। যদি সার্ভারে প্রেরণ করা হয় তবে ক্লায়েন্টের পরিচয় সার্ভারকে দেওয়া হবে।

এরিকসন যেমন উল্লেখ করেছেন, ধরুন অ্যাপ্লিকেশনটি স্বয়ংক্রিয়ভাবে ক্লায়েন্টের প্রমাণীকরণ সম্পাদনের জন্য সেট আপ হয়েছে। ব্যবহারকারী এইচটিটিপি ব্যবহার করছেন বলে বেনামে সার্ফিং করবেন বলে প্রত্যাশা করা হয়েছে। তবে যদি তার ক্লায়েন্ট জিজ্ঞাসা না করে এইচটিটিপিএস অনুসরণ করে তবে তার পরিচয় সার্ভারের কাছে প্রকাশিত হবে।

এইচটিটিপি থেকে এইচটিটিপিএসে পুনঃনির্দেশের আগে শংসাপত্র, ক্লায়েন্ট শংসাপত্র বা এসএসএল সেশন আইডি প্রেরণ করা হবে না তা নিশ্চিত করার জন্য প্রোগ্রামারকে অতিরিক্ত পদক্ষেপ নিতে হবে। ডিফল্ট এগুলি প্রেরণ করা হয়। পুনঃনির্দেশটি যদি ব্যবহারকারীকে আঘাত করে তবে পুনঃনির্দেশটি অনুসরণ করবেন না। এ কারণেই স্বয়ংক্রিয় পুনঃনির্দেশ সমর্থিত নয়।

বুঝতে পেরেছি যে, এখানে কোড যা পুনঃনির্দেশগুলি অনুসরণ করবে।

  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();
  ...

এটি কেবলমাত্র একটি সমাধান যা 1 টিরও বেশি পুনঃনির্দেশের জন্য কাজ করে। ধন্যবাদ!
রজার এলিয়েন

এটি একাধিক পুনঃনির্দেশগুলির জন্য সুন্দরভাবে কাজ করে (HTTPS এপিআই -> HTTP -> HTTP চিত্র)! নিখুঁত সহজ সমাধান।
এরিক এইচ 206

4
@ নাথান - বিশদগুলির জন্য ধন্যবাদ, তবে আমি এখনও এটি কিনিনি। উদাহরণস্বরূপ, কোনও শংসাপত্র বা ক্লায়েন্ট শংসাপত্র প্রেরণ করা হয়েছে কিনা তা ক্লায়েন্টের নিয়ন্ত্রণে থাকলে। যদি এটির ব্যথা হয় তবে এটি করবেন না (এই ক্ষেত্রে, পুনঃনির্দেশকে অনুসরণ করবেন না)।
জুলিয়ান রেসকে

4
আমি শুধু location = URLDecoder.decode(location...অংশটি বুঝতে পারি না । এটি একটি কাজের এনকোডযুক্ত আপেক্ষিক অংশটি (আমার ক্ষেত্রে স্পেস = + সহ) একটি অ-কর্মহীন অংশে ডিকোড করে। আমি এটিকে সরিয়ে দেওয়ার পরে, এটি আমার পক্ষে ঠিক ছিল।
নাইক

@ নাইক আমি নিশ্চিত না কেন আপনার প্রয়োজন নেই তবে আমি তা করি।
নাথান

27

HttpURLConnection.setFollowRedirects(false)কোনও সুযোগে কিছু ডেকেছে ?

আপনি সবসময় কল করতে পারে

conn.setInstanceFollowRedirects(true);

আপনি যদি নিশ্চিত করতে চান তবে আপনি অ্যাপটির বাকী আচরণটি প্রভাবিত করবেন না।


ওও ... এটি সম্পর্কে জানতাম না ... ভাল লাগছিল ... আমি ক্লাসটি সন্ধান করতে যাচ্ছিলাম সেখানে এরকম যুক্তি ছিল .... এটা বোঝা যায় যে এটি একটি শিরোনাম প্রদান করে শিরোনামকে ফিরিয়ে দিবে অধ্যক্ষ .... এখন C # টি প্রশ্নের উত্তর দিতে ফিরে যান: পি [আমি মজা করছি]
monksy

4
নোট করুন যে setFollowRedirects () ক্লাসে কল করা উচিত, উদাহরণ হিসাবে নয়।
karlbecker_com

4
@ ডিএলডিএনএইচ: কার্লবেকার_কম যখন টাইপের দিকে কল setFollowRedirectsকরার ক্ষেত্রে একেবারে সঠিক ছিল , setInstanceFollowRedirectsএটি একটি উদাহরণ পদ্ধতি এবং টাইপটিতে কল করা যায় না।
জন স্কিটি

4
ওহ, আমি কীভাবে এটি ভুল বুঝেছি। ভুল সম্পাদনা সম্পর্কে দুঃখিত। রোলব্যাক করার চেষ্টাও করেছিলাম এবং নিশ্চিতও ছিলাম না যে আমি কীভাবে এটিও বন্ধ করে রেখেছি।
dldnh

7

আপনার উপরের কিছু দ্বারা উল্লিখিত হিসাবে, পুনঃনির্দেশিত প্রোটোকলটি একই রকম হলে সেটফোলোরেডাইরেক্ট এবং সেটআইনস্ট্যান্স ফলোরিডায়ারেক্টস কেবল স্বয়ংক্রিয়ভাবে কাজ করে। উদাহরণস্বরূপ HTTP থেকে http এবং https থেকে https এ।

setFolloRedirect ক্লাস পর্যায়ে থাকে এবং এটি ইউআরএল সংযোগের সমস্ত দৃষ্টান্তের জন্য সেট করে, যেখানে সেটইনস্ট্যান্সফলোআরডাইরেক্টস কেবলমাত্র একটি নির্দিষ্ট উদাহরণের জন্য। এইভাবে বিভিন্ন দৃষ্টান্তের জন্য আমাদের আলাদা আচরণ থাকতে পারে।

আমি এখানে একটি খুব ভাল উদাহরণ পেয়েছি http://www.mkyong.com/java/java-httpurlconnection-follow-redirect-example/


2

আরেকটি বিকল্প হ'ল অ্যাপাচি এইচটিপিপি কম্পোনেন্টস ক্লায়েন্ট ব্যবহার করা :

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

কোডের উদাহরণ:

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet("https://media-hearth.cursecdn.com/avatars/330/498/212.png");
CloseableHttpResponse response = httpclient.execute(httpget);
final HttpEntity entity = response.getEntity();
final InputStream is = entity.getContent();

-4

HTTPUrlConnication অবজেক্টের প্রতিক্রিয়া পরিচালনা করার জন্য দায়বদ্ধ নয়। এটি প্রত্যাশা অনুযায়ী পারফরম্যান্স, এটি অনুরোধ করা URL এর সামগ্রীটি ধরে ফেলে। প্রতিক্রিয়াটি ব্যাখ্যা করার জন্য কার্যকারিতার ব্যবহারকারী এটি আপনার উপর নির্ভর করে। এটি নির্দিষ্টকরণ ব্যতীত বিকাশকারীদের উদ্দেশ্যগুলি পড়তে সক্ষম নয়।


7
কেন এটি এক্ষেত্রে ইনস্টিস্ট্যান্সফলোরেডাইরেক্টস সেট করেছে? ))
শিচেকলাইন

আমার অনুমান যে এটি পরে যুক্ত করার জন্য একটি প্রস্তাবিত বৈশিষ্ট্য ছিল, এটি বোধগম্য হয় .. আমার মন্তব্যটির প্রতি আরও বেশি প্রতিফলিত হয়েছিল ... ক্লাসটি ডিজাইন করা হয়েছে ওয়েব সাইটের সামগ্রী দখল করতে এবং এটি ফিরিয়ে আনতে ... লোকেরা চায় নন এইচটিটিপি 200 বার্তা পান।
ভিক্ষু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.