Translate

[Android] java.net.ProtocolException: unexpected end of stream 에러문제



증상

이미지를 다운로드 시 1분이상 로직이 진행되지 않고 멈추다가 아래와 같은 로그가 발생하며 다음 로직으로 넘어간다.


Source
URL url = new URL(imageDownUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();

conn.setConnectTimeout(5000);
conn.setUseCaches(false);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK){
 File file = new File(getCacheDir()/*Environment.getExternalStorageDirectory().getPath()*/, imageName);
 FileOutputStream fileOutput = new FileOutputStream(file);
 InputStream inputStream = conn.getInputStream();
 byte[] buffer = new byte[4096];
 int bufferLength = 0; 

 while ((bufferLength = inputStream.read(buffer)) > 0 ) {
  fileOutput.write(buffer, 0, bufferLength);
 }
 fileOutput.close();
}



Log
06-24 12:14:38.367 17879 17920 W System.err: java.net.ProtocolException: unexpected end of stream
06-24 12:14:38.372 17879 17920 W System.err: at com.android.okhttp.internal.http.HttpConnection$FixedLengthSource.read(HttpConnection.java:472)
06-24 12:14:38.372 17879 17920 W System.err: at com.android.okio.RealBufferedSource$1.read(RealBufferedSource.java:174)
06-24 12:14:38.372 17879 17920 W System.err: at java.io.InputStream.read(InputStream.java:162)
06-24 12:14:38.372 17879 17920 W System.err: at com.?????$9.run(?????.java:547)
06-24 12:14:38.372 17879 17920 W System.err: at java.lang.Thread.run(Thread.java:818)
06-24 12:14:38.377 17879 17879 I Timeline: Timeline: Activity_launch_request id:com.????? time:1022021








원인 및 분석

관련 이슈를 찾아보니 비슷한 이슈가 있었다.

https://github.com/square/okhttp/issues/1490
(전직 구글 HTTP 마스터이자 현직 OkHTTP 개발자인 Jesse Wilson가 OkHTTP 이슈에 올라온 글에 대해서 답변을 한 글이다.)

내용 중간에 보면
java.net.ProtocolException: unexpected end of stream
라는 Exception 발생 부분에 대해서 이야기를 한다.

URL: https://github.com/square/okhttp/blob/96dfaaa817816b2dc191d4d075a07aeb0c808694/okhttp/src/main/java/com/squareup/okhttp/internal/http/HttpConnection.java#L382

Source
@Override public long read(Buffer sink, long byteCount) throws IOException {
  if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount);
  if (closed) throw new IllegalStateException("closed");
  if (bytesRemaining == 0) return -1;

  long read = source.read(sink, Math.min(bytesRemaining, byteCount));
  if (read == -1) {
    unexpectedEndOfInput(); // The server didn't supply the promised content length.
    throw new ProtocolException("unexpected end of stream");
  }

  bytesRemaining -= read;
  if (bytesRemaining == 0) {
    endOfInput(true);
  }
  return read;
}


내용을 보면 서버의 Response header에 기술된 Content-Length 만큼 Body를 보내주지 않아서 오류가 발생을 했다고 한다.




위의 내용으로 보아 처음에는 다음과 같이 추측을 했다.
1. Server(Nginx) 의 문제
2. Server에 연결된 Network 문제 (보안관련 솔루션 의심)
3. 비정상적인 이미지



결국 서버 부분은 다음과 같이 원인분석 및 해결을 했다.
- [Nginx] net::ERR_CONTENT_LENGTH_MISMATCH 에러
  (http://1004lucifer.blogspot.kr/2015/06/nginx-neterrcontentlengthmismatch.html)



댓글