Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.8.0] memoryCacheExtraOptions affixes the values to the Uri (https) #188

Closed
chrisjenx opened this issue Mar 1, 2013 · 25 comments
Closed
Labels

Comments

@chrisjenx
Copy link
Contributor

I'm using .memoryCacheExtraOptions(512, 512)
I'm not sure if this is the desired effect but by doing this when performing webrequests it now affixes the size to the end of the image.

https://d3jpl91pxevbkh.cloudfront.net/notha/image/upload/v1360769665/1.png
becomes
https://d3jpl91pxevbkh.cloudfront.net/notha/image/upload/v1360769665/1.png_512x512
Which of course fails loading.

Cheers,
Chris

@nostra13
Copy link
Owner

nostra13 commented Mar 1, 2013

http://stackoverflow.com/questions/14789716/android-universal-image-loader-change-hxw-url-parameters

Maybe you have the problem with https, try this class:

public class AuthImageDownloader extends BaseImageDownloader {
    public static final String TAG = AuthImageDownloader.class.getName();


    public AuthImageDownloader(Context context, int connectTimeout, int readTimeout) {
        super(context, connectTimeout, readTimeout);
    }

    @Override
    protected InputStream getStreamFromNetwork(String imageUri, Object extra) throws IOException {

        URL url = null;
        try {
            url = new URL(imageUri);
        } catch (MalformedURLException e) {
            Log.e(TAG, e.getMessage(), e);
        }
        HttpURLConnection http = null;

        if (Scheme.ofUri(imageUri) == Scheme.HTTPS) {
            trustAllHosts();
            HttpsURLConnection https = (HttpsURLConnection) url
                    .openConnection();
            https.setHostnameVerifier(DO_NOT_VERIFY);
            http = https;
            http.connect();
        } else {
            http = (HttpURLConnection) url.openConnection();
        }

        http.setConnectTimeout(connectTimeout);
        http.setReadTimeout(readTimeout);
        return new FlushedInputStream(new BufferedInputStream(
                http.getInputStream()));
    }

    // always verify the host - dont check for certificate
    final static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    /**
     * Trust every server - dont check for any certificate
     */
    private static void trustAllHosts() {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            @Override
            public void checkClientTrusted(
                    java.security.cert.X509Certificate[] x509Certificates,
                    String s) throws java.security.cert.CertificateException {
            }

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

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

        // Install the all-trusting trust manager
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection
                    .setDefaultSSLSocketFactory(sc.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

@chrisjenx
Copy link
Contributor Author

Nothing to do with SSL, this line actually returns an affixed Url which is why the image loader fails.
(https://d3jpl91pxevbkh.cloudfront.net/notha/image/upload/v1360769665/1.png_512x512 which of course is bad) .

    @Override
    protected InputStream getStreamFromNetwork(URI imageUri, Object extra) throws IOException {
      Log.d(TAG, "URL="+imageUri.toString());
      //...
    }

I will look at fixing it in my fork. Seems that a certain flow makes it prefix to the wrong parts of the request.

@nostra13
Copy link
Owner

nostra13 commented Mar 8, 2013

Did you found the reason?

@chrisjenx
Copy link
Contributor Author

I haven't had chance going to investigate this weekend
On 8 Mar 2013 09:35, "Sergey Tarasevich" notifications@github.com wrote:

Did you found the reason?


Reply to this email directly or view it on GitHubhttps://github.com//issues/188#issuecomment-14611118
.

@Narfss
Copy link

Narfss commented Mar 13, 2013

Hello @nostra13 and @chrisjenx, I have a similar problem, Universal Image Downloader and SSL.

I want use the class you post before, but in the point to override getStreamFromNetwork:

public class AuthImageDownloader extends BaseImageDownloader {
...
@OverRide
protected InputStream getStreamFromNetwork(URI imageUri, Object extra) throws IOException {
...
}

Happens this error, and i'm not sure how to fix:

The method getStreamFromNetwork(URI, Object) of type AuthImageDownloader must override or implement a supertype method

The quick fix is remove "@OverRide" annotation. But of course don't works.

Thanks.

@chrisjenx
Copy link
Contributor Author

Just check that the correct method being overridden.

If eclipse is throwing an error on the override annotation it means that you are not overriding/extending the correct class thus the error.

@nostra13
Copy link
Owner

ImageDownloader changed its API, it uses String instead of URI. Updated my comment.

@Narfss
Copy link

Narfss commented Mar 13, 2013

Great, now works perfect.

Thanks, Is incredible how both answer so fast. ^^

@chrisjenx
Copy link
Contributor Author

This is my work around to the above bug:

package com.bizzby.http.requests;

import android.content.Context;
import android.text.TextUtils;
import com.bizzby.utils.QLog;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.http.*;
import com.nostra13.universalimageloader.core.assist.FlushedInputStream;
import com.nostra13.universalimageloader.core.download.BaseImageDownloader;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created with Intellij with Android, BIZZBY product.
 * See licencing for usage of this code.
 * <p/>
 * User: chris
 * Date: 01/03/2013
 * Time: 15:45
 */
public class GoogleImageDownloader extends BaseImageDownloader
{

    protected static final Pattern SIZE_PATTERN = Pattern.compile("(_[0-9]+(_|x)[0-9]+)$", Pattern.CASE_INSENSITIVE);
    public static HttpTransport sHttpTransport;
    public static HttpRequestFactory sHttpRequestFactory;

    public static HttpRequest getHttpRequest(final String uri) throws IOException
    {
        if (sHttpTransport == null) sHttpTransport = AndroidHttp.newCompatibleTransport();
        if (sHttpRequestFactory == null) sHttpRequestFactory = sHttpTransport.createRequestFactory();
        return sHttpRequestFactory.buildGetRequest(new GenericUrl(uri));
    }

    private static String replaceLast(final String string, final String from, final String to)
    {
        int lastIndex = string.lastIndexOf(from);
        if (lastIndex < 0) return string;
        final String tail = string.substring(lastIndex).replaceFirst(from, to);
        return string.substring(0, lastIndex) + tail;
    }

    static String stripSizeOffUrl(final String string)
    {
        if (TextUtils.isEmpty(string)) return string;
        final Matcher matcher = SIZE_PATTERN.matcher(string);
        String group = "";
        while (matcher.find())
        {
            group = matcher.group(1);
        }
        return replaceLast(string, group, "");

    }

    public GoogleImageDownloader(final Context context)
    {
        super(context);
    }

    public GoogleImageDownloader(final Context context, final int connectTimeout, final int readTimeout)
    {
        super(context, connectTimeout, readTimeout);
    }

    @Override
    protected InputStream getStreamFromContent(URI imageUri, final Object extra) throws FileNotFoundException
    {
        imageUri = URI.create(stripSizeOffUrl(imageUri.toString()));
        return super.getStreamFromContent(imageUri, extra);
    }

    @Override
    protected InputStream getStreamFromNetwork(final URI imageUri, final Object extra) throws IOException
    {
        if (null == imageUri) return null;
        final String url = stripSizeOffUrl(imageUri.toString());
        QLog.i("ImageLoader, Downloading [" + url + "]");
        final HttpRequest request = getHttpRequest(url);
        request.setConnectTimeout(connectTimeout);
        request.setReadTimeout(readTimeout);
        final HttpResponse response = request.execute();
        if (response != null && response.isSuccessStatusCode())
        {
            return new FlushedInputStream(response.getContent(), BUFFER_SIZE);
        }
        return null;
    }
}

The cause of this is still on my list todo.

@doridori
Copy link

Im having this issue too - this is no fun - and why is this thread marked closed?

@chrisjenx
Copy link
Contributor Author

@doridori its not marked closed the other #163 is closed which referenced this.

@doridori
Copy link

oh sorry, my bad

@doridori
Copy link

@chrisjenx bug fix works great for

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                .imageDownloader(new CustomImageDownloader(context)) //bug fix

@nostra13
Copy link
Owner

nostra13 commented Apr 1, 2013

Still can't understand how it could happen.

@Lukafin
Copy link

Lukafin commented Apr 4, 2013

Nostra, i am having problems with https and your solution posted above (using AuthImageDownloader class).
The problem is in method encodeCredentials(), where it says that method for Configuration.getInstance() is undefined.

public static String encodeCredentials() {
       try {
           Configuration configuration = Configuration.getInstance();
           String auth = android.util.Base64.encodeToString((configuration.getHttpAuthLogin()
                + ":" + configuration.getHttpAuthPassword()).getBytes("UTF-8"),
                android.util.Base64.NO_WRAP);
           return auth;
       } catch (Exception ignored) {
           Log.e(TAG, ignored.getMessage(), ignored);
       }
       return "";
   }

I am missing something? What are the needed imports for above code?
If i import android.content.res.Configuration, i get even more errors?

@nostra13
Copy link
Owner

nostra13 commented Apr 4, 2013

You should use this authorization only if you need. I guess you don't. I updated AuthImageDownloader code, check it out.

@Lukafin
Copy link

Lukafin commented Apr 5, 2013

Works! I used code below to make it work:

   ImageLoaderimageLoader = ImageLoader.getInstance();

    DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
            .cacheInMemory()
            .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2).build();

    Builder configBuilder = new ImageLoaderConfiguration.Builder(getActivity());
    configBuilder.imageDownloader(new AuthImageDownloader(getActivity(), 1000, 1000));
    configBuilder.defaultDisplayImageOptions(defaultOptions);
    ImageLoaderConfiguration config=configBuilder.build();

    imageLoader.init(config);

Thank you very much for your quick answer.

@doridori
Copy link

I see this is closed - does it now not append the dimensions to the end of the URL?

@nostra13
Copy link
Owner

It didn't append the dimensions before. I couldn't reproduce the bug and couldn't imagine why it can happen. chrisjenx promised to look into it but he didn't I guess. If you have this bug then you can send me your project with this bug so I'll look into it.

@chrisjenx
Copy link
Contributor Author

This bug is still very active. I'm out of the county so no chance to fix.
Dori can you confirm in 1.8.2 see if still an issue?

Chris.
On 10 Apr 2013 16:24, "Sergey Tarasevich" notifications@github.com wrote:

It didn't append the dimensions before. I couldn't reproduce the bug and
couldn't imagine why it can happen. chrisjenx promised to look into it but
he didn't I guess. If you have this bug then you can send me your project
with this bug so I'll look into it.


Reply to this email directly or view it on GitHubhttps://github.com//issues/188#issuecomment-16199551
.

@PankovSerge
Copy link

Got this issue with 1.9.3 and https in link. Use AuthImageDownloader from your comment.

@HarryMMR
Copy link

HarryMMR commented Sep 8, 2015

As suggested, I tried to use AuthImageDownloader to ignore SSL cert error. But from log cat, it seems that AuthImageDownloader override method is not being called and i still get same ssl error.
I already set ".imageDownloader(new AuthImageDownloader(getApplicationContext(),5000,5000)) " in ImageLoaderConfiguration.
Help please!

@huluwa-dev
Copy link

Got this issue with 1.9.4....How to solve it???

@HarryMMR
Copy link

Have anyone found a fix? I need it ASAP.

@zhdh2008
Copy link

zhdh2008 commented Jul 5, 2016

@nostra13 Your code works well, thanks
ps: The version of UIL I use is 1.9.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants