http icon indicating copy to clipboard operation
http copied to clipboard

MultipartRequest dosen't work

Open hemanthrajv opened this issue 6 years ago • 3 comments

I'm trying to upload a image file using MultipartRequest, it dosen't seem to work. I checked using postman, api seem to work fine. Not sure whats wrong with the MultipartRequest.

My Code:

Future<List<String>> uploadImage(SubmitData data, String token) async {
    String path = data.imageFile;
    if (Platform.isIOS) {
      path = Uri.parse(path).toFilePath();
    }

    final Uri uri = Uri.parse(_getUrl(path: '/api/v1/upload'));
    final MultipartRequest request = MultipartRequest('POST', uri);
    request.headers['Authorization'] = token;

    request.fields['id'] = data.id.toString();

    final MultipartFile multipartFile =
        await MultipartFile.fromPath('image', path);
    request.files.add(multipartFile);

    final StreamedResponse response = await request.send();
    final String res = await response.stream.transform(utf8.decoder).join();
    final List<dynamic> temp = json.decode(res)['images'];
    return temp.cast<String>();
}

I'm getting an error: Sometimes SocketException: Write failed (OS Error: Broken pipe, errno = 32), or SocketException: Connection reset by peer (OS Error: Broken pipe, errno = 54),

not sure why this would ever happen.

hemanthrajv avatar Jan 28 '19 17:01 hemanthrajv

I am also facing similar kind of issue.

When I am trying to upload video file to AWS S3 bucket using Multipart, I am facing SocketException: OS Error: Broken pipe, errno = 32, address = address, port = 42644

import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:amazon_cognito_identity_dart_2/sig_v4.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

class AWSClientService {

  Future<Map<String, String>> uploadData({
    @required String folderName,
    @required String fileName,
    @required Uint8List data,
    @required File fileDet,
    @required String filePath,
    @required String accessKeyId,
    @required String secretKeyId,
    @required String region,
    @required String bucketname,
    @required String s3Endpoint,
  }) async {
    final length = data.length;
    final uri = Uri.parse(s3Endpoint);
    var req = http.MultipartRequest("POST", uri);

    final multipartFile = http.MultipartFile(
      'videofiles',
      http.ByteStream.fromBytes(data),
      length,
      filename: fileName,
    );

    
    final policy = Policy.fromS3PresignedPost(
        folderName + fileName, bucketname, accessKeyId, 15, length,
        region: region);
    final key =
        SigV4.calculateSigningKey(secretKeyId, policy.datetime, region, 's3');
    final signature = SigV4.calculateSignature(
      key,
      policy.encode(),
    );

    print("Adding");
    req?.files?.add(multipartFile);
    print("Added");

    req.fields['key'] = policy.key;
    req.fields['acl'] = 'public-read';
    req.fields['X-Amz-Credential'] = policy.credential;
    req.fields['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
    req.fields['X-Amz-Date'] = policy.datetime;
    req.fields['Policy'] = policy.encode();
    req.fields['X-Amz-Signature'] = signature;

    
    try {
     
      var res = await req.send();
      

      var resp = res?.stream?.transform(utf8.decoder);
      
      if (res.statusCode == 200) {
        print("Status code: ${res.statusCode}");
        var bytes = <int>[];

        res.stream.listen((newBytes) {
          bytes.addAll(newBytes);
          print("Stream: $bytes");
        }).onDone(
          () async {
            await fileDet.writeAsBytes(bytes);
            print("On Done: $bytes");
          },
        );
      } else {
        
        var response = await http.Response.fromStream(res);
        
        if (response != null && response?.headers != null) {
          return response.headers;
        } else {
          return {};
        }
      }
    } catch (e) {
      
      print(e.toString());
      return e;
    }
  }
}

class Policy {
  String expiration;
  String region;
  String bucket;
  String key;
  String credential;
  String datetime;
  int maxFileSize;

  Policy(this.key, this.bucket, this.datetime, this.expiration, this.credential,
      this.maxFileSize,
      {this.region = 'ap-south-1'});

  factory Policy.fromS3PresignedPost(
    String key,
    String bucket,
    String accessKeyId,
    int expiryMinutes,
    int maxFileSize, {
    String region,
  }) {
    final datetime = SigV4.generateDatetime();
    final expiration = (DateTime.now())
        .add(Duration(minutes: expiryMinutes))
        .toUtc()
        .toString()
        .split(' ')
        .join('T');
    final cred =
        '$accessKeyId/${SigV4.buildCredentialScope(datetime, region, 's3')}';
    final p = Policy(key, bucket, datetime, expiration, cred, maxFileSize,
        region: region);
    return p;
  }

  String encode() {
    final bytes = utf8.encode(toString());
    return base64.encode(bytes);
  }

  @override
  String toString() {
    return '''
{ "expiration": "${this.expiration}",
  "conditions": [
    {"bucket": "${this.bucket}"},
    ["starts-with", "\$key", "${this.key}"],
    {"acl": "public-read"},
    ["content-length-range", 1, ${this.maxFileSize}],
    {"x-amz-credential": "${this.credential}"},
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    {"x-amz-date": "${this.datetime}" }
  ]
}
''';
  }
}

tejaswinidev24 avatar Mar 15 '22 09:03 tejaswinidev24

Hello, was anyone able to solve this problem? Currently I have the same problem, I use http 0.13.5 and I can't upload images, when I see the chrome inspector in the network tab it doesn't send the file.

sebasrod avatar Mar 12 '23 00:03 sebasrod

Is there Anyone who solve this problem? My function works on dev server and doesnt work on production server.

At production server, the request of app doesnt reach to my server

hanolee avatar Apr 26 '24 05:04 hanolee