I just realized the media hash generation has been changed with Kirby 3.4.0 after a client nervously told me they were sharing the file URLs from the file view and they’re not working anymore. Of course it’s a bad idea to share the hashed file URLs but I can’t really blame him clicking on the URL link in the file view.
Changing this back to crc32($model->filename()) . '-' . $model->modifiedFile() seems to revert the change. Is there any way I can extend this method? I don’t want to edit stuff in the /kirby folder for obvious reasons.
While the file URLs are correctly overwritten they result in a “Not found” message. The file::url component seems to only overwrite the url() function, not making sure the file can actually be accessed. The documentation says (…) can be used to let thumbnails be generated on different services like Cloudinary or Imgix, but it can also be used to host files in a different location and load them from there. so I suppose it’s used to modify the url() to match such a service.
I’d appreciate any help how to overwrite the contentToken() function in src/Cms/App.php, because I think that’s what I have to do. Essentially changing return hash_hmac('sha1', $value, $salt); to return crc32($model->filename());.
Hm. If I understand correct, you have files with hashed filenames by method 1 and now the method changed and your files need to be accessed with the hash of method 2 in the filename (which is known and still the same)? In this case you could implement a rewrite rule with a map function which implements the translation from one hash to the other.
@thguenther This is a hack more than an elegant solution and I haven’t tested it, but as this thought just crossed my mind: could it be a “second-last” option to deal with this in the error handling?
I assume calls to the expired image URLs cause a 404 error. Could you intercept 404s in a way that you check whether the failed URL is a media file, only then calculate the new URL that matches the expired one and return a 301 redirecting to that URL instead?
Ah, I had a hunch (both that you already investigated this path, and that it’s not as straightforward as it appears).
Interestingly, a NotFoundException (the “Not found” text) only occurs when dealing with an original file’s media URL. Running the same experiment on a thumb version of an image (file name ends with -300x-q70.jpg), the Kirby error page is displayed if the hash is wrong. (Not that this knowledge would help you, just to document in case this is being looked into.)
Without any knowledge about the design rationale or technical reasons behind this, I would lean towards framing this as a bug, or at least a inconsistency worth addressing in a future update? After all, a site owner may want to be able to display a custom error page when somebody uses an expired media URL.
For your problem at hand, I don’t have any further ideas at this point
Thanks so much for testing this yourself and spending time on my issue, Sebastian!
I have yet to find the code responsible for triggering the exception but after reading you could reproduce the NotFoundException page instead of a normal error page I’m almost 100% sure this is not intended.
This behavior of a plain “Not Found” message is indeed not great, especially since it’s a one line fix to make Kirby render the error page instead.
I’ve converted this discussion into one issue and one PR:
The media implementation has two separate cases:
If the hash itself is invalid (which is only based on the file path and the content.salt Kirby option), this means that the whole URL is invalid and could never have been correct. For security, Kirby then displayed “Not Found” until now, but of course it doesn’t harm to display the error page. This is actually even better to avoid leaking that the file exists at all.
If the hash is correct, but the timestamp is invalid, Kirby redirects to the new updated URL. No custom error page needed.
Basically the only thing we missed in the new implementation are URLs with the old hash format.