square / picasso

A powerful image downloading and caching library for Android
https://square.github.io/picasso/
Apache License 2.0
18.7k stars 3.97k forks source link

Error 504 when get image #1896

Open sultonov opened 6 years ago

sultonov commented 6 years ago

Couldn't get picture from pixabay.com.

Picasso.get().load("https://cdn.pixabay.com/photo/2018/05/03/00/54/blue-butterfly-flower-3370200_150.jpg").into(view);

This code returned error HTTP 504.

wlxyhy commented 6 years ago

The same issue when loading https, sometimes it can work properly, and sometimes only half of the image was shown, and sometimes it shows exception below:

System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 504 at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51) at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219) at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457) 08-03 11:21:51.283 5252-5252/com.easilydo.mail W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:354)

However, the image can be shown correctly in browser

Picasso.get().load("https://restxmpp.stag.easilydo.cc/public/getavatar?email=wlxyhy@126.com") .memoryPolicy(MemoryPolicy.NO_CACHE).placeholder(initialDrawable).transform(new CropCircleTransformation()).into(this, callback);

RomanTcv commented 6 years ago

I have the same problem, but only on old device - Lg LS620 (android 4.4.2). Picasso version 'com.squareup.picasso:picasso:2.71828'.

W/System.err: com.squareup.picasso.NetworkRequestHandler$ResponseException: HTTP 504
        at com.squareup.picasso.NetworkRequestHandler.load(NetworkRequestHandler.java:51)
        at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:219)
        at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:175)
        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)

Tested urls: https://vignette.wikia.nocookie.net/jamesbond/images/d/dc/JamesBond%28PierceBrosnan%29-_Profile.jpg/revision/latest?cb=20130506224906 https://ksassets.timeincuk.net/wp/uploads/sites/55/2017/08/GettyImages-496903944-920x584.jpg

P.S. Small images load perfect.

jgodinez commented 6 years ago

I'm finding de same problem @R12rus with old devices Samsung 4.4.2 and the same version 2.71828 with "https"

I tried with this code but not works, maybe I'm wrong on something

OkHttpClient.Builder builderPicasso = new OkHttpClient.Builder()
                .protocols(Collections.singletonList(Protocol.HTTP_1_1));

final Picasso picasso = new Picasso.Builder(getContext())
        .downloader(new com.squareup.picasso.OkHttp3Downloader(builderPicasso.build()))
        .listener(new Picasso.Listener() {
            @Override
            public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
                Log.e("Picasso", exception.getMessage());
            }
        })
        .build();

picasso.setLoggingEnabled(true);
picasso.load(item.getThumbnail()).into(imageView);

Any ideas, How can We fix this? @JakeWharton // Sorry to mention you

Thanks so much!

Felipe00 commented 5 years ago

Guys, I tried urls from: ramdomuser and get HTTP 504 message too. Anyone solved this?

Marcelo-Petrucelli commented 5 years ago

Same problem here.

Has anyone find any possible solution for this?

----------------- EDITED -----------------

This solved my problem: https://github.com/square/picasso/issues/2022#issuecomment-435659477

smithaaron commented 5 years ago

@Marcelo-Petrucelli How does allowing cleartext work when both of those URLs are https?

nehagup commented 5 years ago

I'm finding the same problem. Anyone found the solution?

EduardoDornel commented 5 years ago

same problem here!

Marcelo-Petrucelli commented 5 years ago

@smithaaron I really don't know. Most devices were accepting and working perfectly. Specifically at a Xiomi device it simply wasn't working. It worked after the change commented in that link.

bitvale commented 5 years ago

For me it's working in this way (before this not working on API 19):

 OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
 OkHttpClient client = enableTls12OnPreLollipop(httpClient).build();
 mPicasso = new Picasso.Builder(context)
                .downloader(new OkHttp3Downloader(client))
                .listener((picasso, uri, exception) -> Timber.w(exception, "Unable to load image %s", uri.toString()))
                .indicatorsEnabled(false)
                .build();

private OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
        if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 22) {
            try {
                SSLContext sc = SSLContext.getInstance("TLSv1.2");
                sc.init(null, null, null);
                client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));

                ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                        .tlsVersions(TlsVersion.TLS_1_2)
                        .build();

                List<ConnectionSpec> specs = new ArrayList<>();
                specs.add(cs);
                specs.add(ConnectionSpec.COMPATIBLE_TLS);
                specs.add(ConnectionSpec.CLEARTEXT);

                client.connectionSpecs(specs);
            } catch (Exception exc) {
                Timber.e(exc);
            }
        }
   return client;
}

Solution found somewhere on stackoverflow

igaryhe commented 5 years ago

This is due to some network security mechanism in Android Pie. Found a solution here: https://stackoverflow.com/questions/51902629/how-to-allow-all-network-connection-types-http-and-https-in-android-9-pie

dehghanimehrdad commented 5 years ago

I solved it like this:

final SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient client = new OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory).addInterceptor(new Interceptor() { @Override public okhttp3.Response intercept(Chain chain) throws IOException { final Request original = chain.request(); final Request authorized = original.newBuilder().build(); return chain.proceed(authorized); } }).build(); return new Picasso.Builder(context) .downloader(new OkHttp3Downloader(client)) .build();

vishvendu commented 4 years ago

android:usesCleartextTraffic="true" try to add this in your manifest file if you are running in Android 9 or above. Default value in Android P is “false”setting this to true indicates that the app intends to use clear network traffic.

ultra-taco commented 4 years ago

android:usesCleartextTraffic="true"

Thanks vishvendu, this is what it was for me. My images were http://... so I was getting that 504 error.

drusak commented 4 years ago

Still have HTTP 504 error when getting images (via https!) on Android OS 4, 5, 7, 8, 9. Seems the number of fails increased after migrating from 2.5.2 to 2.71828

Also it happens when manually set date/time in future (e.g. 10 days in future). Not sure if it is the same with original question, but one of steps to reproduce. It can be reproduced with 2.5.2, 2.71828 Picasso versions

andreycattalin commented 4 years ago

Uninstalling the app and installing it again, is crazy but works!

icatalin201 commented 4 years ago

I had the same error and i found out that there was a problem with the self-signed certificate from the server.

So my solution was to add a custom SSLSocketFactory to allow all certificates.

public static OkHttpClient.Builder createBuilderWithTrustManager() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        try {
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[]{};
                        }
                    }
            };
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier((hostname, session) -> true);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return builder;
    }
dzhtv commented 3 years ago

1) First, create trust OkHttp client

fun getUnsafeOkHttpClient(): OkHttpClient {
            // Create a trust manager that does not validate certificate chains
            val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
                override fun checkClientTrusted(
                    chain: Array<out X509Certificate>?,
                    authType: String?
                ) {
                }

                override fun checkServerTrusted(
                    chain: Array<out X509Certificate>?,
                    authType: String?
                ) {
                }

                override fun getAcceptedIssuers() = arrayOf<X509Certificate>()
            })

            // Install the all-trusting trust manager
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, trustAllCerts, java.security.SecureRandom())
            // Create an ssl socket factory with our all-trusting manager
            val sslSocketFactory = sslContext.socketFactory

            return OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
                .hostnameVerifier(HostnameVerifier { _, _ -> true })
                .addInterceptor(HttpLoggingInterceptor().apply {
                    level = HttpLoggingInterceptor.Level.BODY
                })
                .build()
        }

2) Add client to Picasso

fun getPicassoUnsafeCertificate(context: Context): Picasso {
    val client = getUnsafeOkHttpClient()
    val picasso = Picasso.Builder(context).downloader(OkHttp3Downloader(client)).build()
    picasso.isLoggingEnabled = true
    return picasso
}

3) Use

getPicassoUnsafeCertificate(context).load(link).into(imageView)
lyawile commented 3 years ago

Helped a lot. Thanks.

abdullahalamodi commented 3 years ago

My problem was wrong in image URL when I used localhost and run on emulator I should replace localhost word with device ip that is 10.0.2.2:80 the url should be something like http//10.0.2.2:80/... And it's work successfully ☺️

akhilesh1102 commented 3 years ago

Couldn't get picture from pixabay.com.

Picasso.get().load("https://cdn.pixabay.com/photo/2018/05/03/00/54/blue-butterfly-flower-3370200_150.jpg").into(view);

This code returned error HTTP 504.

<application ... android:usesCleartextTraffic="true"> worked for me

carlosmeds commented 3 years ago

Hi there, everyone!

<application ... android:usesCleartextTraffic="true"> worked for me too!

saioufe commented 2 years ago

Uninstalling the app and installing it again, is crazy but works!

Thanks man i've been trying to solve it for 5 hours LOL