Skip to content

Multipart file uploads to AWS S3 fail with cuppertino_http but work with HttpClient: Missing content length #1236

Closed
@escamoteur

Description

@escamoteur

While exited about the new cupertino_http package we found out, that we currently can't use it because it does not att a Content-Length header in Multipart file uploads and if I add this header manually I get an 400 from S3 with the message that the request isn't a well-formed multipart request.

See how they compare:

image

I also attach the two requests as raw text files ( I only replace our URLs with XXX)
I also wonder why the Cupertino Client includes data from sentry in a Request that has nothing to do with sentry. this could be a privacy violation.

this is how we do the Upload:

  @override
  Future<MediaUploadPayload> uploadImage(File file) async {
    final api = S3Api(di<ApiClient>());
    final s3Response = await api.getS3PresignedData();
    final S3AccessData accessData = s3Response!.data!;

    final String fileExt = file.path.split('.').last;

    final contentType = lookupMimeType(file.path) ?? 'application/octet-stream';

    var fileLength = await file.length();
    final multipartFile = http.MultipartFile(
      'file',
      file.openRead(),
      fileLength,
      contentType: MediaType.parse(contentType),
    );

    var relativeImagePath = generateImagePath(fileExt);

    final multipartRequest =
        http.MultipartRequest('POST', Uri.parse(accessData.endpointUrl));

    multipartRequest.fields.addAll({
      for (final field in accessData.params.entries)
        field.key: field.value.toString(),
    });
    multipartRequest.fields.addAll({
      'Content-Type': contentType,
      'key': relativeImagePath,
    });
    multipartRequest.files.add(multipartFile);

    final multipartResponse = await multipartRequest.send();
    final response = await http.Response.fromStream(multipartResponse);

    if (response.statusCode != 201) {
      throw Exception('Failed to upload file to S3: ${response.body}');
    }

As we have customers who complain about uploading errors (Connection closed before...) on iOS we would really like to use the new client. If we can change something in the way we use it any pointer would be really helpful.
As it works with the normal Dart HttpClient and in cronnet it seems to be a problem with cupertino_htttp.
cuppertino_client.txt
HttpClient.txt

cc @brianquinlan

Metadata

Metadata

Assignees

Labels

package:cupertino_httpIssues related to package:cupertino_httptype-bugIncorrect behavior (everything from a crash to more subtle misbehavior)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions