Problem/Motivation

Setting 'Enforce clean and canonical URLs.' breaks CSS aggregation on multilingual Drupal 10.1.x with browser caching enabled and where your language has a prefix (f.e. 'en' for English) configured.

Change record https://www.drupal.org/node/3301716 introduced a performance improvement that boils down to: Instead of a page request creating and writing several files before it can be sent to the browser, now the main page request just generates the URLs, and the actual CSS or JavaScript aggregate is individually created by PHP (and still written to disk assuming it's valid).

Behaviour before the change:

A page is requested, the main request generates the aggregated CSS files and writes them to the disk. The HTML of the page is returned to the browser. The browser requests the aggregated CSS files and they are present of the disk so they are returned.

Behaviour after the change:

A page is requested, it no longer generates the aggregated CSS files. The HTML of the page is returned to the browser. The browser requests the aggregated CSS files. They are not present on the disk so they are generated. The RouteNormalizerRequestSubscriber from this module is now triggered when aggregated CSS files are requested from the browser and a redirect response is returned from it redirecting /sites/default/files/css/css_MXjpf7HZqh... to /en/sites/default/files/css/css_MXjpf7HZqh... . The browser then requests /en/sites/default/files/css/css_MXjpf7HZqh... which loads fine but later requests for this URL are blocked by the browser because of MIME type checks because the MIME type is no longer 'text/css' but 'text/plain'.

Steps to reproduce

  1. Install Drupal 10.1.0 or later
  2. Install the redirect module and enable it. The setting 'Enforce clean and canonical URLs.' will be enabled by default.
  3. At Config > Performance , 'Aggregate CSS files' is enabled by default. Set 'Browser and proxy cache maximum age' to 5 minutes.
  4. Enable the 'Language' core module.
  5. At Configuration > Region and language > Languages > Detection and selection , 'URL' is enabled by default. Configure 'URL' to use 'en' as language prefix for English.
  6. Clear cache and delete the generated aggregated CSS files from disk
  7. Visit a page, it will load correctly
  8. Visit the page again and the aggregated CSS will no longer be loaded. In browser console you will find errors like Refused to apply style from 'https://my-drupal10-site.ddev.site/en/sites/default/files/css/css_MXjpf7......' because its MIME type ('text/plain') is not a supported stylesheet MIME type, and strict MIME checking is enabled.

Proposed resolution

Add an exception in RouteNormalizerRequestSubscriber or in RedirectChecker::canRedirect for aggregated CSS paths.

Remaining tasks

Discuss how we want to fix this and fix it.

User interface changes

?

API changes

N/A

Data model changes

N/A

Issue fork redirect-3373123

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Stefdewa created an issue. See original summary.

bladedu’s picture

I confirm the issue on Drupal 10.1 and redirect module.
My scenario is simpler: I have css/js aggregation active and a plain drupal installation.

all files under /sites/default/files/css or js gets redirected to itself appending the query parameters to the existing path until NGINX replies with 414 Request-URI Too Large

dioni’s picture

I can confirm it too

dioni’s picture

StatusFileSize
new907 bytes

I have create a patch because it was blocking my current project.

dioni’s picture

StatusFileSize
new924 bytes

Please, use the patch -2, I forgot to include the preg_quote function.

dioni’s picture

Status: Active » Needs review

Status: Needs review » Needs work

The last submitted patch, 5: 3373123_redirect-2.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dioni’s picture

StatusFileSize
new928 bytes
dioni’s picture

Status: Needs work » Needs review
dioni’s picture

Status: Needs review » Needs work

The last submitted patch, 8: 3373123_redirect-3.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dioni’s picture

Status: Needs work » Needs review
dioni’s picture

StatusFileSize
new940 bytes

Status: Needs review » Needs work

The last submitted patch, 13: 3373123_redirect-4.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dioni’s picture

Status: Needs work » Needs review
dioni’s picture

bladedu’s picture

StatusFileSize
new3.63 KB
new3.96 KB

I refined a bit your patch (using injected service, but also using a different method for fetching the base path getDirectoryPath()method is defined as abstract method from LocalStream from which all other streams are extended.
basePath, instead, is defined by concrete classes and their implementation of getDirectoryPath calls basePath.

Eventually it's the same, but bit more robust (and usable with s3fs module)

Status: Needs review » Needs work

The last submitted patch, 17: 3373123_redirect-5.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

bladedu’s picture

StatusFileSize
new7.28 KB
new3.65 KB

Fixed tests and add one more test to verify that redirect checker returns false when asset path is provided.

bladedu’s picture

StatusFileSize
new7.07 KB
new1.52 KB
bladedu’s picture

Status: Needs work » Needs review

This last patch should work. Going to switch it back to need review.

Thanks!

dioni’s picture

Cool, thanks!!!

stefdewa’s picture

Priority: Major » Normal

The issue is fixed in Drupal 10.1.2 . Issue #3371358: When AssetControllerBase delivers existing file should add content-type makes sure the correct Content-Type is specified (Fix in code: https://git.drupalcode.org/project/drupal/-/commit/6c8799d135b23bfadbf43... ). Lowering priority to 'Normal'.

Nonetheless, we can go forward with the change here because that reduces website calls.

stefdewa’s picture

pub497’s picture

hmm this seems to still be an issue for me on drupal 10.1.3...although it might be for a different reason as we are not using multilingual support, this is what a resulting css file path looks like:

https://website.com/sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-CJ_1uH6Y.css?q=sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-CJ_1uH6Y.css&q=sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-CJ_1uH6Y.css&q=sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-CJ_1uH6Y.css&q=sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-
... this part keeps repeating...
-CJ_1uH6Y.css&q=sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-CJ_1uH6Y.css&q=sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-CJ_1uH6Y.css&q=sites/default/files/css/css_FtDEylGgrC-BYN_tnMeOgX1HzP_qiLJnAp-CJ_1uH6Y.css&delta=0&language=en&theme=gin&include=eJx9kw2WozAIxy9k6xn2JD5CqGaMiQuks87pl_jVsW9236sVfuA_CIiZqf34XYiXxgGOnWb7ze03u_uQf4YC5tRg1fBcZoj3mXPPJGLw8aATb96WGZISJ4MleWKp7C1QT3A50UVZc8GBnpRUbkqiFrT8P1ogvk45yC2GNEojiyhNVrGYVgTOLQL7A4Ofwl59yjxBDF9HWh-zMxXRxYT6pg-pVXCyGj5AzBuzq1vFqxOpB1w6FDlil_oBNTxpLawRkBE059QhtEPoBxyAVb7xF2x_gufpIQVdnb3D1UzZUzczPQN97rGjL93WlwodE3jkMrnVFVK1V5VOGZaO_C5bz7CWiAS0gefogE8OiDaNy0v6IHME3OoQDTguL5kimqe1P_sA9oc276LzsHlcAOYYYT7HuNMEz9s6FxkyKxY9JXe_2Wtu9_t9olTeYeNtrWyJ6v_tYJSegXOyfLUm-4A2Aj7kfww2RejMqPa9fh3yttsy0DyQLaHtc62g8LllJ7nuPThn0QkS9MT_3_qj-M_Mo6OEQ3ta9yP23hEShJl-rd-CC303h5naw_gLPSSaOg

Works fine on drupal 9, also it seems to work fine with the addition of advagg module

andreasderijcke’s picture

I'm having this issue also on 10.1.3 when running on our hosting, but not when running in DDEV.

The patch does fix the issue on the hosting.
So far not been able to identify the reason, gut feeling points toward nginx config.

andreasderijcke’s picture

@pub497 Turns out or issue was indeed due to outdated nginx config, as explained in #3368769-2: 10.1.x breaks Nginx + PHP-FPM with too many redirects even when nginx config is changed

pub497’s picture

hey @andreasderijcke thanks for that! that was exactly the issue I was having

Juanjol made their first commit to this issue’s fork.

juanjol’s picture

Priority: Normal » Major

I confirm that this Issue is currently still occurring in core version 10.1.5 with Redirect version 8.x-1.9.

I have created an MR to make it easier for maintainers to merge this issue. I have added some of the previous patches to the issue so that the contributors don't lose the credits, I hope I did it right. In this MR I have also corrected a problem from patch #20 with CSS/JS added on sites whose basepath is not /.

What I have done is that when checking the requests not only is done on $assetsStreamWrapper->getDirectoryPath() but also takes into account the basePath of the $request.

I had thought that perhaps it would be more efficient to use a str_starts_with instead of preg_match, but I have seen that it would not be controlled if these requests are expressly CSS/JS and I believe that on this occasion it is interesting to do it this way, isn't it?

Finally, it seems to me that this issue is important because CSS and JS aggregation is failing in lot of sites, so I have raised the priority to Major. I hope that this last one does not generate discomfort.

juanjol’s picture

-

juanjol’s picture

I have been rethinking and update a bit the MR so that instead of checking the uri of the request, which contains the base path included and extra parameters, what we check is the path info of the request. This is more similar to what we get from the getDirectoryPath of the asset stream.

juanjol’s picture

StatusFileSize
new17.52 KB

Added patch with changes from MR to facilitate the installation of the patch with composer until the issue is fixed.

mullzk’s picture

Hi
I tested #34 on my installation and it worked.

Drupal 10.1.5, Redirect 8.x-1.9, multilingual
=> Having redirect AND css/js-aggregation enabled leads to css/js-files no longer being loaded.
=> Using the issue-fork from juanjol fixes this (as does disabling css/js-aggregetion or disabling redirect).

Thanks a lot for your work. Hope this gets merged soon.
Being still a Newbie in regard to Drupal-Contrib - if anyone tells me how I can be of assistance for further review, I'll gladly help...

juanjol’s picture

Hi mullzk! Welcome :)

If you have tested the latest patch or the MR changes and they are working for you, please consider changing the issue state from Needs review to 'Reviewed and tested by the community'.

Thanks!

bladedu’s picture

mullzk’s picture

Status: Needs review » Reviewed & tested by the community

Tested on 10.1.5 as described in #35, MR resolves the issue
Tested on Drupal 9.5.11 as well, Redirect works as expected, CSS-& JS-Assets are generated as usual.

jhuhta’s picture

StatusFileSize
new642 bytes

I'm not 100% sure if I had the same issue. However, the new 10.1 aggregation and Redirect together causes an extra language prefix redirect on a multilingual site. But there's a simpler way to prevent that from happening: just disable the normalization on a given route. Here's a patch that works for me on that.

catch’s picture

Patch in #39 looks good to me.

dpacassi’s picture

Using #39 on two big Drupal sites, has been working so far :)

mschudders’s picture

I can also confirm #39 works on a big Drupal multilingual Drupal 10.1.5 with Apache (no NGINX)

juanjol’s picture

After some thought and testing, as far as I can see the solution in #39 is much cleaner than the one we had previously so far, so with your permission I have removed the MR and leave the latest patch as the proposed solution.

flocondetoile’s picture

Aggregated JS/CSS was completly broken after upgrading from 9.5.11 to 10.1.6. Using Apache and PHP-FPM.
Patch #39 solves the issue.
RTBC +1

bladedu’s picture

Yes I confirm patch #39 solves the issue.

volkerk’s picture

Patch #39 works fine on https://www.drupal.org/project/la_eu
So another +1

volkerk’s picture

raffaelj’s picture

I can also confirm that patch #39 solves the issue.

In my case I experienced redirects for aggregated CSS an JS files from `/sites/default/files/css/css_{hash}` to `/de/sites/default/files/css/css_{hash}` with a 301 status code after rebuilding the cache on a multilingual site - only on front page, that is redirected from `/` to `/{lang}`.

Because I don't want to wait (and 301s are browser cached), I added the code from #39 to a custom module and use it in production now. Thanks @jhuhta.

thomaswalther’s picture

#39 solves the issue with endless redirection.

I am missing this patch (with checking the new two collections "system.js_asset" and "system.css_asset") in the newest release 1.9.

andrerb’s picture

I have tried the patch from #39, but it does not solve our problem with the css files not being found.
* Server: Apache
* Drupal 10.2.2
* redirect 1.9 (patched)
* multilingual
* multidomain

The error occurs during an AJAX request if both options ("Enforce clean and canonical URLs" and "Aggregate CSS files") are enabled.
The Error-Message: "An error occurred during the execution of the Ajax response: The following files could not be loaded: /sites/default/files/css/css_CmPeBLE1CkXCsJ5fW5NMix3CFDsvxnLYkuIr83jPmVU.css?delta=1&language=en-us"

If one or the other option is deactivated, the AJAX request works without problems.

We are still trying to find the reason for this

bbu23’s picture

While this behaviour can be confirmed (a multilingual D10 with Enforce clean URLs enabled), in my case I had multiple servers with the same project code & db, but some servers were not affected, they were working fine.

While temporarily disabling the "Enforce clean URLs" confirmed the potential fix of the patch (I was not applying it yet), the question why other server were not affected by this still remained. After deeper investigation, there were permissions + ownership issues with the files folder (recursively). That fixed the problem and no patch was required anymore. Re-enabled the "Enforce clean URLs" and all was fine.

Also temporary dir was fixed in this (there was another issue there)

EDIT: False alarm, we did have to go for the patch, but then the mystery of why the others servers work without will be left unsolved. Confirming that the patch works.

berdir’s picture

Status: Reviewed & tested by the community » Needs work

#39 is the correct fix, please provide this as a merge request.

Berdir changed the visibility of the branch 3373123-setting-enforce-clean to active.

  • Berdir committed c1bcaaf2 on 8.x-1.x
    Issue #3373123: Setting 'Enforce clean and canonical URLs.' breaks CSS...
berdir’s picture

Status: Needs work » Fixed

Merged.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

rolki’s picture

bonrita’s picture

Updating the patch https://www.drupal.org/files/issues/2023-10-20/3373123_redirect_fix_aggr... It is no longer commaptible with the current version 1.10

mibstar’s picture

Ditto to sergeimalyshev on #53.

I can't enable JS aggregation without getting errors using redirect 1.10.0 on a new D10 site. Any ideas why?

Full details on https://www.drupal.org/project/drupal/issues/3377310#comment-15852105