Handle redirects using Okhttp in Android - android

I make some http requests using Okhttp to download a JSON from my server.
For me and all my alpha testers everything works fine, but out in the wild I
experience some exceptions that occur, when I try to parse the response using
Gson.
As far as I understand the exceptions occur, because the connection gets redirected, in situations where the user is at an airport or using a limited
WIFI connection in an hotel etc.
The exception:
Exception java.lang.IllegalStateException: closed
okhttp3.internal.http.Http1xStream$FixedLengthSource.read (Http1xStream.java:378)
okio.Buffer.writeAll (Buffer.java:956)
okio.RealBufferedSource.readByteArray (RealBufferedSource.java:92)
okhttp3.ResponseBody.bytes (ResponseBody.java:83)
okhttp3.ResponseBody.string (ResponseBody.java:109)
[xxxx].BackendFilter.handleResponse (BackendFilter.java:131)
[xxxx].BackendFilter.access$300 (BackendFilter.java:30)
[xxxx].BackendFilter$2.onResponse (BackendFilter.java:114)
okhttp3.RealCall$AsyncCall.execute (RealCall.java:133)
okhttp3.internal.NamedRunnable.run (NamedRunnable.java:32)
java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1133)
java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:607)
java.lang.Thread.run (Thread.java:762)
From my logs in firebase I can see that the URL of the response is different
to the URL I used to set in the request.
i.e. I get: http://www.tunisietelecom.tn/tt/themes/html/TT_Theme/infosolde.html
It basically says:
Dear Customer,
Your plan is exhausted, to continue to benefit from your INTERNET
offer, dial * 140 # for packages via your phone or * 145 # for Data
key packages.
So I assume this specific user got redirected, because his data package
got expired.
The response code nevertheless is a 200 and my application tries to parse
the response body, which fails obviously. Not with the excepetion I
expected, but it fails anyhow. (Can anybody explain to me, why this excepetion
occurs. rather than a Gson JsonSyntaxException?)
I read multiple articles on stackoverflow and did a google search beforehand,
but can anybody tell me how to handle this kind of redirects?
What is the best approach to smoothly dismiss this request, if I (how?)
recognize a redirect.
tl;dr
My approach now would be to disable redirects in the first place by setting OkHttpClient client = new OkHttpClient().newBuilder().followRedirects(false).followSslRedirects(false).build();, but I am not sure (and familar with this topic), if there are
situations where redirects are total fine and I want to allow them.
The next approach, without disabling redirects would be to investigate the
response. If the method response.isRedirect() returns true and the
url of the request (response.request.url()) is any different from
my requested url, I would smoothly dismiss the request.
Is any of these approaches suitable? Are there better strategies to handle
these kind of redirects? Does the exception really occur because of a
redirect?
Thank you all in advance!

Related

SendLogsRequestListener failure in worklight

I am re-implementing an existing worklight system. We have already have a hybrid version. We have decided to re-implement the Client side in pure native. The native client seems work fine.
However, the server seems to be quite unstable - sometimes we don't get a server response after invoking an adapter, sometimes we do get. I have checked the DDMS/Android console. And a Error/Exception was found. Any comments would be appreciated!
com.worklight.common.Logger$SendLogsRequestListener(4274): Logger$SendLogsRequestListener.onFailure in Logger.java:1726 :: Failed to POST data from file /data/data/${APP_NAME}/files/analytics.log.0.send due to: HTTP response code: 500
On a successful adapter call or WLClient connection to the server, the client will attempt to automatically send logs to the server. It looks like something bad is happening on the autosend for adapters. A temporary workaround would be to disable this auto sending behavior by calling
WL.Logger.setAutoSendLogs(false)
But you can only use this call if you do not wish for logs to be sent automatically. If you do wish to have this working properly, I'd suggest opening a PMR so that it can be determined if this is an error in your application or an actual defect.

Fehler (error) 6 - the requested item could not be loaded

Currently I'm developing android application that needs to connect itself to REST API. It is crucial for my app to access API whenever connection is possible (mobile data/wifi).
But when testing my app something extremely weird happened. Application works as expected almost all the time, but when on VipMobile operator (Austria telekom group) I cannot connect to API.
At first I didn't get it, error was too unreadable. It says
j u fehler6 the requested item could not be loaded & wrong mime type
There are a lot of unprintable chars in that message too. When i figured out that it is operator fault i tried to copy link to my API and got this.
What could that possibly be? Can anyone point me in any direction, I cannot publish application as long as there are those ridickulous errors.
This happens when the user is on 3g connection. Some mobile operators intercept clients request and if the Content-Type is not good, or not defined they display page like this. This happens also to vipmobile operator in Serbia.
Try to add right content-type to response headers on your server side.
Try to put for example Content-Type:text/plain;charset=utf-8 to headers

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.

Occasional SocketTimeoutException -- No "OK" message from server

I am currently using the DefaultHttpClient to create an HTTP request to a rails server.
The network call is failing about 4% of the time with a SocketTimeoutException.
I have run Wireshark on my network traffic and discovered the following:
My successful call starts like this
And ends like this
The failed call starts like this:
And ends like this
Please note that the HTTP OK message that is sent to us from the server is missing from the end call, resulting in it timing out after about 15 seconds.
I am wondering if anybody has encountered this before or has any recommendations for debugging the Android Apache library or Apache rails to figure out why we are not receiving the HTTP OK message from the server.
I figured this out. The rails server and apache library were timing out if there were bad parameters in my post request. We were passing in a "_b" parameter, and for some unknown reason the server wouldn't like this and would time out the request. Removing the bad post parameter fixed the problem.
If anybody else is seeing timeouts like this, I recommend reviewing the POST parameters that are being passed in.

Check HTTP request against reliable server

In my android app i keep getting timeouts in the messages between the app and my server.
In an attempt to see if the problem is in the app or my server,
i want to try and Send an HTTP request from my app to
some other server i am sure is up and reliable and then see if i get timeouts.
Is there any server address i can check against?
Thanks in advance!
BTW : i am using a glass Fish servlet for my server
We've successfully sent a simple HTTP GET to google.com -- with a couple of fall-backs (I've also seen internic.org used) in the past, in similar cases.

Categories

Resources