I'm trying to set up SSL (with SSL resumption) using HttpsURLConnection with my own trust manager.
I am only able to perform ssl handshakes and connections. No SSL resumption - The previous sessions are never reused!
I searched all over, but no luck.
All answers refer to HttpClient (which is not an option).
My setup is as follows:
I create an SSL Context which I store for later use.
I then create an SSL Factory using this SSL context which I also store for it to be used with all connections.
I start a connection where everything goes well:
I receive a sessionID, a complete handshake is done and the connection is sent to the server.
One minute later, I start another connection. For some weird reason, this connection does not send the sessionID I had earlier.
I print the SSLContext's session - The last session is still there and is valid.
For some reason this new connection does not use it, thus another session is created and is added to the sessions' cache.
I tried both android version 2.3 and 4.1 as well on 2 different devices.
Following many google results I even tried to add Keep-Alive as some users proposed, as well as other voodoo that led to no different results.
Did anyone run into this? Is there something I'm missing?
What could cause my connections not to use the last session?
Thanks in advance!
What you'd like to do is use reflection to override members in class android.net.SSLCertificateSocketFactory, the members are:
HOSTNAME_VERIFIER
mTrustManagers
mKeyManagers
Do it by getting the class:
Class<?> sslClass = Class.forName("android.net.SSLCertificateSocketFactory");
Field classField = sslClass.getDeclaredField("defaultTrustManager");
classField.setAccessible(true);
classField.set(null /*If Feild is static*/, youObjectHere /*Needs casting*/);
classField.set(objectInstance /*If Feild is not static*/, youObjectHere /*Needs casting*/);
and then:
Override these with you own variables. This will allow for SSL resumption for Android API 14 and above (I tested on 14).
BEWARE
You'd need to maintain this code and keep up with any changes Google might do.
Hope it helped! Good luck!
Related
I am developing a voice chatting app based on webRTC using android libjingle.I want to reconnect users by using ice restart when they change their network from wifi to 4g or vice versa, or are disconnected. I have a question about implementing it by using libjingle. I will write down how to implement ice restart function based on what I understood so let me know there is anything wrong.
Q: As I understand, at first I need to set ice start option to be true in the MediaConstraints option without removing peer connection 객체 used for the first connection like below:
mediaConstraints.optional.add(new MediaConstraints.KeyValuePair("IceRestart", "true"));
Secondly, I need to update MediaConstrants using the peer connection 객체(used for the first connection)'s updateIce method like below:
peerConnection.updateIce(iceServers, mediaConstraints);
And finally is it right to send an offer, which is the same with basic webrtc network?
I want to double check whether I understand well. And if there is something wrong in what I've written, please let me know!!
For doing ice restart, sender should send SDP file with different ice-pwd or ice-ufrag.
IceRestart option forces PeerConnection to update those values.
Steps should be:
Put additional constraint:
cons.mandatory.add(new MediaConstraints.KeyValuePair("IceRestart", "true"));
Generate sdp file:
pc.createOffer(new WebRtcObserver(callbacks), cons);
Set resulted sdp to PeerConnection:
pc.setLocalDescription(new WebRtcObserver(callbacks), sdp);
Send it to remote peer.
So steps 2-4 are the same as for regular offer.
i am trying to develop a cordova(3.5.0) project in android platform and in that i have to check network connection availability before each API call. for that i am using 'navigator.connection.type',and some times it return 0. why this is happening? plz help me for solving this trouble
Without some more details I can only guess.. There are some conditions which may cause this.
navigator.connection.type = 0 -> connection type unknown.
So you may have a connection, you may not it simply hasn't been determined yet, or because of privileges the device isn't saying.
Are you calling this check too early? ie before deviceready
In our app we do not check the connection each time but we handle it this way:
by making the API request anyway, knowing that its possible to fail, we set a timeout and error handling. If it fails by error or timeout we check connection type and then ping the server with a simple "hello" "acknowledge" request. Its a super small request that we figure will work or if it timeouts again the connection must be so poor it might as well be disconnected.
This is because there are really two types of connection you need to check. Many miss this!
And also because its navigator totally lies some times... :/
Just because wifi is on and connected and navigator tells you this, it doesn't mean you will have a connection to the outside world. You need to check the network hardware (which is all navigator will tell you) but you must also check network connectivity, if this is something you are sensitive about.
My app needs to contact the same device it is working on, via http://127.0.0.1/... (a localhost url).
For some reason, about 50% of the times (and maybe exactly 50%) when I reach a website there with JSON content, I get the exception:
java.net.SocketException: recvfrom failed: ECONNRESET (Connection reset by peer)
For the other 50%, I get perfectly good results. I've tried to do polls (and even large delay between polls), but I keep getting the same weird results.
I've searched the internet and also here, and I'm not sure why it occurs. Does the peer mean that the client has caused it? Why does it happen, and how should i handle it?
Some websites say that it's a common thing, but I didn't find what's the best thing to do in such cases.
Ok, the answer was that it's the server's fault - it had to close the connection after each request.
It might be that Android keeps a pool of connections and use the old one or something like that.
Anyway , now it works.
EDIT: according to the API of HttpURLConnection, this can be solved on the client side too:
The input and output streams returned by this class are not buffered.
Most callers should wrap the returned streams with BufferedInputStream
or BufferedOutputStream. Callers that do only bulk reads or writes may
omit buffering. When transferring large amounts of data to or from a
server, use streams to limit how much data is in memory at once.
Unless you need the entire body to be in memory at once, process it as
a stream (rather than storing the complete body as a single byte array
or string).
To reduce latency, this class may reuse the same underlying Socket for
multiple request/response pairs. As a result, HTTP connections may be
held open longer than necessary. Calls to disconnect() may return the
socket to a pool of connected sockets. This behavior can be disabled
by setting the http.keepAlive system property to false before issuing
any HTTP requests. The http.maxConnections property may be used to
control how many idle connections to each server will be held.
Taken from:
developer.android.com/reference/java/net/HttpURLConnection.html
Try to set this property for your HttpURLConnection before connecting:
conn.setRequestProperty("connection", "close");
This will disable "keep-alive" property which is on by default.
This is an old thread i know. But this might help someone.
In my case this error was caused by the .NET WCF (soap) service. One of the objects in the returning result had a DataMember with get{} property but no set{} property.
For serialization to occur every DataMember should have both get{} & set{} available. I implemented an empty set{} (empty due to my business rules), and problem was solved.
My scenerio is a specific bad server implementation, but maybe it'll help someone saving time when troubleshooting.
I was having a lot of these Connection reset by peer when I was visiting certain web pages or downloading files (from my app or the Android browser).
Turned out it was my 3G carrier that blocked the connections (e.g. downloading an .exe file was forbidden).
Do you have the same problem on Wifi ?
in my situation the problem has been solved by cleaning the proxy address and port from APN which was produced by the operator.
as I have tested, using IP address of remote server instead of domain name also can solve the problem.
In our case the issue is in the Server side (Application Pool configuration in IIS). I resolved it by setting Maximum Worker Processes to 1. Setting it with value more than 1 will enable Web Garden which seems to be the issue.
I am facing an interesting problem with HTTPUrlConnection on Android.
Here are the steps
1. Create a new HTTPUrlConnection with a particular url say URL
2. Now I change the APN settings on device level
3. Now I create another HTTPUrlConnection with the same URL.
When trying to read input steam after step 3, connection times-out.
Another interesting thing is When I change the URL in step 3 everything seems to work fine
One reason I can think of can be Android somehow keeps previous connection alive and returns me the same connection in step 3 and since the APN is changed, that connection is no more valid.
Any Insights in this will be greatly appreciated.
Thanks,
Manan
One reason I can think of can be Android somehow keeps previous connection alive and returns me the same connection in step 3 and since the APN is changed, that connection is no more valid.
That is a very distinct possibility. Android added keep-alive support to HttpUrlConnection. Normally, APN settings don't change (AFAIK), so this may not be a big problem. However, you can disable keep-alive via System.setProperty("http.keepAlive", "false");, according to this Android Developer Blog post.
I perform some large downloads. I start a download being connected to 3G, all is fine. Then, I switch to WiFi connection, but the request returns a timeout exception. I have used HttpClient library. I have implemented a retry mechanism, so, when the request returns an exception, it sleeps for 0.5 seconds and tries to execute again and again. I would expect that, after connecting to a WiFi, the Http request could execute. But it seems that the Http execute method returns a null response, all the time after that. Very strange, if I commute again to 3G, the execute method returns again a good response. Can anyone help me please :) ?
First, it seems that it may be more convenient to use DownloadManager for large files - it handles retry and everything.
As for HttpClient - it's known to have some issues, but i'm not sure if you bumped into one of them or just overlooked something. It's been deprecated as of Gingerbread, you may want to try HttpUrlConnection instead, it's said to have less problems than HttpClient.
Also, when switching between WIFI and cell connections, HttpClient may need to be reinitialized completely, there's http range header to tell server which byte you want to continue downloading from. But again, I suggest you give DownloadManager a try, it may save you a lot of time.
This might be a routing problem:
when switching between different network types usually the local ip address and, more important, the local routing table changes, due to a different gateway being used. This means that packages that traveled fine between client and server wont reach any destination after a network change, if they are send the same route. Most likely your client implementation has to be notified of the change or even restartet completely, so that the routing strategy is reinitilized.
If the documentation of the implementation components you use dont reveal anything you could try to track this down using a package sniffer like wireshark. Typically packages running into nirwhana show up easily there.