upload method

  1. @override
Future<AdapterResponse> upload(
  1. AdapterRequest request, {
  2. ProgressCallback? onProgress,
})
override

Uploads data to the server.

This method uploads data (typically files) to the server. Progress can be tracked using the optional onProgress callback.

Parameters:

  • request: The request configuration for the upload, including the data to upload
  • onProgress: Optional callback to track upload progress

Returns a Future that completes with an AdapterResponse when the upload is complete.

Throws AdapterException if the upload fails.

Example:

final request = AdapterRequest(
  baseUrl: 'https://api.example.com',
  path: '/upload',
  method: HttpMethod.post,
  bodyParams: {'file': File('/path/to/file.jpg')},
);

await adapter.upload(
  request,
  onProgress: (count, total) {
    print('Uploaded: ${(count / total * 100).toStringAsFixed(1)}%');
  },
);

Implementation

@override
Future<AdapterResponse> upload(
  AdapterRequest request, {
  ProgressCallback? onProgress,
}) async {
  try {
    // 构建 URI
    final uri = _buildUri(request);

    // 创建 multipart 请求
    final multipartRequest = http.MultipartRequest(
      request.method.name.toUpperCase(),
      uri,
    );

    // 添加头部
    final headers = _buildHeaders(request);
    multipartRequest.headers.addAll(headers);

    // 添加字段和文件
    for (final entry in request.bodyParams.entries) {
      if (entry.value is File) {
        final file = entry.value as File;
        multipartRequest.files.add(
          await http.MultipartFile.fromPath(entry.key, file.path),
        );
      } else if (entry.value is http.MultipartFile) {
        multipartRequest.files.add(entry.value as http.MultipartFile);
      } else {
        multipartRequest.fields[entry.key] = entry.value.toString();
      }
    }

    // 发送请求
    final streamedResponse = await multipartRequest.send();

    // 读取响应
    final responseBody = await streamedResponse.stream.bytesToString();

    // 解析响应数据
    dynamic data;
    try {
      final contentType = streamedResponse.headers['content-type'] ?? '';
      if (contentType.contains('application/json')) {
        data = jsonDecode(responseBody);
      } else {
        data = responseBody;
      }
    } catch (e) {
      data = responseBody;
    }

    // 转换头部
    final responseHeaders = <String, List<String>>{};
    streamedResponse.headers.forEach((key, value) {
      responseHeaders[key] = [value];
    });

    final response = AdapterResponse(
      statusCode: streamedResponse.statusCode,
      statusMessage: streamedResponse.reasonPhrase,
      data: data,
      headers: responseHeaders,
      request: request,
    );

    // 检查是否是错误响应
    if (!response.isSuccess) {
      throw AdapterException(
        message: 'HTTP ${response.statusCode}',
        type: AdapterExceptionType.response,
        statusCode: response.statusCode,
        response: response,
      );
    }

    return response;
  } catch (e, stackTrace) {
    if (e is AdapterException) {
      rethrow;
    }
    throw _convertException(e, stackTrace);
  }
}