Skip to content

refactor(base): modernize and tidy OC::handleRequest()#60293

Open
joshtrichards wants to merge 11 commits into
masterfrom
jtr/refactor-base-handleRequest
Open

refactor(base): modernize and tidy OC::handleRequest()#60293
joshtrichards wants to merge 11 commits into
masterfrom
jtr/refactor-base-handleRequest

Conversation

@joshtrichards
Copy link
Copy Markdown
Member

@joshtrichards joshtrichards commented May 11, 2026

Summary

Refactors the monolithic OC::handleRequest() in lib/base.php for readability and maintainability. Streamlines/documents the control flow and decomposes it a bit. No functional changes intended.

Key changes:

  • Extracts app-loading logic into named helpers: loadAuthenticationApps(), loadAppsForPreAuthenticationPhase(), loadAppsForAuthenticatedRequests(), loadAppsForRouting()
  • Extracts themingAssetRequest() helper to replace a long inline &&-chain
  • Splits checkMaintenanceMode() into a pure renderer (renderMaintenancePage()) with the gate condition now inline in handleRequest() — making the control flow explicit
  • Renames printUpgradePage()renderUpgradePage() for naming consistency
  • Removes unreachable !self::$CLI guard (handleRequest() is only ever called from index.php)
  • Replaces substr($path, -3) !== '.js' with str_ends_with()
  • Resolves $userSession once and reuses it; removes redundant re-fetches
  • Adds/improves inline comments and a full docblock on handleLogin(), which has important side effects to know about

Notes

  • Not sure if this is best left for v35 versus v34 so I left off the milestone. This isn't a feature and should just be an internal refactor so it'd be nice to have it in so we're iterating any backports on the newer code, but I have no strong opinion either way as long as it ends up in master. ;)
  • OC::handleRequest() has no existing standalone / direct unit test coverage. There is, however, a significant amount of indirect coverage via existing integration tests and most of the code paths - particularly the sensitive ones (like maintenance, theming, authentication, etc.) - are covered in that way. The current architecture (bare exit(), header(), Server::get() calls, superglobal reads, etc) makes unit testing impractical without a larger refactor.

TODO

  • Test test test
  • Drop old /core/ajax/update.php request path bypass in this pass?

Checklist

AI (if applicable)

  • The content of this PR was partly or fully generated using AI

Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
Comment thread lib/base.php Outdated
Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
@joshtrichards joshtrichards added the 2. developing Work in progress label May 11, 2026
The real contract is mostly side effects and possibly exceptions, which is important to have documented.

Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
@joshtrichards joshtrichards added the ♻️ refactor Refactor code (not a bug fix, not a feature just refactoring) label May 14, 2026
Signed-off-by: Josh <josh.t.richards@gmail.com>
@joshtrichards joshtrichards added 3. to review Waiting for reviews feature: files and removed 2. developing Work in progress labels May 15, 2026
@joshtrichards joshtrichards marked this pull request as ready for review May 15, 2026 14:41
@joshtrichards joshtrichards requested a review from a team as a code owner May 15, 2026 14:41
@joshtrichards joshtrichards requested review from ArtificialOwl, CarlSchwan, leftybournes and salmart-dev and removed request for a team May 15, 2026 14:41
@joshtrichards joshtrichards changed the title refactor(base): modernize and tidy handleRequest() refactor(base): modernize and tidy OC::handleRequest() May 15, 2026
…route

Signed-off-by: Josh <josh.t.richards@gmail.com>
@joshtrichards joshtrichards added this to the Nextcloud 35 milestone May 19, 2026
@joshtrichards joshtrichards requested a review from come-nc May 19, 2026 13:49
Long standing behavior. Just adds test coverage for it.

Signed-off-by: Josh <josh.t.richards@gmail.com>
Copy link
Copy Markdown
Contributor

@come-nc come-nc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few remarks but the changes looks good.
Could you squash the commits into something more sensible?

Comment thread lib/base.php
$upgrade = Util::needUpgrade();

// Show "upgrade" page if Nextcloud needs to be upgraded and not in maintenance mode (i.e. already in progress).
if ($upgrade && !$maintenance && !$bypassMaintenance) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if ($upgrade && !$maintenance && !$bypassMaintenance) {
if ($upgrade && !$bypassMaintenance) {

The maintenance check is redundant, we exited earlier if we are in maintenance without bypass.
We may want to rename $bypassMaintenance as it also bypasses upgrade check. Could be $isJavascriptResource or something? Or $bypassMaintenanceAndUpgrade.

Comment thread lib/base.php
Comment on lines +1111 to +1113
// NOTE: This is shown to the first web visitor to land after a code update...
// ...and will continue to be shown to subsequent visitors until the upgrade is
// triggered.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// NOTE: This is shown to the first web visitor to land after a code update...
// ...and will continue to be shown to subsequent visitors until the upgrade is
// triggered.
// NOTE: This is shown to the first web visitor to land after a code update
// and will continue to be shown to subsequent visitors until the upgrade is
// triggered.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would actually be clearer:

Suggested change
// NOTE: This is shown to the first web visitor to land after a code update...
// ...and will continue to be shown to subsequent visitors until the upgrade is
// triggered.
// NOTE: This is shown to web visitors after a code update until the upgrade is triggered.

Comment thread lib/base.php
$router->match($requestPath);
return;
} catch (ResourceNotFoundException $e) {
// ...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be replaced by an explanation of why we continue when this exception happens.

Comment thread lib/base.php
Comment on lines 1197 to 1207
if ($requestPath === '') {
// Someone is logged in
$userSession = Server::get(IUserSession::class);
// Redirect to the default app if visitor is logged in
if ($userSession->isLoggedIn()) {
header('X-User-Id: ' . $userSession->getUser()?->getUID());
header('Location: ' . Server::get(IURLGenerator::class)->linkToDefaultPageUrl());
} else {
// Not handled and not logged in
// Redirect to the login page if visitor is not logged in
header('Location: ' . Server::get(IURLGenerator::class)->linkToRouteAbsolute('core.login.showLoginForm'));
}
return;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can’t that be done earlier?
Looks like a loss of time and resources to first run the router and load all apps just to issue a redirection for default route.

Comment thread lib/base.php
}
}

private static function themingAssetRequest(string $requestPath): bool {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static function themingAssetRequest(string $requestPath): bool {
private static function isThemingAssetRequest(string $requestPath): bool {

@joshtrichards joshtrichards added the technical debt 🧱 🤔🚀 label May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews feature: files ♻️ refactor Refactor code (not a bug fix, not a feature just refactoring) technical debt 🧱 🤔🚀

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants