I need a way in Google Cloud to redirect the public URL of jpeg files of my bucket to a Google Function endpoint for checking headers
https://storage.googleapis.com/bucket/folder/file.jpg
This is an example of a jpeg file in my Firebase Storage. A lot of websites are using my images illegally. I need a way to add a background check and process behind each access to the images... In PHP it is easy to do because the script can deliver the image, but here ? I don't know. I need a check on the headers of the website hosting the image, if the header referer is not OK, I want to redirect to an image saying that the real image is not available, or a 403
-
Alexandre Paradis commented
You can create a hosting configuration that redirects to a function. Ex.
```
{
"target": "my-cdn",
"headers": [
{
"source": "/**",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache, no-store, must-revalidate"
},
{ "key": "X-Content-Type-Options", "value": "nosniff" }
]
},
{
"source": "**/*.@(jpg|jpeg|gif|png|webp|svg|ico)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=2592000, s-maxage=7776000"
}
]
}
],
"rewrites": [
{
"source": "**",
"function": "cdn",
"region": "northamerica-northeast1"
}
]
},
```This is the function I'm using to serve images from a Firebase Storage bucket:
```
import { error as logError } from 'firebase-functions/logger';
import { onRequest } from 'firebase-functions/v2/https';
import { Agent, get as httpsGet } from 'https';
import { initializeFirebaseAdminApp } from '../infrastructure/firebase/initializeAdminApp';
import { initializeExpressApp } from '../infrastructure/express/initializeApp';
import { Request, Response } from 'express';
import { lookup } from 'mime-types';initializeFirebaseAdminApp();
const expressApp = initializeExpressApp('cdn');// Configure persistent connection
const agent = new Agent({ keepAlive: true });// Set CDN caching duration in seconds
const cacheMaxAge = 2592000; // 30 days
const cacheSMaxAge = 7776000; // 90 daysconst allowedPrefix = '/';
const isUrlAllowed = (url: string): boolean => url.startsWith(allowedPrefix);// Get firebase URL from received request
const getFirebaseUrl = (url: string): string => {
if (!isUrlAllowed(url)) {
logError('URL is not allowed');
throw new Error('URL is not allowed');
}
// Configure source image URLs. This assumes that we store images on Firebase Storage
const projectId = process.env.GCLOUD_PROJECT;
const pathSeparator = '%2F';
const sourcePrefix = `https://firebasestorage.googleapis.com/v0/b/${projectId}-cdn/o/`;
const sourceSuffix = `?alt=media`;const urlNoPrefix = url.slice(allowedPrefix.length);
const sourceKey = urlNoPrefix.replace(/\//g, pathSeparator);
return `${sourcePrefix}${sourceKey}${sourceSuffix}`;
};expressApp.get('*', ({ url }: Request, response: Response) => {
const firebaseUrl = getFirebaseUrl(url);
httpsGet(firebaseUrl, { agent }, (res) => {
const statusCode = res.statusCode || 404;
const headerPipe = response;
if (statusCode < 400) {
headerPipe.set(
'Cache-Control',
`public, max-age=${cacheMaxAge}, s-maxage=${cacheSMaxAge}`,
);
const contentType = lookup(url);
if (contentType) {
headerPipe.set('Content-Type', contentType); // Some images were saved on Google Storage with a wrong content-type, so we try to set the good one here!
}
}
headerPipe.status(statusCode);
return res.pipe(headerPipe);
});
});export const cdn = onRequest(
{ region: ['northamerica-northeast1'] },
expressApp,
);```