Problem/Motivation
Currently it is possible to enforce a $base_url
from within settings.php
. Up until Drupal 4.6.x this was required. Since then it was only necessary on broken webserver configurations. Also depending on the webserver configuration, setting $base_url
was required in order to prevent instances of #2221699: HTTP_HOST header cannot be trusted (e.g., possibly #1355344: Possible to deface using HTTP_HOST if base_url not set in settings.php), but that issue has been resolved by introducing the trusted_host_patterns
setting.
However, since there is no way to enforce the base URL in a Symfony request, the setting only works for code which is still depending on the deprecated globals. E.g., on a site which enforces $base_url
from settings.php
, modern code using something like $request->getSchemeAndHttpHost()
will produce the wrong results in such configurations.
Note that enforcing $base_url
in settings.php
also influences $base_root
and $base_path
globals.
All of this functionality not covered at all by any tests.
Proposed resolution
Remove the option to specify a base_url
from within settings.php
.
Remaining tasks
Review.
User interface changes
None.
API changes
None.
Data model changes
None.
Beta phase evaluation
Issue category | Bug because it removes defect functionality |
---|---|
Issue priority | Normal |
Disruption | Disruptive for existing sites if they are running on webservers with broken configuration |
Comment | File | Size | Author |
---|---|---|---|
#35 | Screenshot from 2016-06-21 17:28:49.png | 49.2 KB | znerol |
#3 | interdiff.txt | 593 bytes | znerol |
#3 | remove_the_option_to-2528988-3.patch | 4.57 KB | znerol |
#3 | interdiff.txt | 593 bytes | znerol |
#1 | remove_the_option_to-2528988-1.patch | 3.99 KB | znerol |
Comments
Comment #1
znerol CreditAttribution: znerol commentedComment #2
znerol CreditAttribution: znerol commentedComment #3
znerol CreditAttribution: znerol commentedForgot the instance in
Settings::initialize()
.Comment #4
znerol CreditAttribution: znerol commentedPosted change record draft.
Comment #5
dawehnerThe question is whether we could, maybe in the CR, explain how to fix your webserver configuration.
Given that this feature fundamentally brakes assumptions about the request we have, we have problems, when we keep it.
Comment #6
aatdark CreditAttribution: aatdark as a volunteer commentedi'm using drupal behind a reverse proxy which handles HTTPS.
the connection to the actual web server is http.
Client --- [https] -- reverseproxy -- [http] -- webserver (drupal)
drupal8-beta14 works well except that the server sends redirects after POSTs to the http:// site (absolute path)
what is the recommended "fix" in the [webserver]config?
Comment #7
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedThis is major and a hard judgement call.
Tentatively setting to RTBC.
If we promise that base_url would do something, which it long time already does no longer that is a big problem ...
So removing is likely the best option.
It might need the #313145: Support X-Forwarded-* HTTP headers alternates in for it to work properly for all cases, which for now at least has a workaround as Request:: has statics.
Comment #8
catchI've gone ahead and committed/pushed this to 8.0.x.
We know the feature is incompatible with Symfony's handling of base paths (and that the discrepancy between a Drupal base path and a Symfony base path is already a bad issue).
If this breaks an existing install, then that'll be a shame, but we can always revert the patch during a release candidate or even minor release.
However if we leave the feature in, we're stuck with it forever.
Thanks!
Comment #10
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedPublished the change record. (which is how I had found that issue yesterday ;) )
Comment #11
chx CreditAttribution: chx commentedSo what are we doing to avoid Drupal running on an Apache bound to localhost behind a reverse proxy trying to load CSS/JS from http://localhost which is what $base_url was often used for?
Comment #12
catch#313145: Support X-Forwarded-* HTTP headers alternates is supposed to add support for reverse proxies setting host.
The reason I committed this issue is because it's incompatible with the code that checks that - we need to not have three ways to get the same thing that actually get you different things.
Comment #13
pwolanin CreditAttribution: pwolanin as a volunteer and at Acquia commentedAdding note about file_public_base_url settinh to CR
Comment #14
hass CreditAttribution: hass commentedI'm not sure this was a good idea.
I had tons of users in linkchecker that used to run cron with localhost and sometimes with internal ports. In this case relative urls have been prefixed with these internal urls. The only solution was to configure the base path. How can these issues solved now? It does not require a reverse proxy to run into these issues.
Comment #15
hass CreditAttribution: hass commentedComment #16
lightsurge CreditAttribution: lightsurge commentedI also think base_url in $settings is valid for some configurations...
With drupal, I often use an Apache2 vhost, coupled with a reverse proxy that is listening at a subdirectory.
So external_host.com/subfolder1 reverses to internal_host, where Drupal resides. That works pretty well, except during install: #2377233: $_SERVER['REQUEST_URI'] reverse proxies, base_urls and Apache2 don't seem to mix well although it's pretty easy to fix by altering REQUEST_URI in $settings along with setting base_url.
There are other people using this sort configuration, see end of #244593: Document how to configure Drupal for reverse proxies
Comment #17
lightsurge CreditAttribution: lightsurge commentedI might be wrong but it doesn't look like #313145: Support X-Forwarded-* HTTP headers alternates adds support for reverse proxies being able to identify to the internal host the part of the uri which should be considered the base url (i.e. the subfolder that Drupal should consider the top level directory, and therefore not used as part of the Drupal path).
The alternative without base_url might either be setting up the internal host to remove that part of the request URI, or the reverse proxy to remove it from the request before it even reaches the internal web server, or maybe putting it in a subfolder just for the sake of keeping Drupal happy. Is this more valid? Not as easy.
I suppose after this patch, it might be possible to just set chagen REQUEST_URI in $settings, although I don't know if #313145: Support X-Forwarded-* HTTP headers alternates will impact on that.
Comment #18
gaele CreditAttribution: gaele commented+1 for #16. This is the situation:
Client --- [www.example.com/subdir] -- reverseproxy -- [internalhost.local] -- webserver (drupal)
So this statement:
is incorrect. Please change this in the change record.
Comment #19
znerol CreditAttribution: znerol commentedCan anybody explain how you would host any non-drupal application with a setup like #16 or #18? In my opinion there is no value in supporting such setups if the only way to make them work is to retain Drupal specific settings which prevent us from moving forward towards a better architecture.
As pointed out in the issue summary, there is no such setting in Symfony and hence you wouldn't be able to host any Symfony based project like this.
Comment #20
gaele CreditAttribution: gaele commentedDon't forget #14.
There is a need for this, people already use these kind of set ups, so we need a solution. Not necessarily using $base_url.
Comment #21
catchdrush has a --uri option, not sure why that won't work for #14.
We need to allow the setup, but we don't necessarily need explicit support for it in core - it could end up being a documentation issue.
Comment #22
hass CreditAttribution: hass commentedI never analyzed what drush does with
--uri
argument. So I need to ask how this works for my module. If this works reliable I'm fine with this solution. Linkchecker does all it's stuff inside cron. Maybe I need to change some code to make this happen?Comment #23
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commented#19: The problem is HTTP_HOST is only the host, but not the subdir.
e.g. you have external-host.com/subdir => but drupal is in internal-host.com, probably redirected based on varnish rules.
In the past you could just set $base_url to whatever you needed it to be and all generated urls would exhibit that behavior.
Additionally setting .htaccess RewriteBase to /subdir then all works.
So but Drupal now in 8 would generate: external-host.com, which is wrong as it never sees the subdir - but maybe it should, too.
Hmmm, I think it needs more testing the #16 / #18 might just work in practice according to Symfony using the original REQUEST_URI for that - unless Varnish does the rewriting and not .htaccess.
Comment #25
Patricia_W CreditAttribution: Patricia_W as a volunteer commentedI am testing version Drupal 8 of a site and as a result I am using a subdirectory to test. Now I have to add the directory name to all internal links.
I'm far from an expert in this area but if I add the directory name during testing I will have to remove it from the links when I change the URL. Is there a way to avoid this? Previously I could test using $Base_Url.
Comment #27
mat8iou CreditAttribution: mat8iou commentedI'm wishing the $Base_Url setting was still there, as it solved a lot of problems in the past.
Having said that, I've worked out a (sort of) solution to the problem that may work for some people.
See my post on it & then the following post with the solution here:
https://www.drupal.org/node/2716043#comment-11139921
Comment #28
Fidelix CreditAttribution: Fidelix as a volunteer commentedUnfortunately Drupal 8's inability to set a base_url prevents some of our projects from running on Platform.sh (#16).
Comment #29
toomanypets CreditAttribution: toomanypets commentedEvery site I've built with d6 and d7 has been located in subdirectory of webroot, using a top level .htaccess file and $base_url to mask the URL. For example:
webroot: /home/johndoe/sites/www.example.com/htdocs/
drupal: /home/johndoe/sites/www.example.com/htdocs/drupal7/
url: http://www.example.com
This is not a "broken webserver configuration." It's a very flexible and valid configuration.
I can't do this with d8. So I'll use d7 or backdrop instead.
Comment #30
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commented#29: You should be able to just use the subdir functionality of the .htaccess rewrite rules to get that to work.
The problem here was not that we wanted to remove $base_url, but that by introducing Symfony we had partial support for $base_url and partially not, which would have led to even more bugs, because then your site configuration should have worked, but only for certain cases.
#28: Are you sure this is not resolvable with a .htaccess rewrite rule?
Comment #31
toomanypets CreditAttribution: toomanypets commentedRegarding #29...
I was unable use the subdir functionality of the .htaccess rewrite rules to get this to work. Example:
RewriteRule ^$ d8/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ d8/$1 [L]
Problems
1. View source shows assets with subdirectory. For example:
<script src="/d8/core/assets/vendor/jquery/jquery.min.js?v=2.1.4"></script>
This should be:
<script src="/core/assets/vendor/jquery/jquery.min.js?v=2.1.4"></script>
2. Under Basic site settings (admin/config/system/site-information), the default front page prefix is:
http://www.example.com/d8
This should be:
http://www.example.com/
3. When adding an alias (admin/config/search/path/add), the prefix for Existing system path and Path alias is:
http://www.example.com/d8
This should be:
http://www.example.com/
I'm sure there are others. These were the problems I found in the first five minutes.
Workaround
1. Configure .htaccess as shown above
2. Implement https://www.drupal.org/node/2612160#comment-10637490
3. Implement https://www.drupal.org/node/2619432#comment-11012323
Items 2 and 3 don't appear to have received much in the way of community review, and may be a bit dodgy.
Comment #32
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commented#31: What happens if you use:
in your .htaccess?
Comment #33
andypostAlso please keep in mind that it should work with nginx and likely in php-runserver
Comment #34
toomanypets CreditAttribution: toomanypets commentedRegarding #31...
This page (https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteengine) states:
Item 1 is true, therefore RewriteBase is not required in my .htaccess file which is located in webroot.
Regardless of documentation I tested your suggestion. Modifed .htaccess in webroot:
RewriteBase /d8
RewriteRule ^$ $1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ $1 [L]
This also fails, as expected.
I also added "RewriteBase /d8" to the .htaccess file in the Drupal root.
This also fails.
Comment #35
znerol CreditAttribution: znerol commentedI checked on Debian Jessie / Apache 2.4 / php 5.6.20 / mod_rewrite . Drupal 8.1 works in a subdirectory there out of the box, including css and alias paths (see attached screenshot).
So, people having troubles setting up Drupal 8 in a subdirectory, please open a support issue and post the relevant parts of your OS/webserver configuration there.
Comment #36
toomanypets CreditAttribution: toomanypets commentedRegarding #35...
Your screenshot shows that you've accessed this site via
http://localhost/drupal-8/about/
-- the installation subdirectory directory is not masked in the URL. I've never had a problem with this either.The problem I reported in #29 refers to the scenario where we wish to hide (mask) the installation subdirectory in the URL using an .htaccess in webroot combined with $base_url.
Comment #37
znerol CreditAttribution: znerol commented@toomanypets please just open a support request and describe your exact setup there.
Comment #38
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commented#35: The use case is that Drupal 8 is in a sub-directory, but that the subdirectory should be invisible.
e.g.
www.host.com => /d8
But Drupal 8 just showing www.host.com for all generated urls.
Comment #39
znerol CreditAttribution: znerol commentedRe #35: The problem is that people used
$base_url
for many different things. This issue was reopened in #11 and #14 for different reasons, and #29 is yet another one. I'm pretty sure that we will need different solutions for them, therefore I'd suggest to go with separate support requests.Comment #40
gaele CreditAttribution: gaele commentedThis is not fixed.
People used $base_url for valid reasons, so this statement:
is incorrect. Please change this in the change record.
Comment #41
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedI fixed the change record to remove the "annoying line", lets open up support requests for all 3 issues and link them as a child issue of this one, please.
I am pretty sure with some mod_rewrite magic it will be possible to do what you all want.
I am also working on pre-kernel middlewares, which should allow to change the request in a way, to override the requestUri before the Container is even loaded.
Edit:
It seems it is already possible to change the global request:
https://www.drupal.org/node/2619432#comment-11012323
This seems to be the easiest solution.
Comment #42
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedHm, I do think we really bugged this up.
The problem is:
- The goal of this issue was to ensure that we rely on Symfony for base url and base path, which would work fine.
However:
We still use server SCRIPT_NAME (from the request), which is not rewritten by .htaccess, but only the request url, hence people end up with the REQUEST_URI being correct and the $base_url being wrong ...
Therefore this really needs work.
Comment #43
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedTo #42 here is a little script to reproduce:
Put that script as index.php in a directory called 'bar/' and add the following rewrite rule into the main .htaccess of Drupal 8:
Copy the original .htaccess to bar/ directory.
Now get http://d8-dev.host.com/node/1 and it returns:
So Symfony's functions return a base_pathl() of '/' and Drupal's base_path() returns /bar.
That means the very mismatch this issue tried to prevent is still present, but now there is no way to 'fix' this anymore.
Changing that line to:
resolves the problem and did still work fine with the core/ scripts in my tests.
as prepareBaseUrl() has special code to deal with request_uri() being part of the base_url().
And as we call getUri() in page_cache anyway, this is not a performance concern either.
Comment #44
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedFollow-up here: #2753591: Fix mismatch of $base_url with Symfony request object, lets leave this as fixed.