Install new module exposes bug in UnroutedUrlAssembler.buildLocalUrl() resulting in duplicated paths in URLs, such as /core/authorize.php/core/authorize.php

Created on 8 October 2015, about 9 years ago
Updated 30 March 2023, over 1 year ago

Problem/Motivation

Install new module give AJAX error: 404 on /core/authorize.php/core/authorize.php

Problem exists on Nginx and PHP built-in webserver, but not with Apache.

Steps to reproduce:

0. Install Drupal somehow, if its installed change to its directly goto step 3
1. drush qd --profile=standard --core=drupal-8 -y d8rc1test
2. cd d8rc1test/drupal-8
3. drush rs /
4. Log in
5. click on "Extend"
6. click on "+ Install new module"
7. Paste in any module link, e.g. http://ftp.drupal.org/files/projects/devel-8.x-1.x-dev.tar.gz

Result:

Note that if you follow the same steps above in a browser with JavaScript disabled, you receive a similar "Page not found" error for core/authorize.php/core/authorize.php.

The reason that this error works on the Apache webserver is that, when Apache is processing "core/authorize.php/core/authorize.php", it evaluates each part of the path in sequence. When it notices that there is an executable file "authorize.php" at the relative location core/authorize.php, it executes that script, passing it the entire request URI, "core/authorize.php/core/authorize.php". Apache is therefore resilient to this error. Other web servers that treat the entire request as a distinct path, on the other hand, fail to find the authorize.php script and return a 404 instead.

Proposed resolution

The target URL is being correctly generated via `Url::fromUri('base:core/authorize.php');`, which behaves correctly; however, UnroutedUrlAssembler.buildLocalUrl() does not assemble the correct target URL in all cases.

Therefore it does

  • global $base_path is exposed on the request context: $erequestContext->indexPhpBasePath()
  • This method name was chosen to make it as explicit as possible and reduce a potential misunderstanding with the existing base path (which is the base path of the current front controller, which is identical in case of index.php, but not fore update.php/authorize.php
  • The URL asseembler then uses the global $base_path to generate the resulting URL
  • There used to be magic to add the front controller to the generated URL. This was removed as we now use ALWAYS the $base_path, and this is it.
  • Note: This lets base: behave in a consistent way aka. be relative to index.php instead of another front controller

Remaining tasks

Needs RTBC

Why this should be an RC target

.
This issue is not critical, and does not qualify for rc eligible. However, this fixes a serious problem in a core API that is widely used. The risk of changing the implementation of a widely-used core API needs to be balanced against the risk that this bug could easily manifest in other situations. Tracking down this problem is difficult. Also, if not fixed, some web servers, such as Nginx, will not work correctly with all Drupal 8 features.

User interface changes

None.

API changes

None. Fixes a flaw in an existing API which was not correctly fulfilling its contracts.

Data model changes

None.

πŸ› Bug report
Status

Needs work

Version

9.5

Component
RoutingΒ  β†’

Last updated 2 days ago

Created by

πŸ‡ΊπŸ‡ΈUnited States greg.1.anderson

Live updates comments and jobs are added and updated live.
  • Triaged core major

    There is consensus among core maintainers that this is a major issue. Only core committers should add this tag.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡¬πŸ‡§United Kingdom shenzhuxi

    Hi @greg.1.anderson, the patch only works with php built-in web server when ht.router.php is in the root directory.
    https://www.drupal.org/project/drupal/issues/3341324 πŸ› ht.router.php can only be used in the root directory Active patch won't fix it.

    For the URL issues through years, I feel that it may be better for Drupal to stop using weird dot position in URLs and only use dot for extension name.

Production build 0.71.5 2024