Android Retrofit Causes Socket Timeout Exception - android

I am making a POST call to a tomcat server running Struts2 using the retrofit library on an Android Galaxy S3 (/Nexus 7) device. The POST call fails. The tomcat log shows Socket timeout exception.
The same POST using the exact same headers done via curl does not have any issues. I verified that the data on the wire matches using charles proxy.
Any tips/ideas on debugging this issue.
The post call is as follows
#POST(Constants.URL_GET_ORDER_LIST_BASE)
void getCardOrderList(#Body GetOrderListRequest getOrderListRequest, Callback<GetOrderListResponse> cbGetOrderListResponse);
Please let me know if I need to add more information to explain this better.

Adding Square's OKHTTP library into the libs folder fixed the issue.

I was having SocketTimeoutExceptions too. Pay attention to always add the final slash to your POST call.
Example:
BAD
#POST("/customers")
GOOD
#POST("/customers/")
My mistake was just this :)

Related

OkHttp connection leak log line even when OkHttp is not a dependency

I keep seeing the following log line in Logcat while I use my app:
19098-19147/<package> W/OkHttpClient: A connection to <my server> was leaked. Did you forget to close a response body?
I did some research on this bug and found that it can happen when you do things like forget to close a response body in an interceptor. I commented out all of interceptors to see if one of them was causing this issue, but I still saw the log line. I eventually commented out all uses of OkHttp and I still somehow got the error. I even went as far as to removing all OkHttp dependencies from my Gradle file and added an explicit line to make sure that it was excluded as a transitive dependency. I ran gradle app:dependencies in order to generate my dependency tree so I could make sure that OkHttp was not included. Somehow I am STILL seeing this log line. I don't understand how this is possible.
Does anyone know of any common libraries that may have copied and pasted this log line out of the OkHttp library and into theirs? I searched all of the source code of my other dependencies, but didn't find a similar log line in any of them.
Could this have something to do with the new profiling code that Android Studio injects? See this article for more information.
Update: Turns out that my Fresco dependency must have been using OkHttp provided by the system or something like that. #Selvin commented that Android uses it internally. Anyways, apparently when Fresco receives an HTTP response with an error when trying to load an image (in my case HTTP response code 401), it logs this error. I don't see any good way for handling HTTP errors with Fresco/OkHttp. I opened the following issue with Fresco: HTTP error response when loading image results in leaked connection #1983
I know it's very late response but maybe anyone is still getting crazy with this issue and finally I found out what happened. Yes: OkHttp is used internally in HttpURLConnection/HttpsURLConnection components since Android 4.4 so you can get these boring messages in logcat, even if you're not using OkHttp library directly in your project.
The problem is generated by 2 factors:
the socket is reused by the urlConnection object, trying to
optmizing performances on multiple requests on the same host.
the response stream is not correctly closed (see below how to solve)
To prevent these log lines or simply take more control on the flow I made some changes to my code and finally solved this issue.
I disabled persistent connections setting Connection: close header. Default is Connection: keep-alive
Before reading the content (body) of the response, check the http response code. As well described in this article if the response code is >= 400 you got an unsuccess: you have not to read the connection InputStream getInputStream() but the ErrorStream getErrorStream() and close it by calling .close() method on the right stream. The connection leak is here. Finally remember to disconnect() the urlConnection object.

Tasker App: Why my HTTP POST is not sending parameters?

I'm making a simple HTTP POST request using Tasker app, it's working fine but somehow it's not sending my arguments. HTTP GET is working fine. What am I doing wrong?
The only thing the server does is JSON stringify all received parameters and return them like: Text: { parameters }
HTTP GET is working:
HTTP POST works, it returns the response "text: {}" but doesn't return any parameter:
Now sometimes it shows "Bad Request Error 400"
I've tested it with another server and this issue persists...
Here's a fiddle to send get and post requests to the same server and both work.
I've exported my task as xml for you to test: You can download it here
Thanks in advance guys!
I have done a little testing with what you have supplied. It appears that your post parameters are making it to the server but %HTTPR is not getting populated. The Tasker documentation says that this variable will be populated if the response is "text-based", but this does not seem to be the case. I may not know what Tasker considers to be "text-based", but I have tried "text/plain" and "text/html" with no luck.
The work-around that I have come up with is to put the response into a file using the "Output File" field of the post task. (Leave "Content Type" blank or this won't work.) You can then read the file into a variable and do what you need to.
This is either a defect in Tasker, incorrect documentation, or just a misunderstanding of what it takes to make it work. This work-around, however, will get you what you need.
Here is a link to a GitHub repository with the updated task export. You may need to change the output file name/location to work with your device.
Update:
Since I posted the above solution, I have run across a Tasker plugin called "RESTask for Tasker". Evidently, Tasker has enough issues with HTML requests that a separate plugin was needed. I have tested this plugin with POST and it does work, so this is another way to go. The plugin is available on the Google Play store.

Retrofit incorrect response error on android

When i call any webService with expired token,the service returns code 498 with error message "your tokken is expired"..BUT the retrofit gives the response code 500 with error message " internel server error".
response.code() //500 instead of 498
I tested the same url with postman and its working fine but the issue is only with retrofit.
I am using same services on IOS with AFNetworking and its also working fine there.
Any body can help to figure out why this is happening? thanks in advance.
This is not a full answer, but it's too big for a comment.
5xx codes are server errors, this means that the server is crashing, not the app nor is retrofit buggy. The issue most likely is in the server, but can be caused by retrofit - yes, that's true.
My experience with all the questions that say: "I tried this insert random network call here with postman and it works, but retrofit returns 500" is because postman adds headers by default, which retrofit doesn't. The server implementation then expects these headers to be set and due to a faulty implementation crashes if said headers are missing.
I would check the headers retrofit is sending and the headers postman is sending and compare both and make sure which one crashes the server.
It can also be that OkHttp (Retrofit uses OkHttp under the hood) is adding some headers which the server cannot cope with. This would be stranger to me, but not impossible. I think it adds for example by default gzip and some servers might not handle this correctly.
If you have access to the server, than it might even be worth checking there the logs. They might point you right away to the issue.
I'm sorry but I cannot point you directly to the problem. These are just tips to get you started. Hope they help.

android:--java.net.ProtocolException:Too many follow-up requests:21

I am trying to sync my app with the server (periodically,on-demand & when network outage happens),which uses the basic authentication for the syncing.Here i am facing this error.
Had done some research on this but found no solution.Have anyone come across this & have a solution???
PS:I am a novice developer in android.
I recommend double checking the method url that you are using.
For instance, can you run it using Postman or some other REST client and get a valid response?
This behavior happened in one of my project while I accidentally used a broken method URL but with a right host.
good luck:)

What is Apache-HttpClient/UNAVAILABLE error (Android, Google App Engine)?

I am confronting myself with a problem that I do not know how to interpret. I am doing a project using Android and Google App Engine. When I am trying to save information in Google App Engine's Big Table, directly from the servlet (hardcoded) - the save is performed with no problem. But when I am trying to save data from my Android device, the save is not performed and the log indicates Apache-HttpClient/UNAVAILABLE error. To be more specific:
405 55ms 0kb Apache-HttpClient/UNAVAILABLE (java 1.4)
82.155.246.249 - - [10/Jun/2013:05:20:59 -0700] "POST /servletnamehere HTTP/1.1" 405 306 - "Apache-HttpClient/UNAVAILABLE (java 1.4)" "appnamehere.appspot.com" ms=56 cpu_ms=21 cpm_usd=0.000034 app_engine_release=1.8.0 instance=00c61b117cede3f754aa1ece730dc88287a20199
I have seen that 405 HTTP error appears in the context of a POST method ( "405 errors often arise with the POST method. You may be trying to introduce some kind of input form on the Web site, but not all ISPs allow the POST method necessary to process the form." ) => indeed, I am trying to perform add (the object is a JPA Entity) in the database using a POST method. The data I am receiving from my Android device is serialized, through an input stream (in my case, working with JSON is not an option, these are the specifications).
Also, 306 HTTP error reffers to switch proxy. While the porevious error might be a bit intuitive, this one is beyond my student knowledge.
I have followed the instructions of this tutorial (http://trumpy.cs.elon.edu/joel/sigcse2011/), which is indeed what I need, but I really cannot figure out what I did wrong. I took again the procedure, stept by step, but I don't see the flaw.
Any help will be indeed appreciated. If I should post some code, I'll gladly do it.
Best wishes,
Cropcircles
LATER EDIT:
Now I get 417 HTTP error expectation failed. I have seen that I am supposed to set a certain parameter on false, but this workaround was available only for .NET. Is there anyone who knows what's the correspondent of the following, in Java? I am really really confused.
<system.net>
<settings>
<servicePointManager expect100Continue="false" />
</settings>
</system.net>
This is not an answer, but is too long for a comment and may be helpful, so here goes...
First, it's hard to tell what's going on here because there is limited info. Try to post more of the logging either on the client or on the server. Go to the server console and get more info, for instance, or add debugging in the client. I'd start by trying to make the POST from a debug/testing tool like hurl.it: http://www.hurl.it/ (hurl is a nice web front end to a command line HTTP client named curl, see curl itself if you want a more advanced peek). That way you can test and poke around and make SURE your server side works as you expect with a generic client. Then build other clients (like Android).
Second, "Apache-HttpClient/UNAVAILABLE" is not an error, it's just the user-agent String -- so ignore that part. (UNAVAILABLE is where the version typically is, but some impls don't have access to the version sometimes, it seems.)
Third, the 405 response code IS an error, it means POST is not allowed at the server you are trying to POST to. That can either be because POST is not allowed at all on said server, or you're violating some security policy (such as same origin).
If it's AppEngine, first check the APP you are using and make sure it supports POST (look for info on how to do POST at AppEngine to solve, for instance: google app engine: 405 method not allowed). When you say you can do it directly from a "servlet," do you mean that a POST from a different client works? (Servlet is a server side technology, so that's a little confusing.) If so then make sure your Android app is doing the client part the same way to the same host (multipart vs urlencoded, etc).
For a little more on the security stuff, which could be involved, see this post: Google App Engine + jQuery Ajax = 405 Method Not Allowed.
I've had the same trouble and in my case It was an error due to no write permission on server side area.
I was following an android test to write on a file a value transmitted in async way via POST method.
Apache received the POST request but was not able to write the data on the file due to security permission on it.

Categories

Resources