Would it be possible to set up a redirect so an img tag like <img src="/image-redirects/500.jpg"> would show them the image from https://example.com/ad-image/ads/1234/500.jpg?
Yes, you can, but not with an external "redirect" as that will simply present the target URL to the browser on the redirect response (and be blocked - if the browser is blocking simply based on keywords in the URl).
Reverse Proxy
You will either need to configure your server as a reverse proxy (using mod_proxy and related modules with ideally ProxyPass / ProxyPassReverse in the server config), then you can do something like the following in .htaccess (before the WordPress front-controller) using mod_rewrite to route the request through mod_proxy:
RewriteRule ^image-redirects/(\d+\.jpg)$ https://example.com/ad-image/ads/1234/$1 [P]
(Assuming 500 is a dynamic filename consisting of digits only - as in your example).
PHP Script to fetch image
Or, you internally rewrite such requests to a PHP script that fetches the image from the remote server and sends this back in the response.
For example, in .htaccess, using mod_rewrite (again, before the WP front-controller):
RewriteRule ^image-redirects/(\d+\.jpg)$ image-fetch-script.php?file=$1 [L]
In image-fetch-script.php you can examine the file URL parameter and fetch the intended image from the remote server and send this back to the client in the response. You could also cache the image on your server for a period of time. However, the fact that they want you to fetch the images directly from their server may be because they are logging impressions, so local caching would affect this.
Example image-fetch-script.php could be something like:
<?php
/**
* Fetch remote image and send to client
*/
// Remote URL from which to fetch images
$remoteBaseUrl = 'https://example.com/ad-image/ads/1234/';
// Permitted file extensions / mime-types
// NB: If using CURL, can get the mime-type from the HTTP response instead
$mimeTypes = [
'gif' => 'image/gif',
'jpg' => 'image/jpeg',
'png' => 'image/png',
'webp' => 'image/webp',
];
// Get the reqd file the "file" URL parameter in the rewritten URL
$file = $_GET['file'] ?? null;
$remoteUrl = null;
// Validate filename format
// Or even check against a known list of files?
$filenameRegex = '/^[\w-]+\.('.implode('|',array_keys($mimeTypes)).')$/';
if (preg_match($filenameRegex, $file, $matches)) {
header('Content-Type: '.$mimeTypes[$matches[1]]);
$remoteUrl = $remoteBaseUrl.$file;
// OPTIONAL: Check cache here...
// readfile() and exit if current.
// Using readfile()
// - simple, but does not provide any error handling on the HTTP response
// eg. if the remote file does not exist etc.
//$bytes = readfile($remoteUrl);
//if ($bytes === false) {
// General 500 Internal Server Error
// http_response_code(500);
//} else {
// // No error - assume success!
// // But there could have been an HTTP response "error" that is lost
//}
//exit;
// Using CURL
$ch = curl_init($remoteUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($ch);
$curlError = curl_errno($ch);
if ($curlError) $curlError .= ': '.curl_error($ch);
$httpStatus = curl_getinfo($ch,CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($curlError) {
// Only set header when debugging, otherwise could expose the target URL
//header('X-CURL-ERROR: '.$curlError);
// General 500 Internal Server Error
http_response_code(500);
}
// CURL request is OK, but could still be an HTTP failure...
else {
// OK - serve image
if ($httpStatus === 200) {
// OPTIONAL: Save to cache...
echo $content;
}
// Pass through HTTP status from CURL request... 404, 403, etc...
else {
http_response_code($httpStatus);
}
}
exit;
}
// Default failure... "Bad Request"
http_response_code(400);