The Community is undergoing a major upgrade. Find out more, ask us questions or share your thoughts here.

Forum Discussion

Impulsum Support's avatar
Impulsum Support
New member | Level 2
2 years ago

File got corrupted while uploading in chunks to dropbox using API calls.

Hi Team,

 

Using Apex code, I tried to upload a large (>5MB) file in chunks, But the file is getting corrupted always. Please help me. Below is the code.

 

public class relatedFile {
public String Title;
public string filepath;
public Blob VersionData;
}

@AuraEnabled(cacheable=false)
public static string createFile(List<Map<String, Object>> files, Boolean finalChunk, Integer chunksize, string dpaccessToken, string dpteamMemberId,
string dpfileRootNamespaceId, string dpuploadsession)
{
try{
system.debug('files: '+files);
Map<String, Object> file = files[0];
system.debug('file: '+file);
String fileJson = JSON.serialize(file);
system.debug('fileJson: '+fileJson);
relatedFile relatedDocument = (relatedFile) JSON.deserialize(fileJson, relatedFile.class);
system.debug('relatedDocument.VersionData: '+relatedDocument.VersionData);
system.debug('relatedDocument.filepath: '+relatedDocument.filepath);
system.debug('relatedDocument.Title: '+relatedDocument.Title);
system.debug('finalChunk: '+finalChunk);
system.debug('chunksize: '+chunksize);
system.debug('accessToken: '+dpaccessToken);
system.debug('teamMemberId: '+dpteamMemberId);
system.debug('fileRootNamespaceId: '+dpfileRootNamespaceId);
Blob data = relatedDocument.VersionData;

string uploadfileaccesstoken;
string uploadfileteammemberId;
string uploadfileroot_namespace_id;
string uploadsessionid;

System.debug('createFile');
system.debug('in append data size: '+data.size());
integer size = 0;
system.debug('size: '+size);

if(chunksize==0){
system.debug('in start');
uploadfileaccesstoken = getAccessToken();
system.debug('uploadfileaccesstoken: '+uploadfileaccesstoken);

uploadfileteammemberId= getTeamInfo(uploadfileaccesstoken);
system.debug('teammemberId: '+uploadfileteammemberId);

uploadfileroot_namespace_id = getCurrentAccountInfo(uploadfileaccesstoken,uploadfileteammemberId);
System.debug('root_namespace_id:' + uploadfileroot_namespace_id);

DropBoxSyncWrapper.EndFileRequest createfilereq = new DropBoxSyncWrapper.EndFileRequest();
createfilereq.close = false;

Http httpcreatefile = new Http();
HttpRequest reqcreatefile = new HttpRequest();
String jsoncreatefile = JSON.serialize(createfilereq);
System.debug('jsoncreatefile:' + jsoncreatefile);
reqcreatefile.setHeader('Dropbox-API-Path-Root','{".tag":"root","root":"' + uploadfileroot_namespace_id +'"}');
reqcreatefile.setHeader('Content-Type', 'application/octet-stream');
reqcreatefile.setHeader('Dropbox-API-Arg', JSON.serialize(createfilereq));
reqcreatefile.setHeader('Dropbox-API-Select-User', uploadfileteammemberId);
reqcreatefile.setHeader('Authorization', 'Bearer '+uploadfileaccesstoken);
//reqcreatefile.setBodyAsBlob(data);
reqcreatefile.setMethod('POST');
//reqcreatefile.setEndpoint('callout:DropBox_API_FileCreate/2/files/upload');
reqcreatefile.setEndpoint('callout:DropBox_API_FileCreate/2/files/upload_session/start');
reqcreatefile.setTimeout(120000);
HttpResponse responsecreatefile = httpcreatefile.send(reqcreatefile);
system.debug('responsecreatefile: '+responsecreatefile.getBody());
system.debug('responsecreatefile: '+responsecreatefile.getStatusCode());
DropBoxSyncWrapper.CheckFileResponse respcreatefile = (DropBoxSyncWrapper.CheckFileResponse) JSON.deserialize(
responsecreatefile.getBody(), DropBoxSyncWrapper.CheckFileResponse.class);
System.debug('respcreatefile:' + respcreatefile);

System.debug('respcreatefile.session_id:' + respcreatefile.session_id);
if(responsecreatefile.getStatusCode()!=200){
return 'Start Fail';
}
uploadsessionid = respcreatefile.session_id;
}
else{
uploadfileaccesstoken = dpaccessToken;
uploadfileteammemberId = dpteamMemberId;
uploadfileroot_namespace_id = dpfileRootNamespaceId;
uploadsessionid = dpuploadsession;
}
system.debug('uploadfileaccesstoken: '+uploadfileaccesstoken);
system.debug('uploadfileteammemberId: '+uploadfileteammemberId);
system.debug('uploadfileaccesstoken: '+uploadfileroot_namespace_id);
system.debug('uploadsessionid: '+uploadsessionid);
if(uploadsessionid!=''){
Http httpAppendFile = new Http();
HttpRequest reqAppendFile = new HttpRequest();
reqAppendFile.setEndpoint('callout:DropBox_API_FileCreate/2/files/upload_session/append_v2');
String jsstring1 ='{"cursor":{"session_id":"' + uploadsessionid +'","offset":' + chunksize +'},"close":false}';
System.debug('jsstring1:' + jsstring1);
reqAppendFile.setHeader('Content-Type', 'application/octet-stream');
reqAppendFile.setHeader('Dropbox-API-Path-Root','{".tag":"root","root":"' + uploadfileroot_namespace_id +'"}');
reqAppendFile.setHeader('Dropbox-API-Arg', jsstring1);
reqAppendFile.setHeader('Dropbox-API-Select-User', uploadfileteammemberId);
reqAppendFile.setHeader('Authorization', 'Bearer '+uploadfileaccesstoken);
reqAppendFile.setMethod('POST');
reqAppendFile.setBodyAsBlob(data);
HttpResponse responseAppendFile = httpAppendFile.send(reqAppendFile);
System.debug('responsecreatefile-1:' + responseAppendFile.getStatusCode());
System.debug('responsecreatefile-1:' + responseAppendFile.getBody());
if(responseAppendFile.getStatusCode()!=200){
return 'Append Fail';
}
size = data.size()+chunksize;
system.debug('size: '+size);
}
if(finalChunk){
system.debug('in final chunk');

Http httpUploadFinsh = new Http();
HttpRequest reqUploadFinish = new HttpRequest();
reqUploadFinish.setEndpoint('callout:DropBox_API_FileCreate/2/files/upload_session/finish');
reqUploadFinish.setMethod('POST');
String jsstring2 ='{"cursor":{"session_id":"' +uploadsessionid +'","offset":' + size +'},"commit":{"path":"' +relatedDocument.filepath +'","mode":"add","autorename":true,"mute":false,"strict_conflict":false}}';
System.debug('jsstring2:' + jsstring2);
reqUploadFinish.setHeader('Content-Type', 'application/octet-stream');
reqUploadFinish.setHeader('Dropbox-API-Path-Root','{".tag":"root","root":"' + uploadfileroot_namespace_id +'"}');
reqUploadFinish.setHeader('Dropbox-API-Arg', jsstring2);
reqUploadFinish.setHeader('Dropbox-API-Select-User', uploadfileteammemberId);
reqUploadFinish.setHeader('Authorization', 'Bearer '+uploadfileaccesstoken);
//reqUploadFinish.setBodyAsBlob(data);
HttpResponse responseUploadFinish = httpUploadFinsh.send(reqUploadFinish);
DropBoxSyncWrapper.createFileResponse createfileresp = (DropBoxSyncWrapper.createFileResponse) JSON.deserialize(
responseUploadFinish.getBody(), DropBoxSyncWrapper.createFileResponse.class);
System.debug('responseUploadFinish-2:' + responseUploadFinish.getStatusCode());
System.debug('responseUploadFinish-2:' + responseUploadFinish.getBody());
if(responseUploadFinish.getStatusCode()!=200){
return 'Close Fail';
}
system.debug('createfileresp: '+createfileresp.name);
}
return size+','+uploadfileaccesstoken+','+uploadfileteammemberId+','+uploadfileroot_namespace_id+','+uploadsessionid;
}catch(Exception ex){
Utility.log(true,constant.SystemLogTypes.Callout,'DropBoxSyncHandler','createFile',ex.getMessage(),ex.getStackTraceString(),'','','');
return 'Fail';
}
}

 

 

Javascript/LWC code:-

 

 uploadChunk(fileName, fileContents, fromIndex, toIndex,accesstoken,teamMemberId,fileRootNamespaceId,uploadsession){
        console.log('In uploadchunk');
        var chunk = fileContents.substring(fromIndex, toIndex);   
        let isFinalChunk = fileContents.length == toIndex ? true: false;      
        this.filesUploadedtoSalesforce.push({Title: fileName, filepath: this.fileorfolderpath+'/'+fileName,VersionData: chunk});       
        createFile({
            files:this.filesUploadedtoSalesforce,
            finalChunk: isFinalChunk, chunksize: this.apexchunkSize, dpaccessToken: accesstoken, dpteamMemberId: teamMemberId,
            dpfileRootNamespaceId: fileRootNamespaceId, dpuploadsession: uploadsession

        }).then(result => {      
            console.log('result: '+result);  
           
                var resarry = result.split(',');
                console.log(resarry);
                this.apexchunkSize = parseInt(resarry[0]);
                //console.log('this.apexchunkSize: '+this.apexchunkSize);
                fromIndex = toIndex;
                toIndex = Math.min(fileContents.length, fromIndex + CHUNK_SIZE);
                //this.uploadedsize = toIndex;
                //let isFinalChunk = fileContents.length == toIndex ? true: false;
                if (fromIndex < toIndex) {
                    console.log('In uploadchunk loop');
                    this.uploadChunk(fileName, fileContents, fromIndex, toIndex,resarry[1],resarry[2],resarry[3],resarry[4]);  
                }
            
        }).catch(error => {  
        })
         
  • Greg-DB's avatar
    Greg-DB
    Icon for Dropbox Staff rankDropbox Staff

    I see you're attempting to use /2/files/upload_session/start, /2/files/upload_session/append_v2, and /2/files/upload_session/finish to upload files. These are "content-upload" style endpoints, meaning they require the file data in the request body, with the "application/octet-stream" type. And being upload session endpoints, they allow you to upload large files by doing so in pieces. That is, you can upload the first portion in the call to /2/files/upload_session/start, then further portions in call(s) to /2/files/upload_session/append_v2, and then a final portion in the call to /2/files/upload_session/finish.

     

    Also, you didn't mention how big the files you're trying to upload are beyond being larger than 5 MB, but if they are smaller than 150 MB, for the sake of simplicity you may wish to just use /2/files/upload. That allows you to upload files smaller than 150 MB in one request.

     

    In any case, I'm not aware of any current issues on the Dropbox API that would result in file uploads from correctly formatted upload sessions requests resulting in corrupted files, and I don't see any other reports like this, so it sounds like that may be some issue(s) in this code/logic that you'll need to correct. We don't offer code debugging services though, so it may be helpful for you to step through your code with a debugger to try to find the issue(s).

     

    For example, I see you're setting setBodyAsBlob. That method isn't made by Dropbox so I can't offer support for that in particular, so you may want to refer to its documentation to confirm if that's the right method for this operation. Likewise, check that the data you're supplying is the correct data that you intend to upload, and that your logic for supplying the pieces of the files is right and sends the correct pieces in the correct order.

     

    And for reference, while it's in a different language, it uses the same upload session endpoints so you may want to check out this example to see how the logic for using upload sessions works.

    • Impulsum Support's avatar
      Impulsum Support
      New member | Level 2

      Here I am uploading Base64 encoded file to dropbox, But the file is getting corrupted. Can you please help me out here.

      • Greg-DB's avatar
        Greg-DB
        Icon for Dropbox Staff rankDropbox Staff

        Impulsum Support The Dropbox API will accept whatever file data your app provides, exactly as it provides it; it will not perform any additional encoding or decoding. If you supply base64-encoded data, the uploaded data will still have that same base64 encoding. If you wish to upload a non-base64-encoded file, but your data is base64-encoded, you'll need to undo the base64 encoding first.

         

        Otherwise, please refer to my earlier message in this thread for more information on debugging/writing code for this.

About Dropbox API Support & Feedback

Find help with the Dropbox API from other developers.

5,875 PostsLatest Activity: 53 minutes ago
323 Following

If you need more help you can view your support options (expected response time for an email or ticket is 24 hours), or contact us on X or Facebook.

For more info on available support options for your Dropbox plan, see this article.

If you found the answer to your question in this Community thread, please 'like' the post to say thanks and to let us know it was useful!