Vydia / react-native-background-upload

Upload files in your React Native app even while it's backgrounded. Supports Android and iOS, including camera roll assets.
MIT License
723 stars 330 forks source link

Write error: ssl=0xc79b92e8: I/O error during system call, Connection reset by peer% #221

Closed matamicen closed 3 years ago

matamicen commented 3 years ago

Hi @reime005 , me again :)

The library is throwing this error on Android (8 & 10 ate least)

Write error: ssl=0xc79b92e8: I/O error during system call, Connection reset by peer%

We are with RN 063.2 and wiht react-native-background-upload v.6.2.0

here is the code, we call before this a pre signed API in order to upload to s3 bucket.

auxfile = fileaux.replace('file://', '');

  const options = {
    url: respuesta.body.data.url,
    path: auxfile,
    method: 'POST',
    type: 'raw',
    maxRetries: 2, // set retry count (Android only). Default 2
    headers: {
      'Content-Type' : respuesta.body.data.fields['Content-Type'],
      'key' : respuesta.body.data.fields['key'],
      'bucket' : respuesta.body.data.fields['bucket'],
      'X-Amz-Algorithm' : respuesta.body.data.fields['X-Amz-Algorithm'] ,
      'X-Amz-Credential' : respuesta.body.data.fields['X-Amz-Credential'],
      'X-Amz-Date' : respuesta.body.data.fields['X-Amz-Date'],
      'X-Amz-Security-Token' : respuesta.body.data.fields['X-Amz-Security-Token'],
      'Policy' : respuesta.body.data.fields['Policy'],
      'X-Amz-Signature' : respuesta.body.data.fields['X-Amz-Signature'], 
    },
    // Below are options only supported on Android
    notification: {
      enabled: true
    },
    useUtf8Charset: true
  }

  Upload.startUpload(options).then((uploadId) => {
    console.log('Upload started')
    Upload.addListener('progress', uploadId, (data) => {
      console.log(`Progress: ${data.progress}%`)
    })
    Upload.addListener('error', uploadId, (data) => {
      console.log(`Error BackgroundUpload: ${data.error}%`)
    })
    Upload.addListener('cancelled', uploadId, (data) => {
      console.log(`Cancelled!`)
    })
    Upload.addListener('completed', uploadId, (data) => {
      // data includes responseCode: number and responseBody: Object
      console.log('Completed!')
    })
  }).catch((err) => {
    console.log('Upload error!', err)
  })

any ideas?

Thnaks!!

matamicen commented 3 years ago

More info: We are trying to upload videos less than 10mb and we are not using multipart.

matamicen commented 3 years ago

This ssl error was becasue we were sending the AWS data from the Pre Signed Function in HEADER and it has to be placed in PARAMETERS, here the working code, may be help someone, this library is working great to upload to S3 bucket! Thanks guys!


auxfile = fileaux.replace('file://', '');
  console.log('fileaux antes de startupload: '+ auxfile )
  const fileInfo = await Upload.getFileInfo(auxfile);
  console.log(fileInfo)
  console.log('fileinfoMimetype: '+fileInfo.mimeType)
  const options = {
    url: respuesta.body.data.url,
    field: 'file',
    path: auxfile,
    method: 'POST',
    type: 'multipart',
    maxRetries: 2, // set retry count (Android only). Default 2
    headers: {

      'content-type': fileInfo.mimeType,

    },
    parameters: {
      'content-type': fileInfo.mimeType,
      'key' : respuesta.body.data.fields['key'],
      'bucket' : respuesta.body.data.fields['bucket'],
      'X-Amz-Algorithm' : respuesta.body.data.fields['X-Amz-Algorithm'] ,
      'X-Amz-Credential' : respuesta.body.data.fields['X-Amz-Credential'],
      'X-Amz-Date' : respuesta.body.data.fields['X-Amz-Date'],
      'X-Amz-Security-Token' : respuesta.body.data.fields['X-Amz-Security-Token'],
      'Policy' : respuesta.body.data.fields['Policy'],
      'X-Amz-Signature' : respuesta.body.data.fields['X-Amz-Signature'], 

    },

    // Below are options only supported on Android
    notification: {
      enabled: true
    },
    useUtf8Charset: true
  }

  Upload.startUpload(options).then((uploadId) => {
    console.log('Upload started')
    Upload.addListener('progress', uploadId, (data) => {
      console.log(`Progress: ${data.progress}%`)
    })
    Upload.addListener('error', uploadId, (data) => {
      console.log(`Error BackgroundUpload: ${data.error}%`)
    })
    Upload.addListener('cancelled', uploadId, (data) => {
      console.log(`Cancelled!`)
    })
    Upload.addListener('completed', uploadId, (data) => {
      // data includes responseCode: number and responseBody: Object
      console.log('Completed!')
    })
  }).catch((err) => {
    console.log('Upload error!', err)
  })
CuongNguyenLD commented 3 years ago

Hi @matamicen, could you tell me how to get these parameters, the url and the policy please! I'm using AWS.S3().getSignedUrlPromise() to get the url and Signer.sign() to get these params but look like it's not working :(. Thank in advance!!

matamicen commented 3 years ago

@Nagato717 this is the code who calls the pre signed API before UPLOAD, we use ApiGateway & Lambda.

 // call API pre signed
            let apiName = 'project1One';
            let path = "/s3presignedpost";
            let myInit = { 
              headers: {
                'Authorization': jwtToken,
                "Access-Control-Allow-Origin": "*",
                'Content-Type': 'application/json'
              }, 
              body: {
                name: fileName2,

                  }

            }

respuesta = await API.post(apiName, path, myInit);

And this is part of the lambda function:

....
const createPresignedPost = ({ key, contentType }) => {
  const s3 = new AWS.S3();
  const params = {
    Expires: 60,
    Bucket: "proonedsa-project1one-34596hbrl2456",
    Conditions: [["content-length-range", 100, 70000000]], // 100Byte - 10MB
    Fields: {
      "Content-Type": contentType,
      key,
    },
  };

  return new Promise(async (resolve, reject) => {
    s3.createPresignedPost(params, (err, data) => {
      if (err) {
        console.log(err);
        reject(err);
        return;
      }
      console.log(data);
      resolve(data);
    });
  });
};

  const presignedPostData = await createPresignedPost({
      key: `1/videos/${name}`,
      contentType: mime.getType(name),
    });

    return {
      statusCode: 200,
      headers,
      body: {
        error: false,
        data: presignedPostData,
        message: null,
      },
...
iOrcohen commented 2 years ago

@matamicen Thanks for the details explanation ! I actually did the same as you did, and I'm facing error of : "java.net.SocketException: Broken pipe" Did you know anything about it ? thanks ahead!