I have subdomain-based domains, set up like the following:
- local.example.org <-- default, enabled
- de.local.example.org <-- enabled
- ch.local.example.org <-- disabled
When I try to access ch.local.example.org as an anonymous user, my browser tells me that the page is being redirected infinitely (redirect loop).
I also have the following message in watchdog:
Notice: Undefined index: path in domain_invalid_domain_requested() (Zeile 2791 von \sites\all\modules\domain\domain.module).
The respective function (domain_invalid_domain_requested) tries to redirect based on the 'path' property of a domain array; my guess is that it should use domain_get_uri() to get the proper redirect url.
Comments
Comment #1
agentrickardCannot replicate. 'path' should already be populated by the domain_default() call.
There may be a server-level issue (DNS config) at work here.
Is there anything in the site error logs (e.g. Drupal's watchdog() function)?
Comment #2
bforchhammer commentedHm, I should add that the domain was matched via an alias so maybe it's not fully loaded (yet?)...
I'll have another look at this later (not on my dev machine at the moment).
Comment #3
agentrickardIs the alias itself set to redirect? That might explain why I couldn't reproduce.
Comment #4
bforchhammer commentedNo the alias is not redirected.
I was able to reproduce this on a relatively clean setup (domain, domain alias, various core modules+devel) as well. Same domain setup as described above, with additional alias:
Watchdog has just the following pairs of messages over and over again:
This only happens for anonymous users; logged in users are redirected fine.
Comment #5
agentrickardI'm skeptical of changing here without being able to reproduce, since this has (apparently) been working fine for a long time. The only other reports like this turned out to be either a server problem or Global Redirect interfering in the process.
What is you home page set to? I think this might happen if you are using a single node for the home page. Panels or Views might trigger this as well.
I suspect the issue comes up with this line:
$node = menu_get_object();. You are entering into that loop.But I also wonder why $default['path'] is not set. Is it possible you don't have a default domain? Does the attached patch fix things? It makes no difference to my test server.
Comment #6
bforchhammer commentedSorry, I still haven't found time to properly debug this/review your patch; it's on my todo list for this week :)
Comment #7
agentrickardComment #8
Yaron Tal commentedThis seems to happen when domain_default() is called by another module. In my case a custom module called domain_default_id() in hook_domain_bootstrap_full() which will run domain_default(), but without the domain_api() call. This will cause domain_default() to cache the $default value, without running domain_load, and thus not adding the path.
A fix would be to run domain_default(TRUE) in domain_invalid_domain_requested(), but that would not be ideal. I guess a better idea would be to override the $default if domain_default() is run with $alter == TRUE and was not run that way before.
Would then become:
Comment #9
agentrickard@Yaron Tal
I still need a better description of the cause. What is the other module doing? When? Why is it calling domain_default()?
After we understand the cause, we can examine the code for solutions.
Comment #10
Yaron Tal commentedI have the following code in a custom module that is being used to create template domains which are only available to admin users and have no other use than to be copied to new domains.
Comment #11
bforchhammer commented@Yaron Tal: Thanks for taking over and looking into this!
FWIW, when I said above that I was able to reproduce the error with a relatively clean setup, I think it included the domain_variable module, which calls at least
domain_get_domain()duringhook_domain_boostrap_ful(), possibly alsodomain_default().Comment #12
agentrickard@Yaron Tal
Thanks. I see what that code is doing, and it definitely could cause a loop. I'm not sure how we can prevent that without diving into the code.
The test framework should support adding a test for this condition.
You might also get around this because the $_domain array should contain an is_default flag, so you don't need to call domain_default_id(). But I can tell that the 'valid' flag setting is the problem here.
Comment #13
Yaron Tal commentedIf I do a var_dump($_domain); at the start of my hook_domain_bootstrap_full() I get this output (on the default domain):
array(5) {
["domain_id"]=> string(2) "31"
["subdomain"]=> string(15) "domain.dev"
["active_alias_id"]=> string(1) "2"
["redirect"]=> bool(false)
["site_grant"]=> bool(true)
}
I also have the domain_alias module enabled here.
I might have a bit more time later today, and I'll try to write a test which is able to reproduce this issue.
" But I can tell that the 'valid' flag setting is the problem here."
Yeah that will make the domain module redirect the user to the main domain.
The problem is the caching of the domain in domain_default();
1. hook_domain_bootstrap_full() calls domain_default() (or domain_default_id() which calls domain_default()) with $alter = FALSE to make sure domain_api isn't called.
2. domain_default() caches the result.
3. domain_invalid_domain_requested() is triggered because the user is visiting an invalid domain.
4. It cals domain_default() to get the default domain.
5. drupal_goto($default['path'] . drupal_get_path_alias($path));
6. Since domain_api() wasn't called $default['path'] == NULL; and the user will be redirected to the current page on the current domain.
7. And we start back at 1
I hope this make the issue clear. If I have time later today I'll send in a patch for a test.
Comment #14
agentrickardThat's a perfect description.
If 'path' is not being set, perhaps we need to check for that and call domain_get_path() directly in the invalid code.
Comment #15
Yaron Tal commentedI'd suggest the change in comment #8, because the problem is not the missing path, that is just a symptom of a too early cached domain.
Also this would be easy to test for (test seems too small to create a real patch for).
Edit: maybe we could even make sure only the if ($alter){} part of domain_default() is run in the second row of the above test, instead of the whole function again. That way it'd be a bit lighter.
Comment #16
Yaron Tal commentedI created a patch that implements the above tests and suggested changes. I hope it is clear what I mean, and that it helps you fix the bug.
Edit: Sorry this patch comments out a test case.
Comment #17
Yaron Tal commentedFound the same bug again. Re-created patch, now without commenting out the test.
Comment #18
fagoRan into the problem as well while using domain directory. The patch fixes the problem and even comes with a test. It's not necessarily the cleanest solution, but I guess that's due to domain_default() having the $alter in the flag in the first place. Else, patch is good - thus RTBC!
Comment #19
fagoComment #20
agentrickardBumping for review.
Comment #21
agentrickardMinor re-roll.
Comment #23
agentrickardCommitted.