smallseo.info

okhttp

An HTTP+SPDY client for Android and Java applications. OkHttp an http & spdy client for android and java applications

How to set connection timeout with OkHttp

I am developing app using OkHttp library and my trouble is I cannot find how to set connection timeout and socket timeout.

   OkHttpClient client = new OkHttpClient();

   Request request = new Request.Builder().url(url).build();

   Response response = client.newCall(request).execute();

Thanks.


Source: (StackOverflow)

How to implement cookie handling on Android using OkHttp?

Using OkHttp by Square https://github.com/square/okhttp, how can I:

  1. Retrieve a cookie returned from the server
  2. Store the cookie for upcoming requests
  3. Use the stored cookie in subsequent requests
  4. Update the cookie returned by the subsequent request

Ideally the cookie would be stored, resent and updated automatically with every request.


Source: (StackOverflow)

Is it possible to disable following redirects in OkHttp 2.0?

In Android, I'd like to use the new OkHttp 2.0 to request some URLs, but I'd like more control over redirects. I've already found the option to enable or disable following HTTPS → HTTP or HTTP → HTTPS redirects, but I'd like to not follow any redirects, so I can update my GUI as soon as possible, and choose whether to follow them from application logic. I don't see an option to do this. Is it possible, and if so, how can I achieve this?


Source: (StackOverflow)

NoSuchMethodError if i am using okhttp 2.0 and the latest retrofit?

Could not find method com.squareup.okhttp.OkHttpClient.open, referenced from method retrofit.client.OkClient.openConnection.

below is my gradle config

compile 'com.squareup.okhttp:okhttp:+'
compile 'com.squareup.okhttp:okhttp-urlconnection:+'
compile 'com.squareup.retrofit:retrofit:+'

Source: (StackOverflow)

Android Picasso library, How to add authentication headers?

I have tried setting a custom OkHttpClient with a custom Authenticator, however as the doc says: "Responds to authentication challenges from the remote web or proxy server." I have to make 2 requests for each image, and that is not ideal.

Is there a request interceptor like Retrofit does? Or am I missing something in the OkHttpClient?

I'm using the latest versions:

compile 'com.squareup.picasso:picasso:2.3.2'
compile 'com.squareup.okhttp:okhttp:2.0.+'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.0.+'
compile 'com.squareup.okio:okio:1.0.0'

Thanks!


Source: (StackOverflow)

Image adapter leaking memory

I have a simple ListActivity that shows images and I inizialize my OkHttpClient for Picasso Builder in the constructor of the ImageAdapter class:

picassoClient = new OkHttpClient();
picassoClient.interceptors().add(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request newRequest = chain
            .request()
            .newBuilder()
            .addHeader("Cookie","xyz")
            .build();

        return chain.proceed(newRequest);
    }
});

new Picasso.Builder(context).downloader(new OkHttpDownloader(picassoClient)).build();

then in getView() I use Picasso to load images in ImageView:

Picasso.with(context).load(xyzUrl).fit().centerCrop().into(vImage);

It works well, but on device's rotation i see that heap size sometimes slowly grows, sometimes quickly and sometimes remains stable. Only rarely it drops. Am i leaking memory or is there something wrong in code?

EDIT: I inserted this code after Picasso's call in the getView()

if (BuildConfig.DEBUG) {
    Log.i("HEAP SIZE",
    String.valueOf((Runtime.getRuntime().totalMemory() / 1024)
    - (Runtime.getRuntime().freeMemory() / 1024)));
}

and I found that the heap size's growth happens in the getView() after loading bitmap into ImageView. What is wrong?

EDIT 2: tried to set static ImageAdapter, nothing changes

EDIT 3: tried with RecyclerView instead of ListView, same behavior: heap size grows continuously while scrolling image list stepping by 30-40 bytes at every onBindViewHolder(). After device's rotation heap size grows sometimes stepping by even 2-3 Mbytes. Rarely it drops.

Why heap size slowly but continuously grows and why am I leaking some cache or some cached bitmaps after device's rotation?

UPDATE: tried adapter without the code in the constructor (that is without new OkHttpClient and new Picasso.Builder), it works and the heap size now drops well remaining stable. Then, what is the correct way to initialize the client with cookies headers management?

UPSHOT: finally I created my PicassoInstance class, which creates a unique static Picasso singleton and set it as the Picasso Library's singleton. Then I set it in my adapter constructor

PicassoInstance.setPicassoSingleton(context);

It works well, and it is a correct way I hope.

public class PicassoInstance {
private static Picasso myPicassoInstance = null;

public static void setPicassoSingleton(Context context) {
    if (myPicassoInstance == null) {
        myPicassoInstance = createMyPicassoInstance(context);
        Picasso.setSingletonInstance(myPicassoInstance);
        if (BuildConfig.DEBUG) {
            Log.i("PICASSO INSTANCE", "CREATED");
        }
    }
}

private static Picasso createMyPicassoInstance(Context context) {
    OkHttpClient myOkHttpClient = new OkHttpClient();
    myOkHttpClient.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request newRequest = chain.request().newBuilder()
                    .addHeader("Cookie", "xyz").build();
            if (BuildConfig.DEBUG) {
                Log.i("ON INTERCEPT", "COOKIE ADDED");
            }
            return chain.proceed(newRequest);
        }
    });

    return new Picasso.Builder(context).downloader(
            new OkHttpDownloader(myOkHttpClient)).build();
}

}


Source: (StackOverflow)

Trusting all certificates with okHttp

For testing purposes, I'm trying to add a socket factory to my okHttp client that trusts everything while a proxy is set. This has been done many times over, but my implementation of a trusting socket factory seems to be missing something:

class TrustEveryoneManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }

    @Override
    public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { }

    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }
}
OkHttpClient client = new OkHttpClient();

final InetAddress ipAddress = InetAddress.getByName("XX.XXX.XXX.XXX"); // some IP
client.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipAddress, 8888)));

SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = new TrustManager[]{new TrustEveryoneManager()};
sslContext.init(null, trustManagers, null);
client.setSslSocketFactory(sslContext.getSocketFactory);

No requests are being sent out of my app and no exceptions are getting logged so it seems that it's failing silently within okHttp. Upon further investigation, it seems that there is an Exception being swallowed up in okHttp's Connection.upgradeToTls() when the handshake is being forced. The exception I'm being given is: javax.net.ssl.SSLException: SSL handshake terminated: ssl=0x74b522b0: SSL_ERROR_ZERO_RETURN occurred. You should never see this.

The following code produces an SSLContext which works like a charm in creating an SSLSocketFactory that doesn't throw any exceptions:

protected SSLContext getTrustingSslContext() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
    final SSLContextBuilder trustingSSLContextBuilder = SSLContexts.custom()
            .loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true; // Accepts any ssl cert whether valid or not.
                }
            });
    return trustingSSLContextBuilder.build();
}

The issue is that I'm trying to remove all Apache HttpClient dependencies from my app completely. The underlying code with Apache HttpClient to produce the SSLContext seems straightforward enough, but I'm obviously missing something as I cannot configure my SSLContext to match this.

Would anyone be able to produce an SSLContext implementation which does what I'd like without using Apache HttpClient?


Source: (StackOverflow)

Okhttp response callbacks on the main thread

I have created a helper class to handle all of my http calls in my app. It is a simple singleton wrapper for okhttp that looks like this (I have omitted some unimportant parts):

public class HttpUtil {

    private OkHttpClient client;
    private Request.Builder builder;

    ...

    public void get(String url, HttpCallback cb) {
        call("GET", url, cb);
    }

    public void post(String url, HttpCallback cb) {
        call("POST", url, cb);
    }

    private void call(String method, String url, final HttpCallback cb) {
        Request request = builder.url(url).method(method, method.equals("GET") ? null : new RequestBody() {
            // don't care much about request body
            @Override
            public MediaType contentType() {
                return null;
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {

            }
        }).build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Request request, Throwable throwable) {
                cb.onFailure(null, throwable);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                if (!response.isSuccessful()) {
                    cb.onFailure(response, null);
                    return;
                }
                cb.onSuccess(response);
            }
        });
    }


    public interface HttpCallback  {

        /**
         * called when the server response was not 2xx or when an exception was thrown in the process
         * @param response - in case of server error (4xx, 5xx) this contains the server response
         *                 in case of IO exception this is null
         * @param throwable - contains the exception. in case of server error (4xx, 5xx) this is null
         */
        public void onFailure(Response response, Throwable throwable);

        /**
         * contains the server response
         * @param response
         */
        public void onSuccess(Response response);
    }

}

Then, in my main activity, I use this helper class :

HttpUtil.get(url, new HttpUtil.HttpCallback() {
            @Override
            public void onFailure(Response response, Throwable throwable) {
                // handle failure
            }

            @Override
            public void onSuccess(Response response) {
                // <-------- Do some view manipulation here
            }
        });

onSuccess throws an exception when the code runs :

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

From my understanding, Okhttp callbacks run on the main thread so why do I get this error ?

** Just as a side note, I have created HttpCallback interface to wrap Okhttp's Callback class because I wanted to change the behaviour of onResponse and onFailure so I could unite the logic of handling failed responses due to i/o exception and failed responses due to server problems.

Thanks.


Source: (StackOverflow)

How to add parameters to api (http post) using okhttp library in Android

In my Android application, I am using okHttp library. How can I send parameters to the server(api) using the okhttp library? currently I am using the following code to access the server now need to use the okhttp library.

this is the my code:

httpPost = new HttpPost("http://xxx.xxx.xxx.xx/user/login.json");
nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("email".trim(), emailID));
nameValuePairs.add(new BasicNameValuePair("password".trim(), passWord));
httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
String response = new DefaultHttpClient().execute(httpPost, new BasicResponseHandler());

Source: (StackOverflow)

How to configure the Http Cache when using Volley with OkHttp?

I want to try Volley combining with OkHttp but Volley cache system and OkHttp both rely on the HTTP cache as defined in the HTTP specification. So how can be disabled the cache of OkHttp for keeping one copy of HTTP cache?

EDIT: what I have done

public class VolleyUtil {
    // http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/
    private volatile static RequestQueue sRequestQueue;

    /** get the single instance of RequestQueue **/
    public static RequestQueue getQueue(Context context) {
        if (sRequestQueue == null) {
            synchronized (VolleyUtil.class) {
                if (sRequestQueue == null) {
                    OkHttpClient client = new OkHttpClient();
                    client.networkInterceptors().add(new StethoInterceptor());
                    client.setCache(null);
                    sRequestQueue = Volley.newRequestQueue(context.getApplicationContext(), new OkHttpStack(client));
                    VolleyLog.DEBUG = true;
                }
            }
        }
        return sRequestQueue;
    }
}

Which OkHttpClient is referenced from https://gist.github.com/bryanstern/4e8f1cb5a8e14c202750


Source: (StackOverflow)

Is Retrofit+Okhttp using httpCaching as a default in Android?

I use retrofit and okhttp in one of our applications.

I can't really find a good explanation for the default behaviour of Retrofit.

If Okhttp is on the class path it will be automatically used. But as far as I can see it the default HttpResponseCache is null.

Do I need to explicitly enable caching with Retrofit and Okhttp?


Source: (StackOverflow)

Retrofit connection failure returns RetrofitError.response as null

Using Retrofit 1.6.0, OkHTTP 2.0.0, and OkHTTP-UrlConnection 2.0.0.

I am doing a POST to a service using Retrofit to a URL that does not exist. The failure callback is called, as expected. However, the RetrofitError parameter does not have a response. I would really like to grab the HTTP status code that was returned by using

error.getResponse().getStatus()

but since getResponse() returns null, I can't.

Why is getResponse() null and how can I get the status?

Thanks.

Also, the error I am receiving is UnknownHostException, as expected. Repeat: I am expecting this error. I want to know how to get the HTTP status code or why error.getResponse() returns null.

Edit: Here's some code:

RestAdapterBuilderClass.java
    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://badURL.DoesntMatter/");
            .setRequestInterceptor(sRequestInterceptor)
            .setLogLevel(RestAdapter.LogLevel.FULL)
             .build();
    sService = restAdapter.create(ServiceInterface.class);

ServiceInterface.java
    @POST("/Login")
    void login(@Body JsonObject body, Callback<String> callback);

CallbackClass.java
    @Override
    public void failure(RetrofitError error) {
        if (error.getResponse() == null) {

            // error.getResponse() is null when I need to get the status code
            // from it.

            return;
        }
    }

Source: (StackOverflow)

OkHttp how to log request body

I'm using an interceptor, and I would like to log the body of a request I'm making but I can't see any way of doing this.

Is it possible ?

public class LoggingInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();

        long t1 = System.nanoTime();
        Response response = chain.proceed(request);
        long t2 = System.nanoTime();

        double time = (t2 - t1) / 1e6d;

        if (request.method().equals("GET")) {
            Logs.info(String.format("GET " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), response.code(), response.headers(), response.body().charStream()));
        } else if (request.method().equals("POST")) {
            Logs.info(String.format("POST " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), request.body(), response.code(), response.headers(), response.body().charStream()));
        } else if (request.method().equals("PUT")) {
            Logs.info(String.format("PUT " + F_REQUEST_WITH_BODY + F_RESPONSE_WITH_BODY, request.url(), time, request.headers(), request.body().toString(), response.code(), response.headers(), response.body().charStream()));
        } else if (request.method().equals("DELETE")) {
            Logs.info(String.format("DELETE " + F_REQUEST_WITHOUT_BODY + F_RESPONSE_WITHOUT_BODY, request.url(), time, request.headers(), response.code(), response.headers()));
        }

        return response;
    }
}

and the result :

POST  [some url] in 88,7ms
    ZoneName: touraine
    Source: Android
    body: retrofit.client.OkClient$1@1df53f05 <-request.body().toString() gives me this, but I would like the content string
    Response: 500
    Date: Tue, 24 Feb 2015 10:14:22 GMT
    body: [some content] 

Source: (StackOverflow)

Does android use okhttp internally?

This is a stack trace I get when running an android app I recently inherited. We're not using okhttp as an explicity dependency, and the com.android.okhttp in the trace makes me think the aosp is using okhttp now internally?

java.lang.Throwable: Explicit termination method 'close' not called
                        E      at dalvik.system.CloseGuard.open(CloseGuard.java:184)
                        E      at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:278)
                        E      at com.android.okhttp.Connection.upgradeToTls(Connection.java:146)
                        E      at com.android.okhttp.Connection.connect(Connection.java:107)
                        E      at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
                        E      at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
                        E      at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
                        E      at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
                        E      at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
                        E      at com.android.okhttp.internal.http.HttpURLConnectionImpl.getHeaderField(HttpURLConnectionImpl.java:143)
                        E      at java.net.URLConnection.getHeaderFieldInt(URLConnection.java:544)
                        E      at java.net.URLConnection.getContentLength(URLConnection.java:316)
                        E      at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getContentLength(HttpsURLConnectionImpl.java:18
                           2)

Source: (StackOverflow)

How to get response body to retrofit exception?

I am trying to connect to rest service via retrofit in android application. I am getting responses. But when there is some error response from the service, conversion exception occurs and now I want to do some actions based on the response body. But I am getting response body as NULL. But retrofit log has a error message. Why is this happening.

04-14 18:57:35.686: D/Reftofit log(24856): OkHttp-Received-Millis: 1397527055676
04-14 18:57:35.686: D/Reftofit log(24856): OkHttp-Response-Source: NETWORK 200
04-14 18:57:35.686: D/Reftofit log(24856): OkHttp-Sent-Millis: 1397527055492
04-14 18:57:35.686: D/Reftofit log(24856): Server: Apache/2.2.22 (Ubuntu)
04-14 18:57:35.686: D/Reftofit log(24856): X-Powered-By: PHP/5.3.10-1ubuntu3.10
04-14 18:57:35.701: D/Reftofit log(24856): {"result":"Invalid Token ID"}

Code:

  public void failure(RetrofitError arg0) {
                String response = null;

                TokenError r = (TokenError) arg0
                        .getBodyAs(TokenError.class);
                response = r.getErrorDetails();

                Log.e(TAG, response);
                if (response != null
                        && response.contains("Invalid Token ID"))
                    GroupDataProvider.getInstance().onFailure();

            }
        };

Here I am getting r as NULL. I don't know why? Do I need to set something with rest adapter so that the response will be passed to retrofit error object.


Source: (StackOverflow)