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

Is there any way to pass a HttpClient instance? #649

Open
rocboronat opened this issue Sep 6, 2021 · 24 comments
Open

Is there any way to pass a HttpClient instance? #649

rocboronat opened this issue Sep 6, 2021 · 24 comments

Comments

@rocboronat
Copy link

Hello! πŸ‘‹

As we try to use the same HttpClient to keep keepalive connections, is there any way to pass the CachedNetworkImageProvider a HttpClient to use?

Thanks πŸ™‡β€β™‚οΈ

@PascalOtto
Copy link

PascalOtto commented Sep 24, 2021

I really would like to know this, too. I think it is kind of an essential feature.

But it looks like a http-session is created for every single image (#555). That would be absolutely horrible πŸ˜‘

@renefloor
Copy link
Collaborator

I'll take you around the CacheManager files.

When creating the CacheManager you supply a config file in the constructor. The default IO config file uses a standard HttpFileService if nothing else is provided. That http fileservice only creates 1 http client if no other client is provided.

So what you can do is create a different CacheManager object that you supply a config with an HttpFileService that has your httpclient. At the moment you cannot configure this per request.

So like this:

import 'package:http/http.dart' as http;
final cacheManager = CacheManager(
  Config(
    'testCache',
    fileService: HttpFileService(
      httpClient: http.Client(),
    ),
  ),
);

@Jefry-nolastname
Copy link

Jefry-nolastname commented Oct 7, 2021

I'll take you around the CacheManager files.

When creating the CacheManager you supply a config file in the constructor. The default IO config file uses a standard HttpFileService if nothing else is provided. That http fileservice only creates 1 http client if no other client is provided.

So what you can do is create a different CacheManager object that you supply a config with an HttpFileService that has your httpclient. At the moment you cannot configure this per request.

So like this:

import 'package:http/http.dart' as http;
final cacheManager = CacheManager(
  Config(
    'testCache',
    fileService: HttpFileService(
      httpClient: http.Client(),
    ),
  ),
);

i'm sorry, i'm still not quite sure what you meant and where to apply said code. is it in main.dart? or do i have to manually fork the plugin? i'm using self signed certificate on my client so i need to pass the httpClient to the plugin so it can retrieve it successfully, instead of handshake certificate expired.

``the code
ByteData bytes = await rootBundle.load('cert/....pem');
print("bytes ${bytes.lengthInBytes}");
SecurityContext clientContext = new SecurityContext()
..setTrustedCertificatesBytes(bytes.buffer.asUint8List());

httpClient = IOClient(HttpClient(context: clientContext));
response = await httpClient.post(uri,header,.......)..
``

@Jefry-nolastname
Copy link

Jefry-nolastname commented Oct 7, 2021

and i'm stoopid bakka......

import 'package:flutter_cache_manager/flutter_cache_manager.dart'; CachedNetworkImage( cacheManager: CacheManager( Config( 'testCache', fileService: HttpFileService( httpClient: http, ), ), ), httpHeaders: { "Authorization":"bearer ${globVar.tokenRest.token}" }, )

@rocboronat
Copy link
Author

Just a piece of copypasteable code:

import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:http/http.dart' as http;

final cacheManager = CacheManager(
  Config(
    'cacheKey',
    fileService: HttpFileService(
      httpClient: http.Client(),
    ),
  ),
);

If using it as cacheManager makes CachedNetworkImage and CachedNetworkImageProvider always use the same http client, that's it πŸ˜„

If you think it's a good way to deal with it, thanks a lot and feel free to close the issue πŸ™‡

@escamoteur
Copy link

how does cached_network_image know which CacheManager it should use?

@escamoteur
Copy link

OK, seems like you have to pass the CacheManager to every CachedNetworkImage as paramter

@lukehutch
Copy link

If you want to use the cronet or cupertino clients, they cannot be used with runWithClient, and to use the suggested solution of using Provider<Client>, you would have to pass in a new CacheManager instance every time you use CacheWithNetworkImage (because you have to get the Client implementation from the BuildContext, using context.read<Client>).

My question is: is it inefficient to reinstantiate a new CacheManager and a new HttpFileService for every new CachedNetworkImage request? Or as long as the 'cacheKey' matches every time, is the cache going to be reused between requests?

@lukehutch
Copy link

@renefloor said:

So what you can do is create a different CacheManager object that you supply a config with an HttpFileService that has your httpclient. At the moment you cannot configure this per request.

but CachedNetworkImage does take a cacheManager parameter, so why can this not be configured per request?

@escamoteur
Copy link

escamoteur commented Jun 27, 2024 via email

@escamoteur
Copy link

escamoteur commented Jun 27, 2024 via email

@lukehutch
Copy link

Why would you want to do this on every request?

Because see these comments re context: dart-lang/http#1241 (comment)

I don't think you can just rely on getting the Client instance once, and then pre-creating a single instance of cacheManager. But I don't fully understand the context issue.

@lukehutch
Copy link

lukehutch commented Jun 27, 2024

@escamoteur can you please provide full example code of what you are doing?

Why do you need to use get_it at all, if you are just creating a global variable, cacheManager? This will be lazily initialized the first time it is referenced.

@escamoteur
Copy link

escamoteur commented Jun 27, 2024 via email

@HosseinYousefi
Copy link

We only saw that JNI exception once so far.

Can I see how you're setting up the runWithClient?

@escamoteur
Copy link

escamoteur commented Jun 27, 2024 via email

@HosseinYousefi
Copy link

I don't think we should be getting the exception to begin with! I'm maintaining package:jni which is a dependency of package:cronet_http and I want to know why this happens.

@escamoteur
Copy link

escamoteur commented Jun 27, 2024 via email

@HosseinYousefi
Copy link

@escamoteur No worries. Btw are you coming tomorrow to the GDE conf in Berlin? I have a talk there, we can meet and talk about it there!

@escamoteur
Copy link

escamoteur commented Jun 27, 2024 via email

@lukehutch
Copy link

I just read a comment of one of our users who said since we added cronnet the app doesn't start anymore.

@escamoteur was that when you were using runWithClient, or did you get the report after you switched to using get_it?

@escamoteur
Copy link

ok, I could just reproduce this, it has nothing to do with runWithClient if you use an Android without play services cronnet seems not be available

@lukehutch
Copy link

ok, I could just reproduce this, it has nothing to do with runWithClient if you use an Android without play services cronnet seems not be available

What is the exact failure, and is there a way to detect that this is going to fail? I want to make my app robust to this situation...

Also, why on earth would cronet require Google Play Services? It is just the Chromium HTTP client library... @HosseinYousefi

@escamoteur
Copy link

check dart-lang/http#1241 (comment)

I agreee, I too I'm surprised that it seems that cronnet is part of the Google play service part of Android

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

No branches or pull requests

7 participants