Redirect hangs (100% CPU)?
I've got 2.6.1 working fine on my dev machine, but having uploaded it to my webhost I've hit a potentially show-stopping problem, and I'm running out of ideas as to how to diagnose it.
When an action causes a redirect (such as clicking on a username to go to their profile) the redirect never happens. The process grabs ~100% of the CPU until it eventually times out after 2 mins, causing an HTTP 500 response.
Logging added to functions safeHeader() (in functions.compatibility.php) and redirectTo() (in functions.general.php) show that the process does call PHP header(), and a logging statement immediately before the exit() call in redirectTo() is executed, but the 302 header never reaches the client.
I've created a one-line stand-alone PHP file containing just the header() call (with identical parameters) in my forum root folder and this works exactly as it should.
Has anyone seen anything like this before? Any ideas what to do next to diagnose it?
Thanks,
Richard.
Comments
Clicking on a username usually doesn't cause HTTP redirects.
Can you actually visit any page other than the home page if you directly type in the route, e.g. /categories or /discussions? If not, this is most likely a .htaccess or server configuration issue.
My themes: pure | minusbaseline - My plugins: CSSedit | HTMLedit | InfiniteScroll | BirthdayModule | [all] - PM me about customizations
VanillaSkins.com - Plugins, Themes and Graphics for Vanillaforums OS
forum/categories and forum/discussions both work fine.
The (eg) "Admin" username is a link to forum/profile/Admin, which attempts to redirect to forum/profile/discussions/Admin. This behaviour is the same on my dev machine (except that the redirect works OK there, of course). The .htaccess files are the same on server and my dev machine. And it's not a redirect loop -- no 302 header reaches the client.
I also assumed a server config issue, except that the standalone PHP header() redirect to forum/profile/discussions/Admin works perfectly.
The really weird thing is that my logging shows that the process reaches the exit() call (it's the very next call after my final logging) but the process doesn't end until it is eventually timed out. There seems to be no new process launched (which is consistent with the lack of a 302 header reaching the client).
A bit more info:
Out of desperation, I just tried changing the exit() to a return. I have so far found three places where the problematic redirect gets called -- going the profile, as described above, signing out (redirects to the forum home), and going to the Admin Dashboard (to forum/dashboard/settings/home).
Of the three, the first two work OK with return instead of exit. Going to the Dashboard still hangs, but the difference in behaviour gives me something to go on ...
Also, this may no longer be a showstopper in launching the forum, as the link that still doesn't work will only be visible to me, and there is a workaround of going first to the Moderation Queue and thence to Dashboard or Settings.
Any further insight from anyone still gratefully received, however ...
Not
exit()
ing after a redirect is a security issue. It should not be omitted. A client can just ignore the redirect header:https://www.acunetix.com/blog/articles/safely-handling-redirects-die-exit-php/
Never heard of an issue like yours.
What happens if you just
exit();
without a redirect?If the same thing happens it may be a destructor or shutdown function that hangs.
My themes: pure | minusbaseline - My plugins: CSSedit | HTMLedit | InfiniteScroll | BirthdayModule | [all] - PM me about customizations
VanillaSkins.com - Plugins, Themes and Graphics for Vanillaforums OS
I think I have a fix, but still don't understand why ... and as you suspected, it actually has nothing to do with the redirect itself.
I stepped through the code that runs after the
exit();
in an IDE on my dev machine, then added logging to see how far it got on my webhost. I eventually isolated the problem to theheader_register_callback()
call in theGdn_Dispatcher
class.It seems that this causes the problem (but only on my webhost) if you
exit();
without previously having output anything.Having established this, I just added a line
echo 'Redirecting ...'
(output that's never actually seen, of course) to theredirectTo();
function, immediately before theheader();
call, and this seems to have resolved the problem.I've still no idea why this is a problem, though. Doesn't sound like a server config problem to me, so it looks like an issue with the PHP implementation on the webhost (it's running PHP 7.2.9 on LiteSpeed, my dev setup is currently PHP 7.2.7 on Apache).