Signed URLs with Content Length restriction

Viewed 50

I have the following code that generates a signed upload url for a file:

const { Storage } = require('@google-cloud/storage');
const bucketName = 'foo-upload';
const storage = new Storage();
const uploadBucket = storage.bucket(bucketName);

exports.generateUploadLink = async (req, res) => {
  let contentId = req.query.contentId || req.body.contentId;

  let file = uploadBucket.file(`${contentId}.mp3`);

  try {
    let signedUrl = await file.getSignedUrl({
      action: 'write',
      expires: Date.now() + (30 * 1000),
      contentType: 'audio/mpeg'
    });
    res.status(200).json({meta: { status: 'OK'}, uploadUrl: signedUrl[0]});
  } catch(err) {
    console.log(`Error while getting signed url: ${err}`);
    res.status(500).json({meta: { status: 'FAIL', message: `Could not generate signed upload url for: ${contentId}`, error: err}});
  }
  return;
};

How can I enforce a content length restriction on the signed Url such that a file that is subsequently PUT to the Url which is above a certain number of bytes will be rejected?

1 Answers

You can specify a policy document that uploads must satisfy.

Policy Document

Set the content-length-range.

An example that will limit uploads from 0 to 1,000,000,000 bytes and only for Content-Type image/jpeg.

{
 "expiration": "2020-06-16T11:11:11Z",
 "conditions": [
  ["starts-with", "$key", "" ],
  {"acl": "bucket-owner-read" },
  {"bucket": "example-bucket"},
  {"success_action_redirect": "http://www.example.com/success_notification.html" },
  ["eq", "$Content-Type", "image/jpeg" ],
  ["content-length-range", 0, 1000000000]
  ]
}
Related