I am using NodeJS to generate a signed URL to allow my users to upload files.
The code to generate the URL is pretty simple and works with URLs that have the Google Cloud domain.
However, I want the signed url to have my custom domain so the URL I am generating starts with https://example.com
.
async function generateSignedUrl(file) {
const bucketName = '<bucket-name>';
const storage = new Storage({keyFilename: '<path-to-key>'});
const options = {
version: 'v4',
action: 'write',
expires: Date.now() + 15 * 60 * 1000, // 5 minutes
contentType: 'application/octet-stream',
cname: 'https://example.com'
};
const [url] = await storage
.bucket(bucketName)
.file(file)
.getSignedUrl(options)
.catch(error => console.log(error))
return url
}
The infrastructure is such that the bucket is configured as a backend to a load balancer so my DNS server has the load balancer IP and it routes the requests to the load balancer. The load balancer then routes the requests to the bucket.
I tried a simple DNS redirection to the Google Cloud URL and though the redirection works, the upload does not as the browser first sends an OPTIONS request and results in a OPTIONS request cannot be redirected
error. The OPTIONS request is also triggered when the request is sent from one sub-domain to another. For example, front-end deployed at https://staging.app.com
and the signed URL starts with https://upload.staging.app.com
so if I understand it correctly, CORS is not an issue here and DNS redirection is simply not an option?
The problem is the upload works for small files(< 5MB) but for large files, the upload stops suddenly and then fails after some time as the progress update in Axios shows. The load balancer logs show the client_timed_out
error, with 408 or 504. I have also tried using CURL but the behaviour is exactly the same.
If it matters, here is the Axios code that performs the upload.
axios.put(
url,
file,
{
headers: {
'content-type': 'application/octet-stream',
},
onUploadProgress(progressEvent) {
console.log(`Upload Progress: ${JSON.stringify(progressEvent)}`)
},
}
)
I have searched for hours and hours over the last month but cannot find a resource that shows how to implement it. It seems too good to be true but I feel nobody has ever tried it.
Just a note that the exact code works as expected without a CNAME
based url.