react-nativeuppytustus-js-clienttusdotnet

How to resolve application/octet-stream in S3 using TUS node, Tusd, Uppy or .NET,


This is an explanation of a problem, I encountered while uploading files to S3 using tus-node-server or Tusd.

The problem, is I have a server running tus server and takes requests from react and react native clients. The file gets uploaded successfully from the client to S3, but when I check inside S3 bucket, the content-type is always converted to application/octet-stream.

Tried setting the content-type headers but the tus server didn't like that.

In the answer below I explain how to resolve the issue:


Solution

  • It turns out that it has to be passed as a metadata like this from tus-js-client or uppy client.

    Code looks like this:

    uppy

           uppy.addFiles({
                  name: asset.fileName,
                  type: asset.type,
                  data: asset,
                  meta: {
                    name: asset.fileName,
                    type: asset.type,
                    contentType: asset.type, //This field is how you set content-type, it will be parsed on the tus server automatically and will set the correct content-type
                  },
           })

    tus-js-client

            var upload = new tus.Upload({
                  name: asset.fileName,
                  type: asset.type,
                  data: asset,
                  meta: {
                    name: asset.fileName,
                    type: asset.type,
                    contentType: asset.type, //This field is how you set content-type, it will be parsed on the tus server automatically and will set the correct content-type
                  }
            }, {
            endpoint: "http://localhost:1080/files/",
            retryDelays: [0, 3000, 5000, 10000, 20000],
            metadata: {
                filename: file.name,
                filetype: file.type
            },
            onError: function(error) {
                console.log("Failed because: " + error)
            },
            onProgress: function(bytesUploaded, bytesTotal) {
                var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
                console.log(bytesUploaded, bytesTotal, percentage + "%")
            },
            onSuccess: function() {
                console.log("Download %s from %s", upload.file.name, upload.url)
            }
        })
        
        // Check if there are any previous uploads to continue.
        upload.findPreviousUploads().then(function (previousUploads) {
            // Found previous uploads so we select the first one. 
            if (previousUploads.length) {
                upload.resumeFromPreviousUpload(previousUploads[0])
            }
        
            // Start the upload
            upload.start()
        })

    Please note that contentType is the key to setting the content-type on the tus server header. The metadata will be decoded and will be set correctly to S3 content-type.