Add minimal 4xx responses for invalid image derivative requests

Created on 26 May 2023, over 1 year ago
Updated 10 October 2023, about 1 year ago

Problem/Motivation

Drupal's Fast 404 feature, when enabled, is not expected to work with image style derivative URLs, due to this configuration in settings.php, which is what allows Drupal to handle yet-to-be generated image styles.

$config['system.performance']['fast_404']['exclude_paths'] = '/\/(?:styles)|(?:system\/files)\//';  

Without this line, my understanding was that image style generation would break, but it seems its going to be removed anyway in πŸ“Œ Remove 'fast_404.excluded_paths' from system.performance.yml Needs work .

However β€” regardless of whether fast 404s are enabled or disabled with or without this setting β€” currently many invalid URLs handled by Drupal's Image API throw a general 404 not found response, which ends up generating the system 404 handler. On the other hand, some URLs load a minimalist 400 response with a brief message about what went wrong, eg Error generating image, missing source file.

Example of invalid URLs that load the full Drupal 404 page include:

missing image: /sites/default/files/styles/large/public/2023-05/faulty.png?itok=any
invalid itok: /sites/default/files/styles/large/public/2023-05/valid.png?itok=faulty
invalid stylename: /sites/default/files/styles/faulty/public/2023-05/valid.png?itok=any
invalid stylename: /system/files/styles/faulty/public/2023-05/valid.png?itok=any
invalid stream wrapper: /sites/default/files/styles/large/faulty/2023-05/valid.png?itok=any

If a legacy image style gets deleted from the system, it would be nice to know about it with a message like Error generating image, invalid image style "my_legacy_image_style".. Or similarly, if an image cache was flushed, and the image needs to be regenerated, but the itok is not present or is faulty, to see a relevant message like Error generating image, missing image token. or Error generating image, invalid image token "xyz123"..

In general, it would be a great improvement to avoid rendering the full 404 page from Drupal, which is unhelpful in this context when hitting error conditions in the image api, and instead have the image module send a minimalist 400 "Bad Request" response with a brief helpful message instead. Additionally, 400 requests send a better signal to upstream cache systems like Varnish or CDNs that the bad request can be cached potentially indefinitely, unlike 404s which generally are not cacheable for long periods of time, because the URL might work in the future.

Steps to reproduce

  1. Install Drupal 10 on simplytest.me
  2. Create an article node, and upload a PNG image.
  3. Load the full-node display and note the URL of the image rendered as the "wide" image style.
  4. Open the image in a new tab and change "wide" to "large" and change the itok to value "faulty".
    /sites/default/files/styles/large/public/2023-09/filename.png?itok=faulty
    
  5. Get the Olivero 404 page.

Proposed resolution

The only time a 404 response code should be sent for an image derivative request is when the source image is not found on the server or when the image style doesn't exist. And in these cases, we can and should return a minimalist 404 with a brief message. In other cases when the request is actually malformed (eg unsupported stream wrapper scheme, or invalid itok) we should return a 400 "Bad Request" response.
Therefore:

  1. Replace instances of the general NotFoundHttpException() in ImageStyleDownloadController with a minimalist 400 "Bad Request" or 404 "Not Found" response (as the case dictates) and provide a relevant brief message explaining why the request is invalid. Eg: missing image token or invalid image token "@itok" or invalid stream wrapper scheme "@scheme"..
  2. This πŸ‘† will handle most cases, except for the case of an invalid image style name parameter in the URL. To handle that scenario, we can add an Event Subscriber to listen for ParamNotConvertedException, and return a minimalist 404 response with appropriate brief message: invalid image style "@image_style".

Remaining tasks

User interface changes

None.

API changes

Faulty requests to generate image derivatives will now return a minimalist 404 ("Not Found") or 400 ("Bad Request") response with a brief error message. Previously, a full Drupal bootstrap with a 404 page would occur for broken image requests. The following scenarios are covered accordingly:

  • If the request is for a source image that is not found on the server, return a minimal 404 ("Not Found") error.
  • If the request contains an invalid/undefined image_style name, return a minimal 404 ("Not Found") error.
  • If the request contains invalid/missing arguments or parameters, return a minimal 400 ("Bad Request / Client Error") error. The following URL arguments and parameters are covered:
    • missing or invalid image token ("?itok=xxxxxx"),
    • invalid or unknown stream wrapper scheme (eg "public", "private", or any others schemes that not allow-listed by $settings['file_sa_core_2023_005_schemes'])

To help return these minimal 4xx responses, a new service has been introduced to handle Exceptions thrown by the Image API.

Data model changes

None.

Release notes snippet

Faulty requests to generate image derivatives now return a minimalist 404 ("Not Found") or 400 ("Bad Request") response with a brief error message. Previously, a full Drupal bootstrap with a 404 page would occur for broken image derivative requests. This change should not have a negative effect on end users of Drupal and constitutes a minor performance improvement for better cacheability and troubleshooting of broken URLs or incorrect Image API usage.

✨ Feature request
Status

Needs work

Version

11.0 πŸ”₯

Component
Image systemΒ  β†’

Last updated about 4 hours ago

Created by

πŸ‡ͺπŸ‡¨Ecuador jwilson3

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024