B4A Library OkHttp - Replaces the Http library

OkHttpUtils2 source code: [B4X] OkHttpUtils2 / iHttpUtils2 / HttpUtils2 source code
It is included as an internal library.
Usage: [B4X] OkHttpUtils2 with Wait For

The current Http library is based on the Android version of Apache HttpClient. Google has stopped updating this SDK a long time ago and they are removing it from Android M. This means that it is a good time now to switch to a different implementation.

Note that if you are using HttpUtils2 (as you should) it is also based on Http library.

The OkHttp library is based on the OkHttp SDK: http://square.github.io/okhttp/
As this is a newer SDK it supports new features such as SSL SNI, SPDY, Patch requests and better performance.

The OkHttp wrapper API is almost identical to Http library API. The main difference is that the object names start with Ok (OkHttpClient, OkHttpResponse and OkHttpRequest).

This library requires Android 2.3+.

Attached is a modified version of HttpUtils2 library (v2.12) that is based on OkHttp instead of Http.

If you want to use the new HttpUtils2 library you need to copy it to the internal libraries folder.

V1.01 - Compatible with B4J.
V1.00 - Adds support for digest authentication.

OkHttpUtils2 v2.20 is attached. It adds support for multipart requests.

Example:
B4X:
Dim j As HttpJob
j.Initialize("j", Me)
Dim fd As MultipartFileData
fd.Initialize
fd.KeyName = "file"
fd.Dir = File.DirAssets
fd.FileName = "image.png"
fd.ContentType = "image/png"
j.PostMultipart("http://...", CreateMap("param1": "value1"), Array(fd))

OkHttp and OkHttpUtils2 libraries are included in the IDE.
 
Last edited:

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is not so strange. Go over this blog: https://github.com/square/okhttp/wiki/HTTPS

SS-2015-10-01_13.21.37.png
 

corwin42

Expert
Licensed User
Longtime User
Anyway you can keep using the Http library for a long time. It does work on Android 6. You just need to reference android.jar from android-22 or below.
Unfortunately that is not possible if you want to use AppCompat library. The latest support libraries (v23 and up) will require that you compile with the corresponding android.jar. So for v23 support library you will have to compile against v23 android.jar.
 

scrat

Active Member
Licensed User
Longtime User
@Erel
I read the blog and I understood that the solution is with connectionspec (if the correct cipher is in Android).

From the same blog:

You can build your own connection spec with a custom set of TLS versions and cipher suites. For example, this configuration is limited to three highly-regarded cipher suites. Its drawback is that it requires Android 5.0+ and a similarly current webserver.

B4X:
ConnectionSpec spec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
CipherSuite.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256)
.build();

OkHttpClient client = ...
client.setConnectionSpecs(Collections.singletonList(spec));

But with okhttp-2.2.0 i can use api 23 and all websites works . This workaround is enough for me.

thank's
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Unfortunately that is not possible if you want to use AppCompat library. The latest support libraries (v23 and up) will require that you compile with the corresponding android.jar. So for v23 support library you will have to compile against v23 android.jar.
OkHttp library in most cases is better than the older Http library. There are sites that are not supported by Http library and are supported by OkHttp (SNI SSL for example).

The problem is only with sites that use SSL ciphers that are now obsolete.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
Can this new version of httputils2 return the headers? In the previous version a source code modification of the library was needed to do this. I desperately need this to get cookies out of a http response.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
You can change hc_ResponseSuccess to:
B4X:
Sub hc_ResponseSuccess (Response As OkHttpResponse, TaskId As Int)
   Dim job As HttpJob = TaskIdToJob.Get(TaskId)
   job.Tag = Response.GetHeaders
   Response.GetAsynchronously("response", File.OpenOutput(TempFolder, TaskId, False), _
     True, TaskId)
End Sub
The headers will be stored in the Tag property.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
The original Sub is
B4X:
Sub hc_ResponseSuccess (Response As OkHttpResponse, TaskId As Int)
    If Response.ContentLength = 0 Then
        CompleteJob(TaskId, True, "")
    Else
        Response.GetAsynchronously("response", File.OpenOutput(TempFolder, TaskId, False), _
            True, TaskId)
    End If
End Sub

So this has to be completely replaced?
 

Bryanne Vega

Member
Licensed User
Longtime User
okClient.Initialize("getCategories")
okClient.Execute(Session.requestAllCategories,1000)

Called but never actually calls fail or success, why?​
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Will it be delivered in the next Version of B4A as the only http lib (real replacement)?
It will never replace the Http library. It is shipped together with Http library.

@Bryanne Vega not sure where does this come from. Please start a new thread and provide more information (make sure to make the post more readable).
 

dieterp

Active Member
Licensed User
Longtime User
I'm getting the following error when I try build my app after upgrading to OkHttp and HttpUtils2. Can anyone please assist me with what I am doing wrong?

error: incompatible types: HttpUriRequestWrapper cannot be converted to OkHttpRequest
_hc.ExecuteCredentials(processBA,(anywheresoftware.b4h.okhttp.OkHttpClientWrapper.OkHttpRequest)(_job._getrequest()),_taskcounter,_job._username,_job._password);
 

Bryanne Vega

Member
Licensed User
Longtime User
I'm getting the following error when I try build my app after upgrading to OkHttp and HttpUtils2. Can anyone please assist me with what I am doing wrong?

error: incompatible types: HttpUriRequestWrapper cannot be converted to OkHttpRequest
_hc.ExecuteCredentials(processBA,(anywheresoftware.b4h.okhttp.OkHttpClientWrapper.OkHttpRequest)(_job._getrequest()),_taskcounter,_job._username,_job._password);

How are you calling ExecuteCredentials?

It should be: hc.ExecuteCredentials(YourOkHttRequestHere,TaskIDHere,UserHere,PasswordHere)

Could you also show (masked if necesary) your OkHttpRequest Obkect? It's better if you give a sample of your code, or else we would be analyzing blindly.
 

dieterp

Active Member
Licensed User
Longtime User
I have resolved the issue. In updating the OkHttpJob class I didn't copy something over correctly. Thanks for the assistance!
 

Kwame Twum

Active Member
Licensed User
Longtime User
Hi everyone, please after switching to the new httputils2 and okhttp, requests via PostString don't function as they should anymore.
This is the error I get when I attempt to compile together with a shot of the code. What could be wrong?

TooManyParameters.png
 

Kwame Twum

Active Member
Licensed User
Longtime User
Found the solution, I was using the rapid debugger... switched to legacy and it worked.
I don't understand why though.. o_O
Thanks Erel.
 

Bryanne Vega

Member
Licensed User
Longtime User
This happened on a POS Android device. 4.4.

B4X:
javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6e9f1d00: Failure in SSL library, usually a protocol error

error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x684a2ce0:0x00000000)

  at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:449)

  at com.squareup.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)

  at com.squareup.okhttp.Connection.connect(Connection.java:143)

  at com.squareup.okhttp.Connection.connectAndSetOwner(Connection.java:185)

  at com.squareup.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)

  at com.squareup.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)

  at com.squareup.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)

  at com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)

  at com.squareup.okhttp.Call.getResponse(Call.java:273)

  at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:230)

  at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:201)

  at com.squareup.okhttp.Call.execute(Call.java:81)

  at anywheresoftware.b4h.okhttp.OkHttpClientWrapper.executeWithTimeout(OkHttpClientWrapper.java:140)

  at anywheresoftware.b4h.okhttp.OkHttpClientWrapper.access$0(OkHttpClientWrapper.java:137)

  at anywheresoftware.b4h.okhttp.OkHttpClientWrapper$ExecuteHelper.run(OkHttpClientWrapper.java:185)

  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 java.lang.Thread.run(Thread.java:841)

Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6e9f1d00: Failure in SSL library, usually a protocol error

error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x684a2ce0:0x00000000)

  at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)

  at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:406)

  ... 19 more

Error: , javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6e9f1d00: Failure in SSL library, usually a protocol error

error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x684a2ce0:0x00000000), -1
 
Top