upload method
File upload with progress
Implementation
Future<TClientResponse?> upload(
String path, {
required File file,
Map<String, String>? query,
Map<String, String>? fields,
Map<String, String>? headers,
void Function(int sent, int total)? onUploadProgress,
OnCancelCallback? onCancelCallback,
void Function(String message)? onError,
TClientToken? token,
}) async {
try {
final uri = buildUri(path, query);
final request = await ioClient.postUrl(uri).timeout(options.sendTimeout);
setHeaders(request, headers);
// 1. Boundary တည်ဆောက်ခြင်း
final boundary =
'----dart-boundary-${DateTime.now().millisecondsSinceEpoch}';
request.headers.set(
HttpHeaders.contentTypeHeader,
'multipart/form-data; boundary=$boundary',
);
// 2. Data အားလုံး၏ Total Size ကို ကြိုတင်တွက်ချက်ခြင်း (Progress အတွက်)
final filename = file.path.split(Platform.isWindows ? r'\' : '/').last;
final fileLength = await file.length();
// Header နှင့် End boundary bytes များ
final fileHeader = utf8.encode(
'--$boundary\r\n'
'Content-Disposition: form-data; name="file"; filename="$filename"\r\n'
'Content-Type: application/octet-stream\r\n\r\n',
);
final endBoundary = utf8.encode('\r\n--$boundary--\r\n');
int fieldsSize = 0;
List<List<int>> fieldBytesList = [];
if (fields != null) {
fields.forEach((key, value) {
final part = utf8.encode(
'--$boundary\r\nContent-Disposition: form-data; name="$key"\r\n\r\n$value\r\n',
);
fieldBytesList.add(part);
fieldsSize += part.length;
});
}
final totalSize =
fieldsSize + fileHeader.length + fileLength + endBoundary.length;
request.contentLength =
totalSize; // Size အတိအကျပေးခြင်းဖြင့် server error ကင်းစေသည်
int sent = 0;
// 3. Form Fields များပို့ခြင်း
for (var bytes in fieldBytesList) {
request.add(bytes);
sent += bytes.length;
onUploadProgress?.call(sent, totalSize);
}
// 4. File Header ပို့ခြင်း
request.add(fileHeader);
sent += fileHeader.length;
// 5. File Content ကို Stream ဖြင့်ပို့ခြင်း
final fileStream = file.openRead();
await for (final chunk in fileStream) {
if (token?.isCanceled ?? false) {
request.abort();
onCancelCallback?.call(token!.onCancelMessage);
throw Exception(token!.onCancelMessage);
}
request.add(chunk);
sent += chunk.length;
onUploadProgress?.call(sent, totalSize);
}
// 6. End Boundary ပို့ခြင်း
request.add(endBoundary);
sent += endBoundary.length;
onUploadProgress?.call(sent, totalSize);
// 7. Response ရယူခြင်း
final response = await request.close().timeout(options.receiveTimeout);
final responseBody = await response.transform(utf8.decoder).join();
return TClientResponse(
statusCode: response.statusCode,
headers: getResponseHeaders(response),
data: responseBody,
);
} catch (e) {
TClientLogger.instance.showLog(e.toString(), tag: 'upload');
onError?.call(e.toString());
rethrow;
}
}