Excess whitespace character - java.net.ProtocolException: Unexpected status line: ' HTTP/1.1 200 OK'
See original GitHub issueprotected OkHttpClient getHttpClient() {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addInterceptor(new Cookies())
.addInterceptor(new Headers());
return builder.build();
}
protected Retrofit getRetrofit() {
return new Retrofit.Builder()
.baseUrl(getBaseUrl())
.client(getHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public interface ApiFiles {
@GET("api/files/images/{name}")
Call<ResponseBody> image(@Path("name") String name);
}
Bottom code code works correctly but produce memory leak. After a large number of requests, an exception is thrown android.system.ErrnoException: connect failed: EMFILE (Too many open files)
//works correctly but creates a memory leak after a large number of requests
getRetrofit().create(ApiFiles.class).image("name.jpg").execute();
getRetrofit().create(ApiFiles.class).image("name.jpg").execute();
getRetrofit().create(ApiFiles.class).image("name.jpg").execute();
This code produce java.net.ProtocolException: Unexpected status line: " HTTP/1.1 200 OK" on second call. Extra space at the beginning of the status line
ApiFiles call = getRetrofit().create(ApiFiles.class);
call.image("name.jpg").execute();
//next line throws java.net.ProtocolException
call.image("name.jpg").execute();
call.image("name.jpg").execute();
Without retrofit everything works correctly
//works correctly
OkHttpClient client = getHttpClient();
client.newCall(new Request.Builder().url(getBaseUrl() + "api/files/images/name.jpg").build()).execute();
client.newCall(new Request.Builder().url(getBaseUrl() + "api/files/images/name.jpg").build()).execute();
The server receives identical requests and gives identical answers.
If I add “Connection: close” header, everything gets fine
But the server needs to process sequential queries in one close, and this header will increase the load on the server
I think, this is some sort of okhttp problem, when sending requests to the server that does not close the connection after the first request, because after requests to the server that close the connection, such an exception does not thrown.
How to get rid of ProtocolException when using retrofit?
I prepared an android project in which you can repeat and test the problem. Write if necessary
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (1 by maintainers)
I noticed that in Retrofit2, unlike OkHttp3, with multiple requests, the response is read from the same Buffer. After the first request, the buffer size is one byte greater than the Content-Length. Because of this, after reading the entire response, there is a byte in the buffer, which is most likely a space. When reading the response to the second request in the same buffer, this space goes to the beginning. There is status line In the beginning. Since the heder is truncated by the \n character, this space is at the top of the status line and throws ProtocolException. It seems to me necessary to clear this buffer after processing of request, or before new request.
@JakeWharton, you can repeat this problem yourself