Skip to content

Commit 6cdaadb

Browse files
authored
Merge pull request #13712 from nextcloud/bugfix/noid/do-not-load-all-routes
Only load routes of the app which is requested
2 parents eed3a53 + 387cac4 commit 6cdaadb

File tree

5 files changed

+108
-27
lines changed

5 files changed

+108
-27
lines changed

lib/private/Route/Router.php

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function __construct(ILogger $logger) {
7373
$this->logger = $logger;
7474
$baseUrl = \OC::$WEBROOT;
7575
if (!(\OC::$server->getConfig()->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
76-
$baseUrl = \OC::$server->getURLGenerator()->linkTo('', 'index.php');
76+
$baseUrl .= '/index.php';
7777
}
7878
if (!\OC::$CLI && isset($_SERVER['REQUEST_METHOD'])) {
7979
$method = $_SERVER['REQUEST_METHOD'];
@@ -346,13 +346,27 @@ public function getGenerator() {
346346
public function generate($name,
347347
$parameters = [],
348348
$absolute = false) {
349+
$referenceType = UrlGenerator::ABSOLUTE_URL;
350+
if ($absolute === false) {
351+
$referenceType = UrlGenerator::ABSOLUTE_PATH;
352+
}
353+
$name = $this->fixLegacyRootName($name);
354+
if (strpos($name, '.') !== false) {
355+
list($appName, $other) = explode('.', $name, 3);
356+
// OCS routes are prefixed with "ocs."
357+
if ($appName === 'ocs') {
358+
$appName = $other;
359+
}
360+
$this->loadRoutes($appName);
361+
try {
362+
return $this->getGenerator()->generate($name, $parameters, $referenceType);
363+
} catch (RouteNotFoundException $e) {
364+
}
365+
}
366+
367+
// Fallback load all routes
349368
$this->loadRoutes();
350369
try {
351-
$referenceType = UrlGenerator::ABSOLUTE_URL;
352-
if ($absolute === false) {
353-
$referenceType = UrlGenerator::ABSOLUTE_PATH;
354-
}
355-
$name = $this->fixLegacyRootName($name);
356370
return $this->getGenerator()->generate($name, $parameters, $referenceType);
357371
} catch (RouteNotFoundException $e) {
358372
$this->logger->logException($e, ['level' => ILogger::INFO]);

lib/private/Server.php

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -644,16 +644,7 @@ public function __construct($webRoot, \OC\Config $config) {
644644
/** @deprecated 19.0.0 */
645645
$this->registerDeprecatedAlias('L10NFactory', IFactory::class);
646646

647-
$this->registerService(IURLGenerator::class, function (Server $c) {
648-
$config = $c->getConfig();
649-
$cacheFactory = $c->getMemCacheFactory();
650-
$request = $c->getRequest();
651-
return new \OC\URLGenerator(
652-
$config,
653-
$cacheFactory,
654-
$request
655-
);
656-
});
647+
$this->registerAlias(IURLGenerator::class, URLGenerator::class);
657648
/** @deprecated 19.0.0 */
658649
$this->registerDeprecatedAlias('URLGenerator', IURLGenerator::class);
659650

lib/private/URLGenerator.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
use OCP\IConfig;
4545
use OCP\IRequest;
4646
use OCP\IURLGenerator;
47+
use OCP\Route\IRouter;
4748
use RuntimeException;
4849

4950
/**
@@ -56,18 +57,17 @@ class URLGenerator implements IURLGenerator {
5657
private $cacheFactory;
5758
/** @var IRequest */
5859
private $request;
60+
/** @var IRouter*/
61+
private $router;
5962

60-
/**
61-
* @param IConfig $config
62-
* @param ICacheFactory $cacheFactory
63-
* @param IRequest $request
64-
*/
6563
public function __construct(IConfig $config,
6664
ICacheFactory $cacheFactory,
67-
IRequest $request) {
65+
IRequest $request,
66+
IRouter $router) {
6867
$this->config = $config;
6968
$this->cacheFactory = $cacheFactory;
7069
$this->request = $request;
70+
$this->router = $router;
7171
}
7272

7373
/**
@@ -80,8 +80,7 @@ public function __construct(IConfig $config,
8080
* Returns a url to the given route.
8181
*/
8282
public function linkToRoute(string $routeName, array $arguments = []): string {
83-
// TODO: mock router
84-
return \OC::$server->getRouter()->generate($routeName, $arguments);
83+
return $this->router->generate($routeName, $arguments);
8584
}
8685

8786
/**
@@ -97,7 +96,7 @@ public function linkToRouteAbsolute(string $routeName, array $arguments = []): s
9796
}
9897

9998
public function linkToOCSRouteAbsolute(string $routeName, array $arguments = []): string {
100-
$route = \OC::$server->getRouter()->generate('ocs.'.$routeName, $arguments, false);
99+
$route = $this->router->generate('ocs.'.$routeName, $arguments, false);
101100

102101
$indexPhpPos = strpos($route, '/index.php/');
103102
if ($indexPhpPos !== false) {

tests/lib/Route/RouterTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
/**
5+
* @copyright Copyright (c) 2019 Morris Jobke <hey@morrisjobke.de>
6+
*
7+
* @license GNU AGPL version 3 or any later version
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Affero General Public License as
11+
* published by the Free Software Foundation, either version 3 of the
12+
* License, or (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Affero General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Affero General Public License
20+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
namespace Test\Route;
25+
26+
use OC\Route\Router;
27+
use OCP\ILogger;
28+
use Test\TestCase;
29+
30+
/**
31+
* Class RouterTest
32+
*
33+
* @package Test\Route
34+
*/
35+
class RouterTest extends TestCase {
36+
public function testGenerateConsecutively(): void {
37+
/** @var ILogger $logger */
38+
$logger = $this->createMock(ILogger::class);
39+
$router = new Router($logger);
40+
41+
$this->assertEquals('/index.php/apps/files/', $router->generate('files.view.index'));
42+
43+
// the OCS route is the prefixed one for the AppFramework - see /ocs/v1.php for routing details
44+
$this->assertEquals('/index.php/ocsapp/apps/dav/api/v1/direct', $router->generate('ocs.dav.direct.getUrl'));
45+
46+
// special route name - should load all apps and then find the route
47+
$this->assertEquals('/index.php/apps/files/ajax/list.php', $router->generate('files_ajax_list'));
48+
49+
// test caching
50+
$this->assertEquals('/index.php/apps/files/', $router->generate('files.view.index'));
51+
}
52+
}

tests/lib/UrlGeneratorTest.php

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212
use OCP\IConfig;
1313
use OCP\IRequest;
1414
use OCP\IURLGenerator;
15+
use OCP\Route\IRouter;
1516

1617
/**
1718
* Class UrlGeneratorTest
19+
*
20+
* @package Test
1821
*/
1922
class UrlGeneratorTest extends \Test\TestCase {
2023

@@ -24,6 +27,8 @@ class UrlGeneratorTest extends \Test\TestCase {
2427
private $cacheFactory;
2528
/** @var \PHPUnit\Framework\MockObject\MockObject|IRequest */
2629
private $request;
30+
/** @var \PHPUnit\Framework\MockObject\MockObject|IRouter */
31+
private $router;
2732
/** @var IURLGenerator */
2833
private $urlGenerator;
2934
/** @var string */
@@ -34,10 +39,12 @@ protected function setUp(): void {
3439
$this->config = $this->createMock(IConfig::class);
3540
$this->cacheFactory = $this->createMock(ICacheFactory::class);
3641
$this->request = $this->createMock(IRequest::class);
42+
$this->router = $this->createMock(IRouter::class);
3743
$this->urlGenerator = new \OC\URLGenerator(
3844
$this->config,
3945
$this->cacheFactory,
40-
$this->request
46+
$this->request,
47+
$this->router
4148
);
4249
$this->originalWebRoot = \OC::$WEBROOT;
4350
}
@@ -84,14 +91,23 @@ public function testLinkToSubDir($app, $file, $args, $expectedResult) {
8491
public function testLinkToRouteAbsolute($route, $expected) {
8592
$this->mockBaseUrl();
8693
\OC::$WEBROOT = '/nextcloud';
94+
$this->router->expects($this->once())
95+
->method('generate')
96+
->willReturnCallback(function ($routeName, $parameters) {
97+
if ($routeName === 'core.Preview.getPreview') {
98+
return '/index.php/core/preview.png';
99+
} elseif ($routeName === 'cloud_federation_api.requesthandlercontroller.addShare') {
100+
return '/index.php/ocm/shares';
101+
}
102+
});
87103
$result = $this->urlGenerator->linkToRouteAbsolute($route);
88104
$this->assertEquals($expected, $result);
89105
}
90106

91107
public function provideRoutes() {
92108
return [
93-
['files_ajax_list', 'http://localhost/nextcloud/index.php/apps/files/ajax/list.php'],
94109
['core.Preview.getPreview', 'http://localhost/nextcloud/index.php/core/preview.png'],
110+
['cloud_federation_api.requesthandlercontroller.addShare', 'http://localhost/nextcloud/index.php/ocm/shares'],
95111
];
96112
}
97113

@@ -169,6 +185,15 @@ public function testGetBaseUrl() {
169185
public function testLinkToOCSRouteAbsolute(string $route, string $expected) {
170186
$this->mockBaseUrl();
171187
\OC::$WEBROOT = '/nextcloud';
188+
$this->router->expects($this->once())
189+
->method('generate')
190+
->willReturnCallback(function ($routeName, $parameters) {
191+
if ($routeName === 'ocs.core.OCS.getCapabilities') {
192+
return '/index.php/ocsapp/cloud/capabilities';
193+
} elseif ($routeName === 'ocs.core.WhatsNew.dismiss') {
194+
return '/index.php/ocsapp/core/whatsnew';
195+
}
196+
});
172197
$result = $this->urlGenerator->linkToOCSRouteAbsolute($route);
173198
$this->assertEquals($expected, $result);
174199
}

0 commit comments

Comments
 (0)