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)

Retrofit 1.9 with OkHttp 2.2 and interceptors

I thought that these recent versions were supposed to be compatible. There is this tweet; https://twitter.com/JakeWharton/status/553066921675857922 and the changelog of Retrofit 1.9 mentions it too.

However when I try this:

        OkHttpClient httpClient = new OkHttpClient();
        httpClient.interceptors().add(new TokenExpiredInterceptor());

        mRestAdapter = new RestAdapter.Builder()
                .setEndpoint(API_ENDPOINT)
                .setClient(httpClient)
                .setLogLevel(BuildConfig.DEBUG ?
                        RestAdapter.LogLevel.FULL :
                        RestAdapter.LogLevel.NONE)
                .setRequestInterceptor(new AuthorizationInterceptor())
                .build();

It still doesn't work. The setClient method complains about an incompatible Client object;

Error:(29, 21) error: no suitable method found for setClient(OkHttpClient)
method Builder.setClient(Client) is not applicable
(argument mismatch; OkHttpClient cannot be converted to Client)
method Builder.setClient(Provider) is not applicable
(argument mismatch; OkHttpClient cannot be converted to Provider)

What am I missing? I also see OkHttpClient does not implement the Client interface.

I am using this approach for now; https://medium.com/@nullthemall/execute-retrofit-requests-directly-on-okhttp-2-2-7e919d87b64e

Did I misinterpret the changelog? Maye Retrofit 1.9 can uses OkHttpClient 2.2 when it's in the classpath but the interface isn't adapted yet?


Source: (StackOverflow)

Retrofit + Okhttp cancel operation not working

I am using retrofit in my application like this

 final OkHttpClient okHttpClient = new OkHttpClient();
 okHttpClient.interceptors().add(new YourInterceptor());

            final OkClient okClient = new OkClient(okHttpClient);
            Builder restAdapterBuilder = new RestAdapter.Builder();
            restAdapterBuilder.setClient(okClient).setLogLevel(LogLevel.FULL)
                    .setEndpoint("some url");
            final RestAdapter restAdapter = restAdapterBuilder.build();


public class YourInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        // TODO Auto-generated method stub
        Request request = chain.request();

        if (request != null) {
            Request.Builder signedRequestBuilder = request.newBuilder();
            signedRequestBuilder.tag("taggiventorequest");
            request = signedRequestBuilder.build();
            request.tag();
        }
        return chain.proceed(request);
    }
}

after sending request i am calling

okHttpClient.cancel("taggiventorequest");

but request is not cancelling i am getting the response from retrofit dont know why it is not cancelling my request

I need volley like cancelation retrofit


Source: (StackOverflow)

How to retry HTTP requests with OkHttp/Retrofit?

I am using Retrofit/OkHttp (1.6) in my Android project.

I don't find any request retry mechanism built-in to either of them. On searching more, I read OkHttp seems to have silent-retries. I don't see that happening on any of my connections (HTTP or HTTPS). How to configure retries with okclient ?

For now, I am catching exceptions and retrying maintaining a counter variable.


Source: (StackOverflow)

Tracking progress of multipart file upload using OKHTTP

I am trying to implement a a progress bar to indicate the progress of a multipart file upload.

I have read from a comment on this answer - http://stackoverflow.com/a/24285633/1022454 that I have to wrap the sink passed to the RequestBody and provide a callback that tracks the bytes moved.

I have created a custom RequestBody and wrapped the sink with a CustomSink class, however through debugging I can see that the bytes are being written by RealBufferedSink ln 44 and the custom sink write method is only run once, not allowing me to track the bytes moved.

    private class CustomRequestBody extends RequestBody {

    MediaType contentType;
    byte[] content;

    private CustomRequestBody(final MediaType contentType, final byte[] content) {
        this.contentType = contentType;
        this.content = content;
    }

    @Override
    public MediaType contentType() {
        return contentType;
    }

    @Override
    public long contentLength() {
        return content.length;
    }

    @Override
    public void writeTo(BufferedSink sink) throws IOException {
        CustomSink customSink = new CustomSink(sink);
        customSink.write(content);

    }
}


private class CustomSink implements BufferedSink {

    private static final String TAG = "CUSTOM_SINK";

    BufferedSink bufferedSink;

    private CustomSink(BufferedSink bufferedSink) {
        this.bufferedSink = bufferedSink;
    }

    @Override
    public void write(Buffer source, long byteCount) throws IOException {
        Log.d(TAG, "source size: " + source.size() + " bytecount" + byteCount);
        bufferedSink.write(source, byteCount);
    }

    @Override
    public void flush() throws IOException {
        bufferedSink.flush();
    }

    @Override
    public Timeout timeout() {
        return bufferedSink.timeout();
    }

    @Override
    public void close() throws IOException {
        bufferedSink.close();
    }

    @Override
    public Buffer buffer() {
        return bufferedSink.buffer();
    }

    @Override
    public BufferedSink write(ByteString byteString) throws IOException {
        return bufferedSink.write(byteString);
    }

    @Override
    public BufferedSink write(byte[] source) throws IOException {
        return bufferedSink.write(source);
    }

    @Override
    public BufferedSink write(byte[] source, int offset, int byteCount) throws IOException {
        return bufferedSink.write(source, offset, byteCount);
    }

    @Override
    public long writeAll(Source source) throws IOException {
        return bufferedSink.writeAll(source);
    }

    @Override
    public BufferedSink writeUtf8(String string) throws IOException {
        return bufferedSink.writeUtf8(string);
    }

    @Override
    public BufferedSink writeString(String string, Charset charset) throws IOException {
        return bufferedSink.writeString(string, charset);
    }

    @Override
    public BufferedSink writeByte(int b) throws IOException {
        return bufferedSink.writeByte(b);
    }

    @Override
    public BufferedSink writeShort(int s) throws IOException {
        return bufferedSink.writeShort(s);
    }

    @Override
    public BufferedSink writeShortLe(int s) throws IOException {
        return bufferedSink.writeShortLe(s);
    }

    @Override
    public BufferedSink writeInt(int i) throws IOException {
        return bufferedSink.writeInt(i);
    }

    @Override
    public BufferedSink writeIntLe(int i) throws IOException {
        return bufferedSink.writeIntLe(i);
    }

    @Override
    public BufferedSink writeLong(long v) throws IOException {
        return bufferedSink.writeLong(v);
    }

    @Override
    public BufferedSink writeLongLe(long v) throws IOException {
        return bufferedSink.writeLongLe(v);
    }

    @Override
    public BufferedSink emitCompleteSegments() throws IOException {
        return bufferedSink.emitCompleteSegments();
    }

    @Override
    public OutputStream outputStream() {
        return bufferedSink.outputStream();
    }
}

Does anybody have an example of how I would go about doing this?


Source: (StackOverflow)

How can I pin a certificate with Square OKHTTP?

I think I need to create a new SSL Socket Factory? Also, I don't want to use the global SSL Context (https://github.com/square/okhttp/issues/184) for obvious reasons.

thanks!

EDIT:

As of okhttp 2.1.0 you can pin certificates very easily.

See the source code here to get started


Source: (StackOverflow)

How to implement Android Volley with OkHttp 2.0?

This OkHttpStack is no longer supported in OkHttp2.0: https://gist.github.com/JakeWharton/5616899

What is the current pattern to integrate OkHttp 2.0.0 with Volley?


Source: (StackOverflow)

Android Volley MalformedURLException Bad URL

After making a second network request using Volley, I always get this error. It doesn't seem to matter what the url I put in is. Volley always claims it is malformed.

08-04 20:16:26.885  14453-14470/com.thredup.android E/Volley﹕ [994] NetworkDispatcher.run: Unhandled exception java.lang.RuntimeException: Bad URL
java.lang.RuntimeException: Bad URL
        at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:127)
        at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:110)
 Caused by: java.net.MalformedURLException: Protocol not found:
        at java.net.URL.<init>(URL.java:176)
        at java.net.URL.<init>(URL.java:125)
        at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:101)
        at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:93)

Investigating further, I put a couple logs in HurlStack. In

public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders),

the request that fails is REQUEST [ ] 0x0 LOW 26."

Thus, line 101 of HurlStack : URL parsedUrl = new URL(url);

fails with an empty url (request.getUrl() is empty).

I am using OkHttpStack (extending HurlStack). Any ideas on what could be causing this?


Source: (StackOverflow)

OkHTTP and Picasso don't run together

I use Picasso library in my project to load images ande cache them. It works good without any problem. However, when I try to use OkHttp library to perform data communication with my server (JSON communication), Picasso throws exceptions.

I use the following jars : okhttp-2.0.0-RC2, okio-1.0.0, picasso-2.2.0. When I run my project after I add these jars, It crashes with the following :

06-12 11:13:15.824: E/dalvikvm(12105): Could not find class 'com.squareup.okhttp.HttpResponseCache', referenced from method com.squareup.picasso.OkHttpDownloader.<init>

I added okhttp just to use the following method :

public static String executeHttpGet(String urlStr) {
    Response response = null;
    String result = "";
    OkHttpClient client = new OkHttpClient();

    try {
        Request request = new Request.Builder().url(urlStr).build();

        response = client.newCall(request).execute();
        result = response.body().string();
    } catch (Exception ex) {

    }
    return result;
}

The above code works without any problem. However the codes which use Picasso library and used to work perfectly, start to throw the following excecption :

06-12 11:19:49.307: E/AndroidRuntime(13036): FATAL EXCEPTION: main
06-12 11:19:49.307: E/AndroidRuntime(13036): java.lang.NoClassDefFoundError: com.squareup.okhttp.HttpResponseCache
06-12 11:19:49.307: E/AndroidRuntime(13036):    at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:74)
06-12 11:19:49.307: E/AndroidRuntime(13036):    at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:51)
06-12 11:19:49.307: E/AndroidRuntime(13036):    at com.squareup.picasso.OkHttpDownloader.<init>(OkHttpDownloader.java:41)
06-12 11:19:49.307: E/AndroidRuntime(13036):    at com.squareup.picasso.Utils$OkHttpLoaderCreator.create(Utils.java:319)
06-12 11:19:49.307: E/AndroidRuntime(13036):    at com.squareup.picasso.Utils.createDefaultDownloader(Utils.java:171)
06-12 11:19:49.307: E/AndroidRuntime(13036):    at com.squareup.picasso.Picasso$Builder.build(Picasso.java:490)
06-12 11:19:49.307: E/AndroidRuntime(13036):    at com.squareup.picasso.Picasso.with(Picasso.java:390)

My Class Path :

enter image description here

If I remove okhttp-2.0.0-RC2, okio-1.0.0, Picasso lines work.

Why is that happening ? How can I use two libraries together ?


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)