mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-13 05:16:43 +02:00
Add 'ETag header' option for HTML and direct APK links (#2221) - needs testing
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:obtainium/app_sources/html.dart';
|
||||
import 'package:obtainium/components/generated_form.dart';
|
||||
import 'package:obtainium/custom_errors.dart';
|
||||
import 'package:obtainium/providers/source_provider.dart';
|
||||
|
||||
@ -8,12 +9,23 @@ class DirectAPKLink extends AppSource {
|
||||
|
||||
DirectAPKLink() {
|
||||
name = tr('directAPKLink');
|
||||
additionalSourceAppSpecificSettingFormItems = html
|
||||
.additionalSourceAppSpecificSettingFormItems
|
||||
.where((element) => element
|
||||
.where((element) => element.key == 'requestHeader')
|
||||
.isNotEmpty)
|
||||
.toList();
|
||||
additionalSourceAppSpecificSettingFormItems = [
|
||||
...html.additionalSourceAppSpecificSettingFormItems
|
||||
.where((element) => element
|
||||
.where((element) => element.key == 'requestHeader')
|
||||
.isNotEmpty)
|
||||
.toList(),
|
||||
[
|
||||
GeneratedFormDropdown(
|
||||
'defaultPseudoVersioningMethod',
|
||||
[
|
||||
MapEntry('partialAPKHash', tr('partialAPKHash')),
|
||||
MapEntry('ETag', 'ETag')
|
||||
],
|
||||
label: tr('defaultPseudoVersioningMethod'),
|
||||
defaultValue: 'partialAPKHash')
|
||||
]
|
||||
];
|
||||
excludeCommonSettingKeys = [
|
||||
'versionExtractionRegEx',
|
||||
'matchGroupToUse',
|
||||
@ -57,9 +69,8 @@ class DirectAPKLink extends AppSource {
|
||||
additionalSettingsNew[s] = additionalSettings[s];
|
||||
}
|
||||
}
|
||||
additionalSettingsNew['defaultPseudoVersioningMethod'] = 'partialAPKHash';
|
||||
additionalSettingsNew['directAPKLink'] = true;
|
||||
additionalSettings['versionDetection'] = false;
|
||||
additionalSettingsNew['versionDetection'] = false;
|
||||
return html.getLatestAPKDetails(standardUrl, additionalSettingsNew);
|
||||
}
|
||||
}
|
||||
|
@ -263,7 +263,8 @@ class HTML extends AppSource {
|
||||
'defaultPseudoVersioningMethod',
|
||||
[
|
||||
MapEntry('partialAPKHash', tr('partialAPKHash')),
|
||||
MapEntry('APKLinkHash', tr('APKLinkHash'))
|
||||
MapEntry('APKLinkHash', tr('APKLinkHash')),
|
||||
MapEntry('ETag', 'ETag')
|
||||
],
|
||||
label: tr('defaultPseudoVersioningMethod'),
|
||||
defaultValue: 'partialAPKHash')
|
||||
@ -356,14 +357,24 @@ class HTML extends AppSource {
|
||||
additionalSettings['versionExtractWholePage'] == true
|
||||
? versionExtractionWholePageString
|
||||
: relDecoded);
|
||||
version ??= additionalSettings['defaultPseudoVersioningMethod'] ==
|
||||
'APKLinkHash'
|
||||
? rel.hashCode.toString()
|
||||
: (await checkPartialDownloadHashDynamic(rel,
|
||||
headers: await getRequestHeaders(additionalSettings,
|
||||
forAPKDownload: true),
|
||||
allowInsecure: additionalSettings['allowInsecure'] == true))
|
||||
.toString();
|
||||
var apkReqHeaders =
|
||||
await getRequestHeaders(additionalSettings, forAPKDownload: true);
|
||||
if (version == null &&
|
||||
additionalSettings['defaultPseudoVersioningMethod'] == 'ETag') {
|
||||
version = await checkETagHeader(rel,
|
||||
headers: apkReqHeaders,
|
||||
allowInsecure: additionalSettings['allowInsecure'] == true);
|
||||
if (version == null) {
|
||||
throw NoVersionError();
|
||||
}
|
||||
}
|
||||
version ??=
|
||||
additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash'
|
||||
? rel.hashCode.toString()
|
||||
: (await checkPartialDownloadHashDynamic(rel,
|
||||
headers: apkReqHeaders,
|
||||
allowInsecure: additionalSettings['allowInsecure'] == true))
|
||||
.toString();
|
||||
return APKDetails(
|
||||
version,
|
||||
[rel].map((e) {
|
||||
|
@ -220,6 +220,19 @@ Future<String> checkPartialDownloadHash(String url, int bytesToGrab,
|
||||
return hashListOfLists(bytes);
|
||||
}
|
||||
|
||||
Future<String?> checkETagHeader(String url,
|
||||
{Map<String, String>? headers, bool allowInsecure = false}) async {
|
||||
// Send the initial request but cancel it as soon as you have the headers
|
||||
var reqHeaders = headers ?? {};
|
||||
var req = Request('GET', Uri.parse(url));
|
||||
req.headers.addAll(reqHeaders);
|
||||
var client = IOClient(createHttpClient(allowInsecure));
|
||||
StreamedResponse response = await client.send(req);
|
||||
var resHeaders = response.headers;
|
||||
client.close();
|
||||
return resHeaders[HttpHeaders.etagHeader];
|
||||
}
|
||||
|
||||
Future<File> downloadFile(String url, String fileName, bool fileNameHasExt,
|
||||
Function? onProgress, String destDir,
|
||||
{bool useExisting = true,
|
||||
|
Reference in New Issue
Block a user