2016-12-28 5 views
0

현재 목표 대상까지 리디렉션하여 나를 반송 할 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) 
+1

유일한 아이디어는 서버가 잘못된 HTTP 헤더를 보내는 것입니다. TCP 네트워크 스트림을 캡쳐하여 여기에 제공하는 것이 매우 유용합니다. 이를 위해 기기를 루트로 설정 한 다음 http://www.androidtcpdump.com/ 또는 Shark for Root와 같은 앱을 사용해야합니다. https : // url을 http : // – pelya

+0

@pelya로 변경해야합니다. 동일한 기기에서 Chrome에서 요청할 때 헤더가 올바른 것입니다. 다른 방법으로 서버에 접속하면 오류가 발생합니다. 또한 서버는 https로 고정되어 있으므로 http로 전환하여 트래픽을 캡처하는 것은 불가능합니다 (불행히도). 헤더를 가져 오는 다른 방법이 있습니까? – Apzx

+1

Chrome은 HttpURLConnection을 사용하지 않으므로 요청에 다른 HTTP 헤더가 사용됩니다. 서버가 가장 다르게 응답합니다. 로그를 캡처 할 수 없다면 코드에서 HttpURLConnection을 레거시 Apache HttpClient로 바꾸고 버그가 사라지길 바랍니다. 또한'build.gradle'에'useLibrary 'org.apache.http.legacy''를 추가해야합니다. – pelya

답변

0

은 밝혀,이 동작 때문에 URL 문자열에 \n 문자의 원인이되었다.

나는 okhttp가이 결과를 어떻게 관리했는지는 알 수 없지만 캐릭터를 삭제하면 문제가 사라졌습니다.

관련 문제