Not clear how to add custom headers with Glide 4.
Such that they are always appended if I access a remote image (via URL or URI).
Using 4.6.1.
I am getting an error
class com.bumptech.glide.load.engine.GlideException: Failed to load resource There were 2 causes: com.bumptech.glide.load.HttpException(Not Acceptable) com.bumptech.glide.load.HttpException(Not Acceptable) call GlideException#logRootCauses(String) for more detail Cause (1 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, REMOTE There was 1 cause: com.bumptech.glide.load.HttpException(Not Acceptable) call GlideException#logRootCauses(String) for more detail Cause (1 of 1): class com.bumptech.glide.load.HttpException: Not Acceptable Cause (2 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, REMOTE There was 1 cause: com.bumptech.glide.load.HttpException(Not Acceptable) call GlideException#logRootCauses(String) for more detail Cause (1 of 1): class com.bumptech.glide.load.HttpException: Not Acceptable Cause (3 of 3): class com.bumptech.glide.load.engine.GlideException: Failed LoadPath{StringUri->Object->Drawable}, LOCAL Cause (1 of 2): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{StringUri->Drawable->Drawable} Cause (2 of 2): class com.bumptech.glide.load.engine.GlideException: Failed DecodePath{StringUri->Bitmap->Drawable}
My inference, from reading OkHTTP docs, is that server responding with 'image/jpeg'
But my Glide's request does not have anything indicating that it can support image/jpeg.
And indeed, the header coming from Glide, does not have Accept: image/jpeg (or anything at all related for images).
My server code is looking for 'image' string in accept key of the the header.
Therefore the error.
I would think Glide's fetcher would set the header like this itself, but it is not the case, apparently
So I am set on the quest to add an explicit header to all of my Glide URL requests
by
headersBuilder.addHeader("Accept", "image/jpeg");
That in turn, required quite a bit of overriding/registering machinery.
Which I think I am having trouble with.
Therefore wanted to ask to review the below to see if I am doing this custom header addition correctly.
(as my server is not getting the header keys I am setting, still)
my build.gradle:
implementation "com.github.bumptech.glide:glide:4.6.1"
implementation "com.github.bumptech.glide:okhttp3-integration::4.6.1"
annotationProcessor "com.github.bumptech.glide:compiler::4.6.1"
Image loading:
public class ImageLoader {
private final Context context;
public ImageLoader(Context context) {
this.context = context;
}
public void loadImage(String imageUri, ImageView viewToLoadImageIn) {
Uri uri = Uri.parse(imageUri);
RequestOptions options = new RequestOptions();
options.fitCenter();
/* note that GlideApp is auto generated class
because I used GlideModule annotion in my custom OkhttpGLideModule
*/
GlideApp.with(context)
.load(uri)
.apply(options)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(GlideException e, Object model, Target<Drawable> target,
boolean isFirstResource) {
ImageView view = ((ImageViewTarget<?>) target).getView();
view.setLayerType(ImageView.LAYER_TYPE_NONE, null);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target,
DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(viewToLoadImageIn);
}
public void loadImage(URI imageUri, ImageView viewToLoadImageIn) {
RequestOptions options = new RequestOptions();
options.fitCenter();
Glide.with(context)
.load(imageUri)
.apply(options)
.into(viewToLoadImageIn);
}
}
The custom module where I am trying to add custom headers:
import android.support.annotation.Nullable;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.Headers;
import com.bumptech.glide.load.model.LazyHeaders;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
import com.bumptech.glide.load.model.stream.BaseGlideUrlLoader;
import java.io.InputStream;
public class ContentImageLoader extends BaseGlideUrlLoader<String> {
public static class Factory implements ModelLoaderFactory<String, InputStream> {
@Override
public ModelLoader<String, InputStream> build(MultiModelLoaderFactory multiFactory) {
return new ContentImageLoader(multiFactory.build(GlideUrl.class, InputStream.class));
}
@Override
public void teardown() {
}
}
public ContentImageLoader(ModelLoader<GlideUrl, InputStream> urlLoader) {
super(urlLoader);
}
@Override
public boolean handles(String model) {
return true;
}
@Override
protected String getUrl(String model, int width, int height, Options options) {
return model;
}
@Nullable
@Override
protected Headers getHeaders(String s, int width, int height, Options options) {
LazyHeaders.Builder headersBuilder = new LazyHeaders.Builder();
headersBuilder.addHeader("Accept", "image/jpeg");
return headersBuilder.build();
}
}
this is where I am registering the new module (s ).
@GlideModule
public class OkHttpGlideModule extends AppGlideModule{
@Override
public void registerComponents(Context context, Glide glide, Registry registry) {
//I have my own okHTTPclient already with all the right HTTPS things..
OkHttpClient client =AppU1b.getApplicationComponent().okHttpClient();
registry.replace(GlideUrl.class, InputStream.class,
new OkHttpUrlLoader.Factory(client));
/*registering module that helps me to add URL headers
hope that replacing String.class is the right thing to do...
*/
registry.replace(String.class, InputStream.class,
new ContentImageLoader.Factory());
}
}
If all you need to do is add headers, you don't need to register anything (although you're welcome to do so). Instead you can just use
Headers headers = new LazyHeaders().addHeader(...);
GlideUrl url = new GlideUrl(url, headers);
Glide.with(fragment).load(url).into(imageView);
thank you @sjudd . I have done that and it works.
May I still ask, if you could look at the custom module registration and see if you can spot something I am doing wrong
You're replacing with String type, but your model is a Uri. That's probably why your current implementation isn't being called.
If you want to avoid passing in the headers everywhere, you could prepend (or replace) a ModelLoader
This issue has been automatically marked as stale because it has not had activity in the last seven days. It will be closed if no further activity occurs within the next seven days. Thank you for your contributions.
thank you. Yes this is the problem. It was not clear to me (may this is in the doc, but I missed it, that ModelLoader template parameter needs to be GlideURL
Hello,
this was a while back. I ended up using the Glide URL.
Below is the code piece where the headers are added.
With regards to adding something to the end of URL, may be you can do it in this type of function
as well.
My bigger problem was (and it still unresolved): not being able to manage headers 'dynamically' where I would add/remove Authorization header, based user's login status.
That still does not work, because I could not figure how to override default fetcher behavior.
Sorry could not be of more help.
public void loadImage(String imageUri, ImageView viewToLoadImageIn) {
//Timber.d("Fetching image from uri: %s", imageUri);
//Uri uri = Uri.parse(imageUri);
//TODO this is new for glide 4.x move options to constructor somewhere
RequestOptions options = new RequestOptions();
options.fitCenter();
/* after unsuccessfully trying the custom Glide 4 module to override default
fetcher behavior
*/
GlideUrl glideUrl=new GlideUrl(imageUri,new LazyHeaders.Builder()
.addHeader("Accept","image/jpeg")
.build()
);
/* note that GlideApp is auto generated class
because I used GlideModule annotion in OkhttpGLideModule
reason I have done this, is to configure glide
to *NOT* use its default url loader, and instead
use the one that does not care about signed/unsighed
http certificates
*/
GlideApp.with(context)
//.load(uri)
.load(glideUrl)
.apply(options)
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(GlideException e, Object model, Target<Drawable> target,
boolean isFirstResource) {
ImageView view = ((ImageViewTarget<?>) target).getView();
view.setLayerType(ImageView.LAYER_TYPE_NONE, null);
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target,
DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(viewToLoadImageIn);
}
From: Karla notifications@github.com
Sent: Friday, March 6, 2020 7:26 PM
Subject: Re: [bumptech/glide] adding custom headers with Glide 4 (4.6.1) (#3008)
@vladphttps://github.com/vladp Hello! What did you change in your code for it to work? I think I'm in the similar situation. In your case you were trying to add headers, in my case I wan't to add something at the end of my URL. Can you please point me to the changes you've made for it to work? Thanks!