현재 목표 대상까지 리디렉션하여 나를 반송 할 IIS 서버에 요청을 보내려고합니다 (HttpURLConnection
포함).HttpURLConnection 응답 없음 상태 회선 (ProtocolException)
문제 : java.net.ProtocolException: Unexpected status line: <html><head><title>Object moved</title></head><body>
urlConnection.getInputStream()
이 (그것을 호출하는, 또는 urlConnection.getResponseCode()
)를 호출 할 때이 발생합니다.
많은 경우에 서버가 잘못 구성된 경우가 많았지 만,이 경우 Android 사용자 에이전트를 위조하면서 Chrome에서 요청하면 예상되는 결과가 나타납니다.
또한 서버는 이전에는 문제의 원인이되지 않았으며 프로덕션 환경에서 사용 된 것과 같은 방식으로 구성되었습니다.
다른 리디렉션 웹 페이지에 접속하면 괜찮습니다 (https://com.google/
, 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