node.jsexpressazure-blob-storage

POST Method: Getting blank PDF using Download to Buffer from Blob Storage


As my previous question, but this time with POST Method.

got million errors from this first is Content-Length mismatch: too many bytes written (216523 of 215706) but when I managed to fix it, I can now successfully download the PDF but it has blank contents

I will post the other parts of code but with censor in order to protect the client for privacy issues.

Also, I cannot use pipe cause it is not working for us, taking too long to send request in Postman API.

Please help, thank you.

Code:

app.post(
    "/api/**client-endpoint**/download/attachments",
    async (req, res, next) => {
        try {
            let claims = await authentication.authJwtToken(req, req.context);
            req.context.log("Validated claims: ", JSON.stringify(claims));
            let allowedPermissions = [permissionConstants.PERMISSION_ADMIN_CUSTOMER_VIEW];
            let auth = await authorization.authorize(req.context, claims, permissionConstants.AUTH_MODE_CLIENT, allowedPermissions, req.body.clientId, undefined, undefined, constants.AUTH_TOKEN_TYPE_ADMIN);

            let client = await coreClientDao.mssqlGetClientByIdAuthObject(constants.**CLIENTNAME**_CLIENT_ID, req.context);

            const { clientId, customerId, fileUrl } = req.body;
            
            if (!fileUrl) {
                return res.status(400).send({ message: 'fileUrl is required.' });
            }

            req.context.log("Processing file for clientId: ", clientId);

            let blobUrl = fileUrl;

            if (!blobUrl) {
                req.context.log(`Skipping attachment, URL is not yet ready.`, new Date().toString());
                return res.status(400).send({ message: 'Attachment is not ready.' });
            } else {
                let sharedKeyCredential = new StorageSharedKeyCredential(utility.dec(client.storageName), utility.dec(client.storageKey));
                let blobServiceClient = new BlobServiceClient(
                    `https://${utility.dec(client.storageName)}.blob.core.windows.net`,
                    sharedKeyCredential
                );

                let urlParts = new URL(blobUrl);
                let pathParts = urlParts.pathname.split('/');
                let blobName = pathParts.slice(2).join('/'); 

                let sourceBlob = blobServiceClient.getContainerClient(constants.BLOB_CONTAINER_ATTACHMENT).getBlobClient(blobName);

                req.context.log('Downloading blob:', blobName);

                const pdfFile = await sourceBlob.downloadToBuffer({
                    onProgress: (progress) => {
                      req.context.log(`Downloaded ${progress.loadedBytes} bytes`);
                    }
                  });
                  
                res.setHeader('Content-Type', 'application/pdf');
                res.setHeader('Content-Disposition', `attachment; filename="${blobName}"`);
                res.set('Transfer-Encoding', 'identity');
                res.send(pdfFile);
            }
        } catch (error) {
            utility.catchErrorRespnse(res, req.context, error);
        }
    }
);

Solution

  • I tried your code and received an empty PDF file while downloading it from Azure Storage using the downloadToBuffer function.

    Change your code as follows:

         const blobClient = containerClient.getBlobClient(blobName);
    
            const blobProperties = await blobClient.getProperties();
            const bufferSize = blobProperties.contentLength;
    
            const buffer = Buffer.alloc(bufferSize);
            console.log(`Downloading blob "${blobName}" to buffer...`);
            await blobClient.downloadToBuffer(buffer, 0, bufferSize);
            await fs.writeFile(downloadFilePath, buffer);
            console.log(`PDF downloaded and saved to: ${downloadFilePath}`);
            return downloadFilePath; 
            
    

    Output: enter image description here

    I followed this documentation for the downloadToBuffer function and referenced this git for the BlobClient class. You can also find more information in this MSDOC.