By adding RewriteOptions Inherit to the .htaccess we allow virtual hosts to define their own rewrite rules. They would otherwise be overwritten, forcing us to either hack the rewrites in the .htaccess or disable it entirely.

This fix makes it possible to use Drupal's built-in rewrite rules side by side with custom ones.

Comments

kristofferwiklund’s picture

I think it makes sense but I would recommend to change in the comment. Saying "Use custom rewrite rules defined elsewhere." might freak people about security issue but what it actually does is :

"This forces the current configuration to inherit the configuration of the parent. In per-virtual-server context, this means that the maps, conditions and rules of the main server are inherited. In per-directory context this means that conditions and rules of the parent directory's .htaccess configuration are inherited." Apache docs

So a comment like. "Use custom rewrite rules defined in vhost settings. Those rules are applied after rules defined in this file."

chx’s picture

Status: Active » Closed (won't fix)

The handbook suggests http://drupal.org/node/138889 putting Inherit in your vhost config directly. It seems there's nothing to do here.

tobiassjosten’s picture

Status: Closed (won't fix) » Needs review
StatusFileSize
new523 bytes

Putting RewriteOptions Inherit in the vhost configuration does nothing to help this problem. All that achieves is carrying over configuration from the main server, into the vhost scope. The .htaccess will still take precedence and disregard everything else in the end.

I have tried to summarize the problem and rewritten the comment as per Kristoffer's suggestion. Please have another look and consider this?

chx’s picture

Instead of a blog post you need to write an issue summary. The documentation on this option is entirely unclear:

This forces the current configuration to inherit the configuration of the parent. In per-virtual-server context, this means that the maps, conditions and rules of the main server are inherited. In per-directory context this means that conditions and rules of the parent directory's .htaccess configuration are inherited.

I simply supposed that slapping RewriteOptions Inherit into your vhost configuration applies to the whole vhost. Hardly an unreasonable thing to suppose... What you are saying is that this is not so? Then say just that and be done. We have a core issue queue for these things. Slamming me for this on twitter and a blog post is absolutely the wrong thing to do.

tobiassjosten’s picture

Again, I'm sorry if I came across like calling you out; that was never my intention. Glad we could resolve it on IRC though.

As for the issue, the problem is with how inheritance works. On the bottom level you have the main Apache server. Then there's the virtual host, where the Inherit option brings in configuration from the main server. Finally on the top level is the .htaccess and its Inherit option makes it re-use configuration from the virtual host.

When the .htaccess is found and used (with AllowOverride All in the <Directory> container) Apache will completely disregard any rewrite rules in the vhost or main server, if the file does not explicitly allow inheritance.

This patch adds the RewriteOption Inherit configuration to the .htaccess, which will allow site owners to add custom rewrite rules in their virtual host, without touching the .htaccess. All while keeping the original functionality of the .htaccess.

There is one caveat however. Inherited rewrite rules are evaluated in the backwards order, starting with the ones in .htaccess. Because it uses a catch-all pattern, even with inheritance it will not allow arbitrary rewrite paths in the vhost.

For use cases like routing /robots.txt through Drupal instead of serving the file, this is perfectly fine. My simple patch fixes this and for that reason I think it's still valid.

All the other use cases could be fixed too but it'd require Apache >= 2.3.10, where InheritBefore was introduced. This makes vhost rewrite rules be evaluated first. I could add that to the patch, so that if you want this functionality you could just use a newer version of Apache and it would just work. Do you think that would be a good idea?

chx’s picture

Maybe commented out? Because if you add an option that is not recognized by Apache it freaks out.

tobiassjosten’s picture

StatusFileSize
new610 bytes

The problem with that is then we're back to square one — you would have to go in and make changes to the `.htaccess` core file.

But you are of course right, we can't have Apache freak out.

One alternative is to use mod_version and apply this configuration only where supported. It would require enabling that module of course but this feature is entirely directed to advanced users anyway, so I think it's a fair tradeoff. Wouldn't you agree?

Adding a new patch for this.

ericthelast’s picture

I wholeheartedly second this patch. Currently, we have a use case that requires an additional rewrite rule to be placed in .htaccess for it to work. This is obviously a terrible idea as 1) it's hacking core, 2) every time core is updated we have to remember to re-apply the rules.

I could settle for using this patch but again...ever core update I'd have to remember to re-apply. Any ideas???

Letharion’s picture

Category: bug » feature

From http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions:
Inherit

Rules inherited from the parent scope are applied after rules specified in the child scope.

InheritBefore

Like Inherit above, but the rules from the parent scope are applied before rules specified in the child scope. Available in Apache HTTP Server 2.3.10 and later.

If we add InheritBefore, one can make additions to the rules in the .htaccess file with your vhost file.
If we add Inherit, one can make additions and changes to the rules in the .htaccess file with your vhost file. (As the vhost file rules are now applied after .htaccess, one can override what the .htaccess file says)

I would argue that Inherit is a better option. Among the limited advanced users that will have a vhost file, what reason is there to limit their ability to potentially overwrite changes in the .htaccess file?

While I agree that it's a useful feature, I believe this is the wrong approach to take to solve the type of issues in #8. There is a far more generic solution to that in a make-file for example.

I can't see how this is a bug though, so I'm setting to feature request.

tobiassjosten’s picture

Thanks for taking the time to review this!

The problem is with Drupal's finishing catch-all rewrite rule in the .htaccess. If you use Inherit with that, any rewrite rules in your vhost will be moot, since everything will have been routed through the front controller already. I just tested with the following.

# .htaccess
RewriteOptions Inherit
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^ index.html [L]
# vhost
RewriteRule ^asdf$ asdf.html [L]

It will show index.html when I visit /asdf. Unfortunately I don't have access to Apache >2.3.10 (with InheritBefore) right now but I am positive it worked as expected last I experimented, while writing this patch.

Letharion’s picture

I haven't done Apache inherit rules myself. I thought about it in terms of programming inheritance, but actually, "inherit" doesn't inherit, it prepends (inherit) or appends (inheritbefore) rules, which is quite different.

My comments in #9 with regard to Inherit vs InheritBefore should be ignored. Patch in #7 looks good.

Is this something we can write tests for? Do we have the capability with the test bots to setup different vhost files?

ericthelast’s picture

Just as an aside, using Drupal 7 I was able to use hook_url_inbound_alter() and preg_match() to simulate a rewrite rule. Not as optimal as a true rewrite but it did satisfy my immediate need.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

daften’s picture

Issue summary: View changes

Is it still an option to do this? With composer being used, I suspect it might for some use cases be needed more now than before.

jelle_s’s picture

Just to confirm: Patch from #7 still applies to 8.5.x-dev.

daften’s picture

Status: Needs review » Reviewed & tested by the community

The patch still applies

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

The .htaccess file is a file where we expect user modifications. I think the correct thing here is to add a commented out section like

  # If you want to inherit rewrite rules from a parent context uncomment the
  # following line: (Requires an apache version >= 2.3.10)
  # RewriteOptions InheritBefore

I run my dev set up in a virtual document root which means I have to change .htaccess and have to manage incorporating any changes to .htaccess that come from HEAD.

Also, could suddenly enabling this option on existing sites have unexpected repercussions?

daften’s picture

Status: Needs work » Reviewed & tested by the community

Changes to .htaccess can be annoying and cumbersome. E.g. we have a build server that assembles our code, so we have to just use the .htaccess from drupal core as is. Same for a lot of people that use shared hosting.
This change has NO impact for existing users, none whatsoever. Unless you've already put rewrite rules in a htaccess file higher up, which would be a very strange scenario ... :)
This allows you to put rewrite rules in another .htaccess file in a folder higher in the folder hierarchy of the server, which is otherwise impossible. ALL other htaccess items can already be put in such a htaccess file and just work. Also, the rewrite rules in the "other" htaccess file are applied before the rules in the drupal htaccess file, so the drupal access rules are still the "master".

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

Unless you've already put rewrite rules in a htaccess file higher up, which would be a very strange scenario ...

When you are dealing thousands or sites there is pretty much a case of every strange scenario. As pointed out in #22 .htaccess is meant to be customised and there is no way we can provide something that just works for everyone. But we should not change it to something that might break an existing site. For me we should improve the documentation in the .htaccess file and move on. If we want to do this otherwise we need to wait till Drupal 9 as there is no need to make a potential breaking change till then.

If you have a build server it could easily assemble your htaccess file for you.

daften’s picture

I don't agree at all that this would break anything. And assembling a htaccess file on a build server is not something that can be done extremely easily. But fine, I haven't seen every user's setup.
One question though: how can we make sure this issue will actually be picked up for drupal 9 and not lie around for another 6 years. It'd be a shame to let a change like this lying around because it doesn't get picked up. And do we need additional documentation then on drupal.org in the handbook for this?

And thanks for responding. If i seem pissed off, it most likely is because I am, because we struggled with this for quite a while, and this would have been so helpful.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

catch’s picture

Status: Needs review » Needs work

The way to move this issue forward would have been to implement the feedback from #22. That could still happen so marking needs work for that.

Composer scaffolding makes it a lot easier to manage .htaccess in git.

https://www.drupal.org/docs/develop/using-composer/using-drupals-compose...

Version: 9.5.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.