fix(version-service+gateway+app): fix APK download 404 and SHA-256 false failure
Three coordinated fixes to make in-app APK download work end-to-end:
1. version-service/main.ts: serve uploaded files as static assets via
NestExpressApplication.useStaticAssets('/data/versions', prefix:
'/downloads/versions'), so GET /downloads/versions/{platform}/{file}
returns the actual APK stored in the Docker volume.
2. kong.yml: add /downloads/versions route to Kong so requests from
the Flutter app can reach version-service through the API gateway.
Previously only /api/v1/versions and /api/app/version were routed;
the download URL returned by the check endpoint was unreachable (404).
3. download_manager.dart: skip SHA-256 verification when sha256Expected
is empty string. The check endpoint always returns sha256:"" because
version-service doesn't store file hashes. The previous code compared
actual_hash == "" which always failed, causing the downloaded file to
be deleted after a successful download.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0f328b9794
commit
e6f864d409
|
|
@ -118,18 +118,22 @@ class DownloadManager {
|
|||
await tempFile.rename(savePath);
|
||||
|
||||
debugPrint('Download completed');
|
||||
_status = DownloadStatus.verifying;
|
||||
|
||||
// 校验 SHA-256
|
||||
final isValid = await _verifySha256(file, sha256Expected);
|
||||
if (!isValid) {
|
||||
debugPrint('SHA-256 verification failed');
|
||||
await file.delete();
|
||||
_status = DownloadStatus.failed;
|
||||
return null;
|
||||
// 校验 SHA-256(仅在服务器提供了哈希值时校验)
|
||||
if (sha256Expected.isNotEmpty) {
|
||||
_status = DownloadStatus.verifying;
|
||||
final isValid = await _verifySha256(file, sha256Expected);
|
||||
if (!isValid) {
|
||||
debugPrint('SHA-256 verification failed');
|
||||
await file.delete();
|
||||
_status = DownloadStatus.failed;
|
||||
return null;
|
||||
}
|
||||
debugPrint('SHA-256 verified');
|
||||
} else {
|
||||
debugPrint('SHA-256 not provided, skipping verification');
|
||||
}
|
||||
|
||||
debugPrint('SHA-256 verified');
|
||||
_status = DownloadStatus.completed;
|
||||
return file;
|
||||
} on DioException catch (e) {
|
||||
|
|
|
|||
|
|
@ -124,6 +124,10 @@ services:
|
|||
paths:
|
||||
- /api/app/version
|
||||
strip_path: false
|
||||
- name: app-version-download-route
|
||||
paths:
|
||||
- /downloads/versions
|
||||
strip_path: false
|
||||
|
||||
- name: billing-service
|
||||
url: http://billing-service:3010
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { VersionModule } from './version.module';
|
||||
|
|
@ -13,9 +14,13 @@ process.on('uncaughtException', (error) => {
|
|||
});
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(VersionModule);
|
||||
const app = await NestFactory.create<NestExpressApplication>(VersionModule);
|
||||
const config = app.get(ConfigService);
|
||||
const port = config.get<number>('VERSION_SERVICE_PORT', 3009);
|
||||
// Serve uploaded APK/IPA files as static assets
|
||||
// Files are stored at /data/versions/{platform}/filename
|
||||
// Accessible via GET /downloads/versions/{platform}/filename
|
||||
app.useStaticAssets('/data/versions', { prefix: '/downloads/versions' });
|
||||
await app.listen(port);
|
||||
logger.log(`version-service running on port ${port}`);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue