Calling httpError(404) leads to endless redirect loop #1045

th3hamm0r opened this Issue Jul 10, 2014 · 5 comments

4 participants


If your custom code calls httpError(404) in the "index" action or an earlier stage like the init() method and this URL is an existing SiteTree URL or it existed before (versioned table), it results in an endless redirect loop.

Why would someone call httpError(404) for an existing and published URL?
Sometimes we have pages were more conditions (beside "is published") have to be fulfilled. For example we've implemented a time based publishing and versioning of content where the page is published, but actually we check some other dates in the init() method and if the conditions are not met, we throw a 404 error.

Currently this results in an endless redirect loop by the OldPageRedirector because SilverStripe/OldPageRedirector "thinks" the page is existing and therefore redirects to the URL again.

I think it should be differentiated if the core is throwing a 404 or the developer who is using the framework. In the first case the OldPageRedirector should handle the 404 and this is good, because it is a nice feature!
In the second case I think the developer has a good reason to throw a 404 and probably does not want to get a 301 to another or sometimes the same URL.

For now we are using a custom httpError method with no fallback.

Maybe this has to be split into a feature and a bug ticket?

  • BUG: OldPageRedirector redirects to the current URL again
  • FEATURE: The page lookup should use a different 404 error which is then handled by the OldPageRedirector extension. Just calling httpError(404) on a RequestHandler should by default not trigger this extension.

As long as the problem is not resolved - this is the workaround I found:

throw new SS_HTTPResponse_Exception(ErrorPage::response_for(404), 404);
SilbinaryWolf commented May 31, 2016 edited

I went with something like this to ensure the 'onBeforeHTTPError' hooks were being called:

// Workaround cms/#1045
// - Stop infinite redirect
// @see:
$ref = new ReflectionProperty($this->owner->class, 'extension_instances');
$extension_instances = $ref->getValue($this->owner);
$ref->setValue($this->owner, $extension_instances);

return $this->owner->httpError(404);
SilverStripe Ltd. member

See fix #1515

Rather than any complex logic, I've just gone to stop the page redirecting to itself (as it's of no value).

SilverStripe Ltd. member

this is now fixed in 3.2 and up

@dhensby dhensby closed this Jun 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment