私は現在、ターゲットの宛先までリダイレクトで私をバウンスするIISサーバーにリクエストを(HttpURLConnection
で)作成しようとしています。HttpURLConnectionレスポンスがありませんステータスライン(ProtocolException)
問題:urlConnection.getInputStream()
は(それを呼び出す、またはurlConnection.getResponseCode()
)が呼び出されたときにjava.net.ProtocolException: Unexpected status line: <html><head><title>Object moved</title></head><body>
これが起こります。
多くの場合、問題がサーバーの設定が間違っている場合がありますが、この場合、Androidユーザーエージェントを偽装してChromeからリクエストすると、予期した結果が得られます。
さらに、サーバーは古くからあり、問題の原因となったことはなく、本番環境で使用されているのと同じ方法で構成されています。
別のリダイレクトWebページにアクセスすると問題なく動作します(https://com.google/
でテスト、2回のリダイレクト)。サーバー上のリダイレクトされていないウェブページには問題はありません。
私は2日間探していて、進歩していません。どんな助けもありがとう。
現在使用されているコード:
StringBuilder builder = new StringBuilder();
HttpsURLConnection urlConnection = null;
try {
URL url = new URL(urlStrings[0]);
urlConnection = (HttpsURLConnection) url.openConnection();
LogHelper.Log(getBaseContext(), "Request on URL :\n\"" + url + "\"");
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(10000);
urlConnection.setConnectTimeout(15000);
urlConnection.setRequestProperty("Accept","*/*");
urlConnection.setDoOutput(false);
urlConnection.setDoInput(true);
urlConnection.setInstanceFollowRedirects(true);
urlConnection.setUseCaches(false);
CookieManager cookieManager = new CookieManager();
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);
urlConnection.connect();
int status = urlConnection.getResponseCode();
LogHelper.Log(getBaseContext(), "Status code is \"" + status + "\"");
if (!url.equals(urlConnection.getURL())) {
LogHelper.Log(getBaseContext(), "URL after redirection is :\n\"" + urlConnection.getURL() + "\"");
}
switch (status/100) {
case 1:
case 2:
case 3:
InputStream stream = urlConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line).append("\n");
}
reader.close();
break;
case 4:
case 5:
InputStream errorStream = urlConnection.getErrorStream();
BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream));
String errorLine;
while ((errorLine = errorReader.readLine()) != null) {
builder.append(errorLine).append("\n");
}
errorReader.close();
throw new Exception(builder.toString());
default:
throw new Exception("Unknown status code: " + status);
}
} catch (Exception e) {
LogHelper.Log(getBaseContext(), e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return builder.toString();
結果のエラー:
java.net.ProtocolException: Unexpected status line: <html><head><title>Object moved</title></head><body>
at com.android.okhttp.internal.http.StatusLine.parse(StatusLine.java:54)
at com.android.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:239)
at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:104)
at com.android.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:1120)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:951)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:482)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(
at com.pushmanager.clientmdm.activities.RegistrationView$1$2.doInBackground(
at com.pushmanager.clientmdm.activities.RegistrationView$1$2.doInBackground(
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
私の唯一のアイデアは、サーバーが間違ったHTTPヘッダーを送信することです。 TCPネットワークストリームをキャプチャしてここに入力すると非常に便利です。そのためにデバイスをルートし、次にhttp://www.androidtcpdump.com/またはShark for Rootのようなアプリを使用する必要があります。 https:// URLをhttp:// – pelya
@pelyaに変更する必要があります。同じデバイスでChromeからリクエストするときにヘッダーが正しいことです。他の方法でサーバーに接続するとエラーになりません。 また、サーバーはhttpsで固定されているため、httpに切り替えることでトラフィックをキャプチャすることはできません(残念ながら)。ヘッダーを取得する他の方法はありますか? – Apzx
ChromeはHttpURLConnectionを使用しないため、要求のHTTPヘッダーが異なるため、おそらくサーバーの応答が異なる可能性があります。ログを取得できない場合は、コード内のHttpURLConnectionを従来のApache HttpClientに置き換えて、バグがなくなることを期待してください。また、 'build.gradle'に' useLibrary 'org.apache.http.legacy''を追加する必要があります。 – pelya