- Saved searches
- Use saved searches to filter your results more quickly
- Excess whitespace character — java.net.ProtocolException: Unexpected status line: ‘ HTTP/1.1 200 OK’ #2724
- Excess whitespace character — java.net.ProtocolException: Unexpected status line: ‘ HTTP/1.1 200 OK’ #2724
- Comments
- java.net.ProtocolException: Unexpected status line: HTTP/1.1 422��Unprocessable Entity
- Related videos on Youtube
- loeschg
- Comments
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Excess whitespace character — java.net.ProtocolException: Unexpected status line: ‘ HTTP/1.1 200 OK’ #2724
Excess whitespace character — java.net.ProtocolException: Unexpected status line: ‘ HTTP/1.1 200 OK’ #2724
Comments
protected 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/") Call 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
The text was updated successfully, but these errors were encountered:
I think you should only build on ApiFiles instance, you do not need to create an instance every time you send a request.
droidlomg, I’m doing this. The problem is not this
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();
This is just an example of the fact that when you re-create Retrofit, everything works correctly
getRetrofit().create(ApiFiles.class).image(«name.jpg»).execute();
getRetrofit().create(ApiFiles.class).image(«name.jpg»).execute();
KursX , I haven‘t met this situation yet, but if as you say «If I add «Connection: close» header, everything gets fine» , My sugguestion is: add an interceptor, add header «Connection: close» after you ‘ve get a response. It may be possible to solve the problem temporarily.
droidlomg, I can not do this, since I have a large number of consecutive requests when I synchronize data. And the server keeps the connection. If it is interrupted after each request, the server load is unreasonably increased. Now it’s easier for me to copy the sources of the retrovit and clean up the extra space manually)
Ideally, I would like the developers of the library to clean up the buffer after processing the request, because I’m sure that the problem is this, but I still can not find where it should be done in order to offer a solution
me to,
i found this issue a week ago after update Android studio, im not sure about this fix, but suddenly work after adding
.registerTypeAdapterFactory(new YOUR TYPE ADAPTER)
i put that on gson builder, then use it on converter factory on retrofit builder.
in your code:
protected Retrofit getRetrofit()
protected Retrofit getRetrofit()
and also check your build tools version, i use «27.0.3»
i hope this help u
grats!
You should not be creating a new instance of your API, Retrofit, and OkHttp constantly. Create a single instance of each and re-use it everywhere. These objects are expensive to create and hold on to resources like sockets and files that you should not rely on the garbage collector to clean up. Adding Connection: close just pushes the problem farther out but eventually it will crash the very same way.
@JakeWharton , When re-used, an error occurs (java.net.ProtocolException). The problem is precisely this. I do not create a new instance of Retrofit constantly.
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();
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.
java.net.ProtocolException: Unexpected status line: HTTP/1.1 422��Unprocessable Entity
Your server appears to violate the HTTP spec. The status line is defined as follows:
The first line of a response message is the status-line, consisting of the protocol version, a space (SP), the status code, another space, a possibly empty textual phrase describing the status code, and ending with CRLF.
status-line = HTTP-version SP status-code SP reason-phrase CRLF
From the exception it appears that a non-space character (or two) is between the status code and reason phrase.
OkHttp is looking for ASCII spaces (character #32) between these elements. You can use something like WireShark or maybe Charles to intercept the network traffic and figure out what characters are being used by your HTTP server.
Related videos on Youtube
loeschg
Comments
02-05 04:45:13.981 15972-16249/com.myapp.android D/Retrofit﹕ ---> HTTP POST http://10.0.0.4:3000/api/v1/users/1/posts 02-05 04:45:13.981 15972-16249/com.myapp.android D/Retrofit﹕ Accept: application/json 02-05 04:45:13.981 15972-16249/com.myapp.android D/Retrofit﹕ Content-Type: application/json; charset=UTF-8 02-05 04:45:13.981 15972-16249/com.myapp.android D/Retrofit﹕ Content-Length: 150 02-05 04:45:13.981 15972-16249/com.myapp.android D/Retrofit﹕ 02-05 04:45:13.981 15972-16249/com.myapp.android D/Retrofit﹕ ---> END HTTP (150-byte body) 02-05 04:45:14.001 15972-15972/com.myapp.android W/EGL_genymotion﹕ eglSurfaceAttrib not implemented 02-05 04:45:14.017 15972-16249/com.myapp.android D/Retrofit﹕ ---- ERROR http://10.0.0.4:3000/api/v1/users/1/posts 02-05 04:45:14.017 15972-16249/com.myapp.android D/Retrofit﹕ java.net.ProtocolException: Unexpected status line: HTTP/1.1 422��Unprocessable Entity at com.squareup.okhttp.internal.http.StatusLine.parse(StatusLine.java:73) at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:187) at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80) at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:791) at com.squareup.okhttp.internal.http.HttpEngine.access$200(HttpEngine.java:90) at com.squareup.okhttp.internal.http.HttpEngine$NetworkInterceptorChain.proceed(HttpEngine.java:784) at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:645) at com.squareup.okhttp.Call.getResponse(Call.java:263) at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:219) at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:192) at com.squareup.okhttp.Call.execute(Call.java:79) at retrofit.client.OkClient.execute(OkClient.java:53) at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:326) at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220) at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265) at retrofit.RxSupport$2.run(RxSupport.java:55) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at retrofit.Platform$Android$2$1.run(Platform.java:142) at java.lang.Thread.run(Thread.java:841) 02-05 04:45:14.017 15972-16249/com.myapp.android D/Retrofit﹕ ---- END ERROR
compile 'com.squareup.retrofit:retrofit:1.9.0' compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0' compile 'com.squareup.okhttp:okhttp:2.2.0'
I get the expected result when sending via Postman (https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en) Edit: I’m making the following call in Rails to return this 422 result:
render json: @post.errors.to_json, status: :unprocessable_entity
Another Edit: Here’s a screenshot of the request being made via Wireshark. Nothing looks out of the ordinary, but I’ve also never used the tool before. Here’s the appropriate hex.