37

Is there a method to add a custom header to request when an image is downloaded? I can use volley or okhttp in Glide.

I tried adding a cookie to the cookiemanager in okhttpclient, but it didn't help.

Is there a method to debug request response in Glide?

Anton Menshov
  • 2,266
  • 14
  • 34
  • 55
tomi
  • 381
  • 1
  • 3
  • 3

8 Answers8

92

Since 3.6.0 it's possible to set custom headers for each request:

GlideUrl glideUrl = new GlideUrl("url", new LazyHeaders.Builder()
    .addHeader("key1", "value")
    .addHeader("key2", new LazyHeaderFactory() {
        @Override
        public String buildHeader() {
            String expensiveAuthHeader = computeExpensiveAuthHeader();
            return expensiveAuthHeader;
        }
    })
    .build());

Glide....load(glideUrl)....;
TWiStErRob
  • 44,762
  • 26
  • 170
  • 254
  • I am still getting this issue - com.bumptech.glide.load.HttpException: Unauthorized – Shoeb Siddique Aug 29 '17 at 07:07
  • my app is getting crashed.. java.lang.IllegalArgumentException: Must not be null or empty pointing out to he line .build()) ... – Android Geek Jan 22 '20 at 11:19
  • what is the "computeExpensiveAuthHeader()" method do in this script? – Arash Afsharpour Apr 01 '21 at 14:24
  • 1
    @ArashAfsharpour that's code you define. That `LazyHeaders` example demonstrates how to calculate an expensive header on a background thread, since Glide loads are usually started on the main thread and accessing disk/network would block UI. If you have all the info you need in fast accessible memory, you don't need `LazyHeaderFactory`s. – TWiStErRob Apr 01 '21 at 17:12
  • It works. If you don't see your headers in your logs, make sure they don't replace anywhere after that. – antaki93 Jul 21 '22 at 15:07
  • @antaki93 just to double-check the validity of the answer: same code works on Glide 4.x in 2022? – TWiStErRob Jul 21 '22 at 15:25
  • @TWiStErRob yes, Glide 4.13.2. But I didn't use the `LazyHeaderFactory` and `buildHeader()` – antaki93 Jul 21 '22 at 15:35
16

Try this:

ImageView imgThumb = itemView.findViewById(R.id.image_thumb);

GlideUrl url = new GlideUrl("https://your-url.com", new LazyHeaders.Builder()
                .addHeader("User-Agent", "your-user-agent")
                .build());

RequestOptions options = new RequestOptions()
    .diskCacheStrategy(DiskCacheStrategy.NONE);

Glide.with(mContext).load(glideUrl)
                    .transition(withCrossFade())
                    .thumbnail(0.5f)
                    .apply(options)
                    .into(imgThumb);

The Glide reference is:

implementation 'com.github.bumptech.glide:glide:4.6.1'
educoutinho
  • 869
  • 9
  • 16
  • my app is getting crashed.. java.lang.IllegalArgumentException: Must not be null or empty pointing out to he line .build()) ... – Android Geek Jan 22 '20 at 11:19
16

Kotlin + Glide 4.10.0

val token = "..."
val url = https://url.to.your.image
val glideUrl = GlideUrl(url) { mapOf(Pair("Authorization", "Bearer $token")) }

Glide.with(context)
     .load(glideUrl)
     .into(imageView)
ArcDexx
  • 453
  • 5
  • 15
4

If you can't get Glide to do it, you can use OkHttp Interceptors.

Jesse Wilson
  • 39,078
  • 8
  • 121
  • 128
3

This is late, I think but I put it here for notes for anyone else facing the issue. Here are my code samples (this is for Glide v4):

BaseGlideUrlLoader module:

private static class HeaderedLoader extends BaseGlideUrlLoader<String> {

    public static final Headers HEADERS = new LazyHeaders.Builder()
            .addHeader("Referer", UserSingleton.getInstance().getBaseUrl())
            .build();

    public HeaderedLoader(ModelLoader<GlideUrl, InputStream> concreteLoader) {
        super(concreteLoader);
    }

    @Override public boolean handles(@NonNull String model) {
        return true;
    }

    @Override protected String getUrl(String model, int width, int height, Options options) {
        return model;
    }

    @Override protected Headers getHeaders(String model, int width, int height, Options options) {
        return HEADERS;
    }

    public static class Factory implements ModelLoaderFactory<String, InputStream> {

        @Override public @NonNull ModelLoader<String, InputStream> build(
                @NonNull MultiModelLoaderFactory multiFactory) {
            return new HeaderedLoader(multiFactory.build(GlideUrl.class, InputStream.class));
        }

        @Override public void teardown() { /* nothing to free */ }
    }
}

Add the HeaderLoader class in the AppGlideModule.

@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
    super.registerComponents(context, glide, registry);

    registry.replace(GlideUrl.class, InputStream.class,
            new OkHttpUrlLoader.Factory(CustomOkHttpsClient.getTrustedOkHttpClient()
            ));

    // override default loader with one that attaches headers
    registry.replace(String.class, InputStream.class, new HeaderedLoader.Factory());
}

My solution is based on link provided here https://github.com/TWiStErRob/glide-support/commit/b357427363c28a82495097ec862b82acdf3b4357

The original issue is discussed here https://github.com/bumptech/glide/issues/471

Thanks to @TWiStErRob

Yazid
  • 409
  • 7
  • 8
1

Interceptors sound like a great choice. You can pass in your own instance of an OkHttp client to an OkHttpUrlLoader.Factory and register the Factory with Glide.

If you want more control, you can also simply fork the OkHttp ModelLoader and DataFetcher, register your forked ModelLoader, and get direct access to the OkHttp client for every request.

Sam Judd
  • 7,317
  • 1
  • 38
  • 38
1
// make sure it's registered in AndroidManifest.xml as described at https://github.com/bumptech/glide/wiki/Configuration#including-a-glidemodule
public class GlideSetup implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) { /* no costumization */ }
@Override public void registerComponents(Context context, Glide glide) {
    glide.register(String.class, InputStream.class, new HeaderedLoader.Factory());
}

private static class HeaderedLoader extends BaseGlideUrlLoader<String> {
    public static final Headers HEADERS = new LazyHeaders.Builder()
            .addHeader("User-Agent", USER_AGENT)
            .addHeader("App-Agent", APP_AGENT)
            .build();

    public HeaderedLoader(Context context) {
        super(context);
    }

    @Override protected String getUrl(String model, int width, int height) {
        return model;
    }

    @Override protected Headers getHeaders(String model, int width, int height) {
        return HEADERS;
    }

    public static class Factory implements ModelLoaderFactory<String, InputStream> {
        @Override public StreamModelLoader<String> build(Context context, GenericLoaderFactory factories) {
            return new HeaderedLoader(context);
        }
        @Override public void teardown() { /* nothing to free */ }
    }
}

}

and then

....load("http://....")....;
Morteza Rastgoo
  • 6,772
  • 7
  • 40
  • 61
  • 1
    Take a look at the comments in the issue this was pulled from before using it: https://github.com/bumptech/glide/issues/471. In particular, replacing the String -> InputStream loader will remove default handling of uri and file path strings. Consider instead a custom model type (other than String). – Sam Judd May 27 '15 at 16:14
0

Please read this thread: https://github.com/bumptech/glide/issues/198

It appears as if it will be implemented in the coming release (4.0).

Naphtali Gilead
  • 222
  • 4
  • 18