본문 바로가기
개발/안드로이드

java.net.ProtocolException: unexpected end of stream

by 장모 2021. 5. 7.

미리 결론: 서버가 HTTP/1.0으로 응답해 발생했던 문제 1.1로 변경해서 해결됨. 

 

Retrofit 사용중에 간헐적으로 오류가 발생했다. 

검색해보면 

1. Connection: close 헤더를 추가하라거나 

2. OkHttpClient.Builder에서 retryOnConnectionFailure를 true로 변경하라거나 

3. 에뮬레이터에서만 발생하는 오류라거나 

4. 그냥 OkHttp 자체의 버그이거나

5. 혹은 서버의 문제

 

라는 글들을 볼 수 있는데 1-3까지로는 해결되는게 없다. 4를 확인하기 위해 새 프로젝트를 만들어 UrlConnection을 사용해서 테스트를 했는데 같은 문제가 발생했다. 로그에서 OkHttp를 볼 수 있었어서 OkHttp 문제가 아니라는 것이 확인된 것은 아니지만, 프레임워크에 들어간 코드의 문제는 아닐 것 같아서 5로 넘어갔다. 

 

TCP 뷰어로 연결 상태를 확인해봐도 뭔가 이상하긴 하고...

서버의 응답을 확인해보니 기본값이 HTTP/1.0! 뚜둥! 

    # The version of the HTTP protocol we support.
    # Set this to HTTP/1.1 to enable automatic keepalive
    protocol_version = "HTTP/1.0"

 

 

그런데 1.0이라고 해도 OkHttp가 지원을 하면 문제가 없을텐데 하고 확인해보니 1.1부터 지원! 뚜둥!

square.github.io/okhttp/4.x/okhttp/okhttp3/-ok-http-client/-builder/protocols/

 

protocols - OkHttp - OkHttp

okhttp / okhttp3 / OkHttpClient / Builder / protocols protocols fun protocols(protocols:List ): Builder Configure the protocols used by this client to communicate with remote servers. By default this client will prefer the most efficient transport availabl

square.github.io

 

내 경우는 Flask 개발용 서버라 아래 코드로 간단히 응답 프로토콜을 변경해서 해결했다.

from werkzeug.serving import WSGIRequestHandler
WSGIRequestHandler.protocol_version = "HTTP/1.1"

 

고작 이 두줄...고작 응답이 HTTP/1.0으로 내려가고 있다는 것을 몰라서 이틀을 날렸다. Stackoverflow나 retrofit의 issue의 답에서도 이에 대한 얘기가 없다는게 신기. 너무 바보같아서 없나...

 

 

 

댓글