mirror of
https://github.com/ImranR98/Obtainium.git
synced 2025-07-31 21:00:15 +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:easy_localization/easy_localization.dart';
|
||||||
import 'package:obtainium/app_sources/html.dart';
|
import 'package:obtainium/app_sources/html.dart';
|
||||||
|
import 'package:obtainium/components/generated_form.dart';
|
||||||
import 'package:obtainium/custom_errors.dart';
|
import 'package:obtainium/custom_errors.dart';
|
||||||
import 'package:obtainium/providers/source_provider.dart';
|
import 'package:obtainium/providers/source_provider.dart';
|
||||||
|
|
||||||
@@ -8,12 +9,23 @@ class DirectAPKLink extends AppSource {
|
|||||||
|
|
||||||
DirectAPKLink() {
|
DirectAPKLink() {
|
||||||
name = tr('directAPKLink');
|
name = tr('directAPKLink');
|
||||||
additionalSourceAppSpecificSettingFormItems = html
|
additionalSourceAppSpecificSettingFormItems = [
|
||||||
.additionalSourceAppSpecificSettingFormItems
|
...html.additionalSourceAppSpecificSettingFormItems
|
||||||
.where((element) => element
|
.where((element) => element
|
||||||
.where((element) => element.key == 'requestHeader')
|
.where((element) => element.key == 'requestHeader')
|
||||||
.isNotEmpty)
|
.isNotEmpty)
|
||||||
.toList();
|
.toList(),
|
||||||
|
[
|
||||||
|
GeneratedFormDropdown(
|
||||||
|
'defaultPseudoVersioningMethod',
|
||||||
|
[
|
||||||
|
MapEntry('partialAPKHash', tr('partialAPKHash')),
|
||||||
|
MapEntry('ETag', 'ETag')
|
||||||
|
],
|
||||||
|
label: tr('defaultPseudoVersioningMethod'),
|
||||||
|
defaultValue: 'partialAPKHash')
|
||||||
|
]
|
||||||
|
];
|
||||||
excludeCommonSettingKeys = [
|
excludeCommonSettingKeys = [
|
||||||
'versionExtractionRegEx',
|
'versionExtractionRegEx',
|
||||||
'matchGroupToUse',
|
'matchGroupToUse',
|
||||||
@@ -57,9 +69,8 @@ class DirectAPKLink extends AppSource {
|
|||||||
additionalSettingsNew[s] = additionalSettings[s];
|
additionalSettingsNew[s] = additionalSettings[s];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
additionalSettingsNew['defaultPseudoVersioningMethod'] = 'partialAPKHash';
|
|
||||||
additionalSettingsNew['directAPKLink'] = true;
|
additionalSettingsNew['directAPKLink'] = true;
|
||||||
additionalSettings['versionDetection'] = false;
|
additionalSettingsNew['versionDetection'] = false;
|
||||||
return html.getLatestAPKDetails(standardUrl, additionalSettingsNew);
|
return html.getLatestAPKDetails(standardUrl, additionalSettingsNew);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -263,7 +263,8 @@ class HTML extends AppSource {
|
|||||||
'defaultPseudoVersioningMethod',
|
'defaultPseudoVersioningMethod',
|
||||||
[
|
[
|
||||||
MapEntry('partialAPKHash', tr('partialAPKHash')),
|
MapEntry('partialAPKHash', tr('partialAPKHash')),
|
||||||
MapEntry('APKLinkHash', tr('APKLinkHash'))
|
MapEntry('APKLinkHash', tr('APKLinkHash')),
|
||||||
|
MapEntry('ETag', 'ETag')
|
||||||
],
|
],
|
||||||
label: tr('defaultPseudoVersioningMethod'),
|
label: tr('defaultPseudoVersioningMethod'),
|
||||||
defaultValue: 'partialAPKHash')
|
defaultValue: 'partialAPKHash')
|
||||||
@@ -356,14 +357,24 @@ class HTML extends AppSource {
|
|||||||
additionalSettings['versionExtractWholePage'] == true
|
additionalSettings['versionExtractWholePage'] == true
|
||||||
? versionExtractionWholePageString
|
? versionExtractionWholePageString
|
||||||
: relDecoded);
|
: relDecoded);
|
||||||
version ??= additionalSettings['defaultPseudoVersioningMethod'] ==
|
var apkReqHeaders =
|
||||||
'APKLinkHash'
|
await getRequestHeaders(additionalSettings, forAPKDownload: true);
|
||||||
? rel.hashCode.toString()
|
if (version == null &&
|
||||||
: (await checkPartialDownloadHashDynamic(rel,
|
additionalSettings['defaultPseudoVersioningMethod'] == 'ETag') {
|
||||||
headers: await getRequestHeaders(additionalSettings,
|
version = await checkETagHeader(rel,
|
||||||
forAPKDownload: true),
|
headers: apkReqHeaders,
|
||||||
allowInsecure: additionalSettings['allowInsecure'] == true))
|
allowInsecure: additionalSettings['allowInsecure'] == true);
|
||||||
.toString();
|
if (version == null) {
|
||||||
|
throw NoVersionError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
version ??=
|
||||||
|
additionalSettings['defaultPseudoVersioningMethod'] == 'APKLinkHash'
|
||||||
|
? rel.hashCode.toString()
|
||||||
|
: (await checkPartialDownloadHashDynamic(rel,
|
||||||
|
headers: apkReqHeaders,
|
||||||
|
allowInsecure: additionalSettings['allowInsecure'] == true))
|
||||||
|
.toString();
|
||||||
return APKDetails(
|
return APKDetails(
|
||||||
version,
|
version,
|
||||||
[rel].map((e) {
|
[rel].map((e) {
|
||||||
|
@@ -220,6 +220,19 @@ Future<String> checkPartialDownloadHash(String url, int bytesToGrab,
|
|||||||
return hashListOfLists(bytes);
|
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,
|
Future<File> downloadFile(String url, String fileName, bool fileNameHasExt,
|
||||||
Function? onProgress, String destDir,
|
Function? onProgress, String destDir,
|
||||||
{bool useExisting = true,
|
{bool useExisting = true,
|
||||||
|
Reference in New Issue
Block a user