Confluence: Attachment download stays at 99% when it was uploaded through the REST API

A customer noticed that, when downloading their XLSX files from Confluence, those uploaded through our plugin can’t be fully downloaded. The Chrome download remains stuck at 99.9%.

It happens for all files, but I’ve created an example.xlsx and compared the result in Confluence’s home attachment directory after upload:

  • If I upload through Confluence’s editor (upload.action), it will be fine, and my example file is 5082 bytes,
  • If I upload through the REST API, then any download of that file will hang at 99.9%, and the file is 5037 bytes, and not similar to the original file.

Does Confluence’s REST API mangle the file before saving it? Is there something to do with encodings/UTF-8? It’s not the BOM, since it’s 45 bytes of difference. Is there any other parameter to specify through the REST upload so that it doesn’t mangle the data/encoding/contents?


For information:

  • URL for upload.action: http://example.com/plugins/drag-and-drop/upload.action?pageId=1540099&filename=MIME%20Test.xlsx&size=5082&minorEdit=true&spaceKey=EXMPL&mimeType=application%2Fvnd.openxmlformats-officedocument.spreadsheetml.sheet&contentType=page&isVFMSupported=true&name=MIME%20Test.xlsx, interestingly the MIME type and size are specified in the URL, on top of the body,
  • URL for Confluence’s REST API: POST http://example.com/rest/api/content/1234/child/attachment (documented here and tutorial here)

My code:


        const $uploadField = $('#excel-integration-upload-form').find('input[type=file]');
        if ($uploadField.size() === 0) throw new Error("The upload field can't be found on the page");
        const field = $uploadField[0];
        const fileToUpload = field.files && field.files[0];

        // Post the multipart data to the create attachment REST resource
        // there must be  at least one file
        if (fileToUpload) {

            let path = AJS.contextPath() + "/rest/api/content/" + pageId + "/child/attachment";
            let filename = fileToUpload.name;
            let actionData = new FormData();
            actionData.append('file', fileToUpload, filename);
            actionData.append('minorEdit', 'true');
            actionData.append('comment', 'Uploaded by Requirement Yogi');
            $.ajax({
                type: 'POST',
                url: path,
                data: actionData,
                processData: false,
                headers: {
                    "X-Atlassian-Token": "no-check"
                },
                contentType: false,
                cache: false,
                success: function (data, status, response) {
                    // ...
                },

Does Confluence’s REST API mangle the file before saving it? Is there something to do with encodings/UTF-8? It’s not the BOM, since it’s 45 bytes of difference.

Is there any other parameter to specify through the REST upload so that it doesn’t mangle the data/encoding/contents?

Confluence didn’t modify the files when uploaded through the REST API. It was us / our usage of Apache POI that modified the files in the home directory’s attachment folder.

The issue was in the process:

  • Upload the Excel file,
  • Then the file is read from the attachment folder by Requirement Yogi, into Apache POI,
  • Then the user would download the file,

In step 2, Apache POI would modify the file while reading it, I suppose to optimize it. Since the file was modified, Confluence was sending to the client the original file size, then the bytes, and the client would wait until the original file size was received, and it would wait forever.

Solution: Pass the ‘readonly’ flag to Apache POI when reading files.