From c14a7ba87e9d72208192675bfb6772bf597ba4b4 Mon Sep 17 00:00:00 2001 From: Dmitry Date: Fri, 19 Dec 2025 05:22:29 +0300 Subject: [PATCH] stuff --- .../lib/api/v2/media_api_v2.dart | 66 ++++++++++--------- .../test/api/v2/media_api_v2_test.mocks.dart | 18 ----- 2 files changed, 35 insertions(+), 49 deletions(-) diff --git a/mnemo_cards_backend/lib/api/v2/media_api_v2.dart b/mnemo_cards_backend/lib/api/v2/media_api_v2.dart index aad1bc8..0cc93d7 100644 --- a/mnemo_cards_backend/lib/api/v2/media_api_v2.dart +++ b/mnemo_cards_backend/lib/api/v2/media_api_v2.dart @@ -23,15 +23,18 @@ class MediaApiV2 { Router get router => _$MediaApiV2Router(this); - Response _ok(Object? object, {Map headers = const {}}) => - Response( - 200, - body: object == null ? null : jsonEncode(object), - headers: { - 'Content-Type': 'application/json', - ...headers, - }, - ); + Response _ok(Object? object, {Map headers = const {}}) { + final body = object == null ? null : jsonEncode(object); + final responseHeaders = { + 'Content-Type': 'application/json; charset=utf-8', + if (body != null) 'Content-Length': body.length.toString(), + ...headers, + }; + return Response.ok( + body, + headers: responseHeaders, + ); + } Response _badRequest(String message) => Response.badRequest( body: jsonEncode({'error': 'Bad Request', 'message': message}), @@ -74,29 +77,30 @@ class MediaApiV2 { await for (final part in multipart.parts) { // Check if this is the 'file' field final contentDisposition = part.headers['content-disposition'] ?? ''; - if (!contentDisposition.contains('name="file"')) { - continue; + if (contentDisposition.contains('name="file"')) { + // Read file bytes + final chunks = >[]; + await for (final chunk in part) { + chunks.add(chunk); + } + fileBytes = Uint8List.fromList( + chunks.expand((chunk) => chunk).toList(), + ); + + // Get content type from part headers + fileContentType = part.headers['content-type'] ?? + 'application/octet-stream'; + + // Extract filename from content-disposition header + final filenameMatch = + RegExp(r'filename="?([^"]+)"?').firstMatch(contentDisposition); + filename = filenameMatch?.group(1); + } else { + // Read and discard other parts to ensure full request is consumed + await for (final _ in part) { + // Discard chunks from other parts + } } - - // Read file bytes - final chunks = >[]; - await for (final chunk in part) { - chunks.add(chunk); - } - fileBytes = Uint8List.fromList( - chunks.expand((chunk) => chunk).toList(), - ); - - // Get content type from part headers - fileContentType = part.headers['content-type'] ?? - 'application/octet-stream'; - - // Extract filename from content-disposition header - final filenameMatch = - RegExp(r'filename="?([^"]+)"?').firstMatch(contentDisposition); - filename = filenameMatch?.group(1); - - break; // Found file, no need to continue } if (fileBytes == null) { diff --git a/mnemo_cards_backend/test/api/v2/media_api_v2_test.mocks.dart b/mnemo_cards_backend/test/api/v2/media_api_v2_test.mocks.dart index 751cb39..a8d531e 100644 --- a/mnemo_cards_backend/test/api/v2/media_api_v2_test.mocks.dart +++ b/mnemo_cards_backend/test/api/v2/media_api_v2_test.mocks.dart @@ -224,22 +224,4 @@ class MockPackManager extends _i1.Mock implements _i8.PackManager { ), ) as _i5.Future<_i3.CardPackDto>); - - @override - _i5.Future> getPackPreviewImages(String? packId) => - (super.noSuchMethod( - Invocation.method(#getPackPreviewImages, [packId]), - returnValue: _i5.Future>.value([]), - ) - as _i5.Future>); - - @override - _i5.Future> getPackImages(String? packId) => - (super.noSuchMethod( - Invocation.method(#getPackImages, [packId]), - returnValue: _i5.Future>.value( - {}, - ), - ) - as _i5.Future>); }