refactor(base): modernize and tidy OC::handleRequest()#60293
refactor(base): modernize and tidy OC::handleRequest()#60293joshtrichards wants to merge 11 commits into
OC::handleRequest()#60293Conversation
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>
Signed-off-by: Josh <josh.t.richards@gmail.com>
Signed-off-by: Josh <josh.t.richards@gmail.com>
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>
Signed-off-by: Josh <josh.t.richards@gmail.com>
OC::handleRequest()
…route Signed-off-by: Josh <josh.t.richards@gmail.com>
Long standing behavior. Just adds test coverage for it. Signed-off-by: Josh <josh.t.richards@gmail.com>
come-nc
left a comment
There was a problem hiding this comment.
A few remarks but the changes looks good.
Could you squash the commits into something more sensible?
| $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) { |
There was a problem hiding this comment.
| 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.
| // 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. |
There was a problem hiding this comment.
| // 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. |
There was a problem hiding this comment.
This would actually be clearer:
| // 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. |
| $router->match($requestPath); | ||
| return; | ||
| } catch (ResourceNotFoundException $e) { | ||
| // ... |
There was a problem hiding this comment.
Should be replaced by an explanation of why we continue when this exception happens.
| 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; | ||
| } |
There was a problem hiding this comment.
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.
| } | ||
| } | ||
|
|
||
| private static function themingAssetRequest(string $requestPath): bool { |
There was a problem hiding this comment.
| private static function themingAssetRequest(string $requestPath): bool { | |
| private static function isThemingAssetRequest(string $requestPath): bool { |
Summary
Refactors the monolithic
OC::handleRequest()inlib/base.phpfor readability and maintainability. Streamlines/documents the control flow and decomposes it a bit. No functional changes intended.Key changes:
loadAuthenticationApps(),loadAppsForPreAuthenticationPhase(),loadAppsForAuthenticatedRequests(),loadAppsForRouting()themingAssetRequest()helper to replace a long inline&&-chaincheckMaintenanceMode()into a pure renderer (renderMaintenancePage()) with the gate condition now inline inhandleRequest()— making the control flow explicitprintUpgradePage()→renderUpgradePage()for naming consistency!self::$CLIguard (handleRequest()is only ever called fromindex.php)substr($path, -3) !== '.js'withstr_ends_with()$userSessiononce and reuses it; removes redundant re-fetcheshandleLogin(), which has important side effects to know aboutNotes
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 (bareexit(),header(),Server::get()calls, superglobal reads, etc) makes unit testing impractical without a larger refactor.TODO
/core/ajax/update.phprequest path bypass in this pass?Checklist
3. to review, feature component)stable32)AI (if applicable)