2
0
mirror of https://github.com/inventree/inventree-app.git synced 2026-07-04 03:40:41 +00:00

Reuse http client and cache the https setting (#845)

This makes the app way faster by not having to redo the TCP and TLS handshake all the time and removing a disk read on each http request.
This commit is contained in:
Jorropo
2026-07-02 13:49:17 +02:00
committed by GitHub
parent 06013b3ac5
commit 4195841827
2 changed files with 64 additions and 40 deletions
+63 -40
View File
@@ -479,10 +479,7 @@ class InvenTreeAPI {
url = url + "/"; url = url + "/";
} }
// Cache the "strictHttps" setting, so we can use it later without async requirement await _refreshHttpsPolicy();
_strictHttps =
await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false)
as bool;
debug("Connecting to ${apiUrl}"); debug("Connecting to ${apiUrl}");
@@ -566,6 +563,8 @@ class InvenTreeAPI {
profile = userProfile; profile = userProfile;
await _refreshHttpsPolicy();
// Form a name to request the token with // Form a name to request the token with
String platform_name = "inventree-mobile-app"; String platform_name = "inventree-mobile-app";
@@ -658,6 +657,8 @@ class InvenTreeAPI {
_connecting = false; _connecting = false;
profile = null; profile = null;
_resetHttpClient();
// Clear received settings // Clear received settings
_globalSettings.clear(); _globalSettings.clear();
_userSettings.clear(); _userSettings.clear();
@@ -930,17 +931,11 @@ class InvenTreeAPI {
HttpClientRequest? _request; HttpClientRequest? _request;
final bool strictHttps =
await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false)
as bool;
var client = createClient(url, strictHttps: strictHttps);
showLoadingOverlay(); showLoadingOverlay();
// Attempt to open a connection to the server // Attempt to open a connection to the server
try { try {
_request = await client _request = await httpClient
.openUrl("GET", _uri) .openUrl("GET", _uri)
.timeout(Duration(seconds: 10)); .timeout(Duration(seconds: 10));
@@ -1013,14 +1008,6 @@ class InvenTreeAPI {
String method = "POST", String method = "POST",
Map<String, dynamic>? fields, Map<String, dynamic>? fields,
}) async { }) async {
bool strictHttps = await InvenTreeSettingsManager().getBool(
INV_STRICT_HTTPS,
false,
);
// Create an IOClient wrapper for sending the MultipartRequest
final ioClient = IOClient(createClient(url, strictHttps: strictHttps));
final uri = Uri.parse(makeApiUrl(url)); final uri = Uri.parse(makeApiUrl(url));
final request = http.MultipartRequest(method, uri); final request = http.MultipartRequest(method, uri);
@@ -1050,9 +1037,9 @@ class InvenTreeAPI {
String jsondata = ""; String jsondata = "";
try { try {
var streamedResponse = await ioClient var streamedResponse = await IOClient(
.send(request) httpClient,
.timeout(Duration(seconds: 120)); ).send(request).timeout(Duration(seconds: 120));
final httpResponse = await http.Response.fromStream(streamedResponse); final httpResponse = await http.Response.fromStream(streamedResponse);
response.statusCode = httpResponse.statusCode; response.statusCode = httpResponse.statusCode;
@@ -1198,14 +1185,14 @@ class InvenTreeAPI {
* Note that for some instances, we may wish to ignore certificate errors (e.g. self-signed certificates) * Note that for some instances, we may wish to ignore certificate errors (e.g. self-signed certificates)
* In this case, we will allow the user to disable "strict HTTPS" mode * In this case, we will allow the user to disable "strict HTTPS" mode
*/ */
HttpClient createClient(String url, {bool strictHttps = true}) { HttpClient _createClient() {
var client = HttpClient(); HttpClient client = HttpClient();
client.badCertificateCallback = client.badCertificateCallback =
(X509Certificate cert, String host, int port) { (X509Certificate cert, String host, int port) {
if (strictHttps) { if (_strictHttps) {
showServerError( showServerError(
url, "${host}:${port}",
L10().serverCertificateError, L10().serverCertificateError,
L10().serverCertificateInvalid, L10().serverCertificateInvalid,
); );
@@ -1222,6 +1209,40 @@ class InvenTreeAPI {
return client; return client;
} }
/*
* Cached, reusable HttpClient instance.
* Avoids doing a slow TCP + TLS handshake on each request.
*/
HttpClient? _httpClient;
HttpClient get httpClient {
return _httpClient ??= _createClient();
}
void _resetHttpClient() {
_httpClient?.close(force: true);
_httpClient = null;
_imageCacheManager = null;
}
/*
* Notify the API that the "strictHttps" setting has been changed.
*/
void onStrictHttpsChanged(bool strictHttps) {
if (strictHttps != _strictHttps) {
_strictHttps = strictHttps;
_resetHttpClient();
}
}
Future<void> _refreshHttpsPolicy() async {
final bool strictHttps =
await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false)
as bool;
onStrictHttpsChanged(strictHttps);
}
/* /*
* Initiate a HTTP request to the server * Initiate a HTTP request to the server
* *
@@ -1265,15 +1286,9 @@ class InvenTreeAPI {
HttpClientRequest? _request; HttpClientRequest? _request;
final bool strictHttps =
await InvenTreeSettingsManager().getValue(INV_STRICT_HTTPS, false)
as bool;
var client = createClient(url, strictHttps: strictHttps);
// Attempt to open a connection to the server // Attempt to open a connection to the server
try { try {
_request = await client _request = await httpClient
.openUrl(method, _uri) .openUrl(method, _uri)
.timeout(Duration(seconds: 10)); .timeout(Duration(seconds: 10));
@@ -1593,12 +1608,6 @@ class InvenTreeAPI {
String url = makeUrl(imageUrl); String url = makeUrl(imageUrl);
const key = "inventree_network_image";
CacheManager manager = CacheManager(
Config(key, fileService: InvenTreeFileService(strictHttps: _strictHttps)),
);
return CachedNetworkImage( return CachedNetworkImage(
imageUrl: url, imageUrl: url,
placeholder: (context, url) => CircularProgressIndicator(), placeholder: (context, url) => CircularProgressIndicator(),
@@ -1614,7 +1623,21 @@ class InvenTreeAPI {
httpHeaders: defaultHeaders(), httpHeaders: defaultHeaders(),
height: height, height: height,
width: width, width: width,
cacheManager: manager, cacheManager: imageCacheManager,
);
}
CacheManager? _imageCacheManager;
CacheManager get imageCacheManager {
return _imageCacheManager ??= CacheManager(
Config(
"inventree_network_image",
fileService: InvenTreeFileService(
client: httpClient,
strictHttps: _strictHttps,
),
),
); );
} }
+1
View File
@@ -274,6 +274,7 @@ class _InvenTreeAppSettingsState extends State<InvenTreeAppSettingsWidget> {
value: strictHttps, value: strictHttps,
onChanged: (bool value) { onChanged: (bool value) {
InvenTreeSettingsManager().setValue(INV_STRICT_HTTPS, value); InvenTreeSettingsManager().setValue(INV_STRICT_HTTPS, value);
InvenTreeAPI().onStrictHttpsChanged(value);
setState(() { setState(() {
strictHttps = value; strictHttps = value;
}); });