Previously I created a REST API which was taking a ZIP file and two other parameters as input from the flutter mobile application

var uri = Uri.parse("http://XX.XXX.XX.XX/gatewayapp/userinfo/sendFileToServer/");
var request = http.MultipartRequest('POST', uri);
     Map<String, String> headers = {
       "Accept": "application/json"
     };
     //add headers
     request.headers.addAll(headers);
     request.fields["customerNumber"] = customerNumber;
     request.fields['zippassword'] = password;
   var file=  await http.MultipartFile.fromPath(
         'userDetailsFile',
         filePath
     );
     request.files.add(file);
     
     await request.send().then((streamedResponse) async {
     ....Implemented the business logic on the response which I was getting
     }

It was working as per the expectation.

We moved the API from HTTP to HTTPS using Nginx on the AWS server and changed all the GET and POST-call from the mobile application using HTTPClient and HttpClientRequest and it worked as per the expectation.

However, we are not able to do a multipart request using HTTPClient and HttpClientRequest on the API. I tried using httpclient method but no luck. I also tried something which is given on the below link :

Using HTTPClient on Dart lang github

var uri = Uri.parse("https://XX.XXX.XX.XX/gatewayapp/userinfo/sendFileToServer/");    
HttpClient client = await CommonController.createHttpClient();
HttpClientRequest request = await client.post( uri.toString() , 443, filePath);

Can anyone please help me move forward in the right direction? Any help would be appreciated! Thanks

1

There are 1 best solutions below

1
On

Apologies for the answering the question so late.

I was able to send ZIP file using SSL (Self Signed certificate deployed on AWS) using the HTTPClient provided by flutter.

Issue

  1. When we generated certificate using Open SSL and added those certificates in the NGINX configuration to enable SSL. (It was not having root permission.)

  2. We were able to hit the first HTTPS request by adding SSL certificate in the HTTPClientRequest as show in below code. But were getting error in the sub sequent HTTP request.

    static Future createHttpClient(//Passing the parameters) async { 
        SecurityContext securityContext = SecurityContext.defaultContext;
        var certificate = (await 
        rootBundle.load(Constants.HTTPS_CRT_PATH)).buffer.asInt8List();
        var key = (await rootBundle.load(Constants.HTTPS_KEY_PATH)).buffer.asInt8List();
        securityContext.useCertificateChainBytes(certificate);
        securityContext.usePrivateKeyBytes(key);
        HttpClient httpClient = new HttpClient(context: securityContext);
        httpClient.badCertificateCallback =
            ((X509Certificate cert, String host, int port) => true);
        HttpClientRequest request = httpClient.postUrl(Uri.parse(url));
        request.contentLength = json.encode(requestBody).length;
        request.write(json.encode(requestBody));
        HttpClientResponse response = await request.close();
        print("response status code "+response.statusCode.toString());
        return response;
    }
    
  3. We were adding the certificate every time we were making a HTTP request and getting a error of Bad SSL Handshake exception :

    I/flutter ( 9066): HandshakeException: Handshake error in client (OS Error:
    I/flutter ( 9066): CERTIFICATE_VERIFY_FAILED: self signed certificate(handshake.cc:354)) 
    

Steps to fix the issue

  1. Add the certificate in the /etc/ssl/ folder of the system as the certificate requires root access.
  2. Second we need to add certificate using Singleton Design pattern just once when we are making the first HTTP request.
  3. Third, when making any HTTP call we just need to use Multipart method of HTTP Client to send the request.

I will add the code sample for adding the certificate using Singleton pattern and making the HTTP calls.