0

I want to understand and know how to make a multiPart request with an mp4 file attached. While I understand there are posts that speak of dependencies such as dio or flutter_upload to do this, I don't want to cheat myself in knowing the why of things. So how do I accomplish this task? I keep getting the following error when making a request:

Error Snippet:

flutter: Failed due to: Unsupported Media Type and status code: 415

My endpoint only accepts Content-Types of application/JSON, but my app still threw when I tried to refactor my request to send json. I understand Dart requires data to be encoded before making a request but I am confused about how I do this with a MultipartFile instance when I get the following error: The argument type 'String' can't be assigned to the parameter type 'MultipartFile'. Finally, I refactored my function to reflect my latest attempt to send the correct format (despite no encoding involved :D).

Code Snippet:

Future<void> createAudioUpload(String fileUrl) async {
  Uri ourUri = Uri.parse(
      'https://[redacted]');
  final request =
      http.MultipartRequest('POST', ourUri); // creates our req instance

  final file = await http.MultipartFile.fromPath('audio', fileUrl,
      contentType: MediaType('audio', 'mp4')); // points a ref to file

  request.files.add(file); // adds our file to our request instance
  final response = await request.send(); // sends our request to the endpoint!

  if (response.statusCode == 200) {
    print('Success, $response');
  } else {
    print('Failed due to:${response.reasonPhrase}');
  }
}

Code Snippet V2: (sending data as bytes)

Future<void> createAudioUpload(String fileUrl) async {
  Uri ourUri = Uri.parse(
      '[redacted]');
  final request =
      http.MultipartRequest('POST', ourUri); // creates our req instance

  File ourFile = File(fileUrl);
  List<int> fileBytes = ourFile.readAsBytesSync();
  // String base64File = base64Encode(fileBytes);

  final file = http.MultipartFile.fromBytes('flutter_sound', fileBytes,
      filename: fileUrl.split("/").last,
      );

  request.files.add(file); // adds our file to our request instance
  final response = await request.send(); // sends our request to the endpoint!

  if (response.statusCode == 200) {
    print('Success, $response');
  } else {
    print('Failed due to: ${response.reasonPhrase} and status code: ${response.statusCode} ');
  }
}

Questions I want to understand (after I referenced flutter docs):

  1. What is supposed to be the first positional argument of MultipartFile.fromPath
  2. What is the correct syntax to pass for application/json? would the arguments be passed as "application", "json" for MIME main and sub type per the docs at https://pub.dev/documentation/http_parser/latest/http_parser/MediaType/MediaType.html ?

Quick Note

  1. The data passes through an API gateway and is eventually stored in an S3 bucket.
  2. I referenced https://pub.dev/documentation/http/latest/http/MultipartRequest-class.html for constructing the code.
  3. If there is known documentation how to convert the audio file to bytes before sending that is also great!

Any help is appreciated.

Dan der Mensch
  • 322
  • 2
  • 13
  • 1
    I don't believe you can use a multipart request as they will all have a `Content-Type` of `multipart/something` which you say your endpoint cannot accept. Is there anything wrong with just a normal POST request? – Christopher Moore Apr 30 '21 at 20:48
  • Hey Chris, when I submit a normal POST request without additional headers I still get the same error. I am looking to see if there can be some tweaks to what the endpoint receives instead. – Dan der Mensch May 03 '21 at 13:24
  • Could you show the error and maybe edit your question to add the code to show what you tried to do? – Christopher Moore May 03 '21 at 14:32
  • The error code above is already included above for the status code of: 415. And I just added another snippet of my attempt to send data in byte format. The main point of confusion for me is knowing what to do with the **MultipartFile** constructor – Dan der Mensch May 03 '21 at 15:22
  • 1
    What I meant in my first comment was to use the [`post`](https://pub.dev/documentation/http/latest/http/post.html) function to send the data because using the multipart request will set the content-type to `multipart/something` which your endpoint then rejects with the expected 415. Using a post would allow send JSON data and set the correct headers. Could you elaborate on your confusion with the `MultipartFile` constructors? Or why you want to continue with them? The `fromPath` static method takes a *full* file path as its first argument and you're using the `fromBytes` constructor correctly. – Christopher Moore May 03 '21 at 15:31
  • Awesome! I just realized what you said. After implementing your observation I deviated from submitting an instance of Multipart form to submitting the byte formatted audio wrapped in JSON. The bucket confirmed with a 200 response and my audio file was stored in the S3 bucket! – Dan der Mensch May 03 '21 at 21:47
  • As to your question Chris, I was referencing https://stackoverflow.com/questions/59809222/flutter-http-request-upload-mp3-file and one other post when writing that code to accomplish my goal. I became so absorbed in finding the solution that I ignored my payload type did not match my endpoint to begin with. For the downvote, if whoever could be so kind as to explain where my post is lacking so I may better format my questions in the future since I covered the issue, included snippets of my code and error. Thanks! – Dan der Mensch May 03 '21 at 21:50
  • 1
    The only reason I could think of for the downvote is you have multiple question in a single post, which is discouraged and a reason your question could be closed. So something to be wary of. However, this is one of the few well-researched and well-described posts on the flutter tag so I upvoted to compensate for whoever downvoted you :). Based on how I led you to a solution in the comments, the downvoter might have also voted because the problem you describe is an [X-Y](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) problem, but I don't see that as a reason to downvote. – Christopher Moore May 03 '21 at 22:16

0 Answers0