@@ -18,73 +18,73 @@ discard block |
||
18 | 18 | $nextcloudDir = dirname(__DIR__); |
19 | 19 | |
20 | 20 | class NextcloudNamespaceSkipVoter implements ClassNameImportSkipVoterInterface { |
21 | - private array $namespacePrefixes = [ |
|
22 | - 'OC', |
|
23 | - 'OCA', |
|
24 | - 'OCP', |
|
25 | - ]; |
|
26 | - private array $skippedClassNames = [ |
|
27 | - 'Backend', |
|
28 | - 'Connection', |
|
29 | - 'Exception', |
|
30 | - 'IManager', |
|
31 | - 'IProvider', |
|
32 | - 'Manager', |
|
33 | - 'Plugin', |
|
34 | - 'Provider', |
|
35 | - ]; |
|
36 | - public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool { |
|
37 | - if (in_array($fullyQualifiedObjectType->getShortName(), $this->skippedClassNames)) { |
|
38 | - // Skip common class names to avoid confusion |
|
39 | - return true; |
|
40 | - } |
|
41 | - foreach ($this->namespacePrefixes as $prefix) { |
|
42 | - if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) { |
|
43 | - // Import Nextcloud namespaces |
|
44 | - return false; |
|
45 | - } |
|
46 | - } |
|
47 | - // Skip everything else |
|
48 | - return true; |
|
49 | - } |
|
21 | + private array $namespacePrefixes = [ |
|
22 | + 'OC', |
|
23 | + 'OCA', |
|
24 | + 'OCP', |
|
25 | + ]; |
|
26 | + private array $skippedClassNames = [ |
|
27 | + 'Backend', |
|
28 | + 'Connection', |
|
29 | + 'Exception', |
|
30 | + 'IManager', |
|
31 | + 'IProvider', |
|
32 | + 'Manager', |
|
33 | + 'Plugin', |
|
34 | + 'Provider', |
|
35 | + ]; |
|
36 | + public function shouldSkip(File $file, FullyQualifiedObjectType $fullyQualifiedObjectType, Node $node) : bool { |
|
37 | + if (in_array($fullyQualifiedObjectType->getShortName(), $this->skippedClassNames)) { |
|
38 | + // Skip common class names to avoid confusion |
|
39 | + return true; |
|
40 | + } |
|
41 | + foreach ($this->namespacePrefixes as $prefix) { |
|
42 | + if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) { |
|
43 | + // Import Nextcloud namespaces |
|
44 | + return false; |
|
45 | + } |
|
46 | + } |
|
47 | + // Skip everything else |
|
48 | + return true; |
|
49 | + } |
|
50 | 50 | } |
51 | 51 | |
52 | 52 | $config = RectorConfig::configure() |
53 | - ->withPaths([ |
|
54 | - $nextcloudDir . '/apps', |
|
55 | - $nextcloudDir . '/core', |
|
56 | - $nextcloudDir . '/ocs', |
|
57 | - $nextcloudDir . '/ocs-provider', |
|
58 | - $nextcloudDir . '/console.php', |
|
59 | - $nextcloudDir . '/cron.php', |
|
60 | - $nextcloudDir . '/index.php', |
|
61 | - $nextcloudDir . '/occ', |
|
62 | - $nextcloudDir . '/public.php', |
|
63 | - $nextcloudDir . '/remote.php', |
|
64 | - $nextcloudDir . '/status.php', |
|
65 | - $nextcloudDir . '/version.php', |
|
66 | - // $nextcloudDir . '/config', |
|
67 | - // $nextcloudDir . '/lib', |
|
68 | - // $nextcloudDir . '/tests', |
|
69 | - // $nextcloudDir . '/themes', |
|
70 | - ]) |
|
71 | - ->withSkip([ |
|
72 | - $nextcloudDir . '/apps/*/3rdparty/*', |
|
73 | - $nextcloudDir . '/apps/*/build/stubs/*', |
|
74 | - $nextcloudDir . '/apps/*/composer/*', |
|
75 | - $nextcloudDir . '/apps/*/config/*', |
|
76 | - ]) |
|
77 | - // uncomment to reach your current PHP version |
|
78 | - // ->withPhpSets() |
|
79 | - ->withImportNames(importShortClasses:false) |
|
80 | - ->withTypeCoverageLevel(0) |
|
81 | - ->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [ |
|
82 | - 'inline_public' => true, |
|
83 | - 'rename_property' => true, |
|
84 | - ]) |
|
85 | - ->withSets([ |
|
86 | - NextcloudSets::NEXTCLOUD_25, |
|
87 | - ]); |
|
53 | + ->withPaths([ |
|
54 | + $nextcloudDir . '/apps', |
|
55 | + $nextcloudDir . '/core', |
|
56 | + $nextcloudDir . '/ocs', |
|
57 | + $nextcloudDir . '/ocs-provider', |
|
58 | + $nextcloudDir . '/console.php', |
|
59 | + $nextcloudDir . '/cron.php', |
|
60 | + $nextcloudDir . '/index.php', |
|
61 | + $nextcloudDir . '/occ', |
|
62 | + $nextcloudDir . '/public.php', |
|
63 | + $nextcloudDir . '/remote.php', |
|
64 | + $nextcloudDir . '/status.php', |
|
65 | + $nextcloudDir . '/version.php', |
|
66 | + // $nextcloudDir . '/config', |
|
67 | + // $nextcloudDir . '/lib', |
|
68 | + // $nextcloudDir . '/tests', |
|
69 | + // $nextcloudDir . '/themes', |
|
70 | + ]) |
|
71 | + ->withSkip([ |
|
72 | + $nextcloudDir . '/apps/*/3rdparty/*', |
|
73 | + $nextcloudDir . '/apps/*/build/stubs/*', |
|
74 | + $nextcloudDir . '/apps/*/composer/*', |
|
75 | + $nextcloudDir . '/apps/*/config/*', |
|
76 | + ]) |
|
77 | + // uncomment to reach your current PHP version |
|
78 | + // ->withPhpSets() |
|
79 | + ->withImportNames(importShortClasses:false) |
|
80 | + ->withTypeCoverageLevel(0) |
|
81 | + ->withConfiguredRule(ClassPropertyAssignToConstructorPromotionRector::class, [ |
|
82 | + 'inline_public' => true, |
|
83 | + 'rename_property' => true, |
|
84 | + ]) |
|
85 | + ->withSets([ |
|
86 | + NextcloudSets::NEXTCLOUD_25, |
|
87 | + ]); |
|
88 | 88 | |
89 | 89 | $config->registerService(NextcloudNamespaceSkipVoter::class, tag:ClassNameImportSkipVoterInterface::class); |
90 | 90 | |
@@ -96,11 +96,11 @@ discard block |
||
96 | 96 | $ignoredEntries = array_values($ignoredEntries); |
97 | 97 | |
98 | 98 | foreach ($ignoredEntries as $ignoredEntry) { |
99 | - if (str_ends_with($ignoredEntry, '/')) { |
|
100 | - $config->withSkip([$ignoredEntry . '*']); |
|
101 | - } else { |
|
102 | - $config->withSkip([$ignoredEntry . '/*']); |
|
103 | - } |
|
99 | + if (str_ends_with($ignoredEntry, '/')) { |
|
100 | + $config->withSkip([$ignoredEntry . '*']); |
|
101 | + } else { |
|
102 | + $config->withSkip([$ignoredEntry . '/*']); |
|
103 | + } |
|
104 | 104 | } |
105 | 105 | |
106 | 106 | return $config; |
@@ -39,7 +39,7 @@ discard block |
||
39 | 39 | return true; |
40 | 40 | } |
41 | 41 | foreach ($this->namespacePrefixes as $prefix) { |
42 | - if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix . '\\')) { |
|
42 | + if (str_starts_with($fullyQualifiedObjectType->getClassName(), $prefix.'\\')) { |
|
43 | 43 | // Import Nextcloud namespaces |
44 | 44 | return false; |
45 | 45 | } |
@@ -51,28 +51,28 @@ discard block |
||
51 | 51 | |
52 | 52 | $config = RectorConfig::configure() |
53 | 53 | ->withPaths([ |
54 | - $nextcloudDir . '/apps', |
|
55 | - $nextcloudDir . '/core', |
|
56 | - $nextcloudDir . '/ocs', |
|
57 | - $nextcloudDir . '/ocs-provider', |
|
58 | - $nextcloudDir . '/console.php', |
|
59 | - $nextcloudDir . '/cron.php', |
|
60 | - $nextcloudDir . '/index.php', |
|
61 | - $nextcloudDir . '/occ', |
|
62 | - $nextcloudDir . '/public.php', |
|
63 | - $nextcloudDir . '/remote.php', |
|
64 | - $nextcloudDir . '/status.php', |
|
65 | - $nextcloudDir . '/version.php', |
|
54 | + $nextcloudDir.'/apps', |
|
55 | + $nextcloudDir.'/core', |
|
56 | + $nextcloudDir.'/ocs', |
|
57 | + $nextcloudDir.'/ocs-provider', |
|
58 | + $nextcloudDir.'/console.php', |
|
59 | + $nextcloudDir.'/cron.php', |
|
60 | + $nextcloudDir.'/index.php', |
|
61 | + $nextcloudDir.'/occ', |
|
62 | + $nextcloudDir.'/public.php', |
|
63 | + $nextcloudDir.'/remote.php', |
|
64 | + $nextcloudDir.'/status.php', |
|
65 | + $nextcloudDir.'/version.php', |
|
66 | 66 | // $nextcloudDir . '/config', |
67 | 67 | // $nextcloudDir . '/lib', |
68 | 68 | // $nextcloudDir . '/tests', |
69 | 69 | // $nextcloudDir . '/themes', |
70 | 70 | ]) |
71 | 71 | ->withSkip([ |
72 | - $nextcloudDir . '/apps/*/3rdparty/*', |
|
73 | - $nextcloudDir . '/apps/*/build/stubs/*', |
|
74 | - $nextcloudDir . '/apps/*/composer/*', |
|
75 | - $nextcloudDir . '/apps/*/config/*', |
|
72 | + $nextcloudDir.'/apps/*/3rdparty/*', |
|
73 | + $nextcloudDir.'/apps/*/build/stubs/*', |
|
74 | + $nextcloudDir.'/apps/*/composer/*', |
|
75 | + $nextcloudDir.'/apps/*/config/*', |
|
76 | 76 | ]) |
77 | 77 | // uncomment to reach your current PHP version |
78 | 78 | // ->withPhpSets() |
@@ -89,7 +89,7 @@ discard block |
||
89 | 89 | $config->registerService(NextcloudNamespaceSkipVoter::class, tag:ClassNameImportSkipVoterInterface::class); |
90 | 90 | |
91 | 91 | /* Ignore all files ignored by git */ |
92 | -$ignoredEntries = shell_exec('git status --porcelain --ignored ' . escapeshellarg($nextcloudDir)); |
|
92 | +$ignoredEntries = shell_exec('git status --porcelain --ignored '.escapeshellarg($nextcloudDir)); |
|
93 | 93 | $ignoredEntries = explode("\n", $ignoredEntries); |
94 | 94 | $ignoredEntries = array_filter($ignoredEntries, static fn (string $line) => str_starts_with($line, '!! ')); |
95 | 95 | $ignoredEntries = array_map(static fn (string $line) => substr($line, 3), $ignoredEntries); |
@@ -97,9 +97,9 @@ discard block |
||
97 | 97 | |
98 | 98 | foreach ($ignoredEntries as $ignoredEntry) { |
99 | 99 | if (str_ends_with($ignoredEntry, '/')) { |
100 | - $config->withSkip([$ignoredEntry . '*']); |
|
100 | + $config->withSkip([$ignoredEntry.'*']); |
|
101 | 101 | } else { |
102 | - $config->withSkip([$ignoredEntry . '/*']); |
|
102 | + $config->withSkip([$ignoredEntry.'/*']); |
|
103 | 103 | } |
104 | 104 | } |
105 | 105 |
@@ -28,47 +28,47 @@ discard block |
||
28 | 28 | } |
29 | 29 | |
30 | 30 | function handleException(Exception|Error $e): void { |
31 | - try { |
|
32 | - $request = \OCP\Server::get(IRequest::class); |
|
33 | - // in case the request content type is text/xml - we assume it's a WebDAV request |
|
34 | - $isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml'); |
|
35 | - if ($isXmlContentType === 0) { |
|
36 | - // fire up a simple server to properly process the exception |
|
37 | - $server = new Server(); |
|
38 | - if (!($e instanceof RemoteException)) { |
|
39 | - // we shall not log on RemoteException |
|
40 | - $server->addPlugin(new ExceptionLoggerPlugin('webdav', \OCP\Server::get(LoggerInterface::class))); |
|
41 | - } |
|
42 | - $server->on('beforeMethod:*', function () use ($e): void { |
|
43 | - if ($e instanceof RemoteException) { |
|
44 | - switch ($e->getCode()) { |
|
45 | - case 503: |
|
46 | - throw new ServiceUnavailable($e->getMessage()); |
|
47 | - case 404: |
|
48 | - throw new \Sabre\DAV\Exception\NotFound($e->getMessage()); |
|
49 | - } |
|
50 | - } |
|
51 | - $class = get_class($e); |
|
52 | - $msg = $e->getMessage(); |
|
53 | - throw new ServiceUnavailable("$class: $msg"); |
|
54 | - }); |
|
55 | - $server->exec(); |
|
56 | - } else { |
|
57 | - $statusCode = 500; |
|
58 | - if ($e instanceof ServiceUnavailableException) { |
|
59 | - $statusCode = 503; |
|
60 | - } |
|
61 | - if ($e instanceof RemoteException) { |
|
62 | - // we shall not log on RemoteException |
|
63 | - \OCP\Server::get(ITemplateManager::class)->printErrorPage($e->getMessage(), '', $e->getCode()); |
|
64 | - } else { |
|
65 | - \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['app' => 'remote','exception' => $e]); |
|
66 | - \OCP\Server::get(ITemplateManager::class)->printExceptionErrorPage($e, $statusCode); |
|
67 | - } |
|
68 | - } |
|
69 | - } catch (\Exception $e) { |
|
70 | - \OCP\Server::get(ITemplateManager::class)->printExceptionErrorPage($e, 500); |
|
71 | - } |
|
31 | + try { |
|
32 | + $request = \OCP\Server::get(IRequest::class); |
|
33 | + // in case the request content type is text/xml - we assume it's a WebDAV request |
|
34 | + $isXmlContentType = strpos($request->getHeader('Content-Type'), 'text/xml'); |
|
35 | + if ($isXmlContentType === 0) { |
|
36 | + // fire up a simple server to properly process the exception |
|
37 | + $server = new Server(); |
|
38 | + if (!($e instanceof RemoteException)) { |
|
39 | + // we shall not log on RemoteException |
|
40 | + $server->addPlugin(new ExceptionLoggerPlugin('webdav', \OCP\Server::get(LoggerInterface::class))); |
|
41 | + } |
|
42 | + $server->on('beforeMethod:*', function () use ($e): void { |
|
43 | + if ($e instanceof RemoteException) { |
|
44 | + switch ($e->getCode()) { |
|
45 | + case 503: |
|
46 | + throw new ServiceUnavailable($e->getMessage()); |
|
47 | + case 404: |
|
48 | + throw new \Sabre\DAV\Exception\NotFound($e->getMessage()); |
|
49 | + } |
|
50 | + } |
|
51 | + $class = get_class($e); |
|
52 | + $msg = $e->getMessage(); |
|
53 | + throw new ServiceUnavailable("$class: $msg"); |
|
54 | + }); |
|
55 | + $server->exec(); |
|
56 | + } else { |
|
57 | + $statusCode = 500; |
|
58 | + if ($e instanceof ServiceUnavailableException) { |
|
59 | + $statusCode = 503; |
|
60 | + } |
|
61 | + if ($e instanceof RemoteException) { |
|
62 | + // we shall not log on RemoteException |
|
63 | + \OCP\Server::get(ITemplateManager::class)->printErrorPage($e->getMessage(), '', $e->getCode()); |
|
64 | + } else { |
|
65 | + \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['app' => 'remote','exception' => $e]); |
|
66 | + \OCP\Server::get(ITemplateManager::class)->printExceptionErrorPage($e, $statusCode); |
|
67 | + } |
|
68 | + } |
|
69 | + } catch (\Exception $e) { |
|
70 | + \OCP\Server::get(ITemplateManager::class)->printExceptionErrorPage($e, 500); |
|
71 | + } |
|
72 | 72 | } |
73 | 73 | |
74 | 74 | /** |
@@ -76,81 +76,81 @@ discard block |
||
76 | 76 | * @return string |
77 | 77 | */ |
78 | 78 | function resolveService($service) { |
79 | - $services = [ |
|
80 | - 'webdav' => 'dav/appinfo/v1/webdav.php', |
|
81 | - 'dav' => 'dav/appinfo/v2/remote.php', |
|
82 | - 'caldav' => 'dav/appinfo/v1/caldav.php', |
|
83 | - 'calendar' => 'dav/appinfo/v1/caldav.php', |
|
84 | - 'carddav' => 'dav/appinfo/v1/carddav.php', |
|
85 | - 'contacts' => 'dav/appinfo/v1/carddav.php', |
|
86 | - 'files' => 'dav/appinfo/v1/webdav.php', |
|
87 | - 'direct' => 'dav/appinfo/v2/direct.php', |
|
88 | - ]; |
|
89 | - if (isset($services[$service])) { |
|
90 | - return $services[$service]; |
|
91 | - } |
|
92 | - |
|
93 | - return \OCP\Server::get(IConfig::class)->getAppValue('core', 'remote_' . $service); |
|
79 | + $services = [ |
|
80 | + 'webdav' => 'dav/appinfo/v1/webdav.php', |
|
81 | + 'dav' => 'dav/appinfo/v2/remote.php', |
|
82 | + 'caldav' => 'dav/appinfo/v1/caldav.php', |
|
83 | + 'calendar' => 'dav/appinfo/v1/caldav.php', |
|
84 | + 'carddav' => 'dav/appinfo/v1/carddav.php', |
|
85 | + 'contacts' => 'dav/appinfo/v1/carddav.php', |
|
86 | + 'files' => 'dav/appinfo/v1/webdav.php', |
|
87 | + 'direct' => 'dav/appinfo/v2/direct.php', |
|
88 | + ]; |
|
89 | + if (isset($services[$service])) { |
|
90 | + return $services[$service]; |
|
91 | + } |
|
92 | + |
|
93 | + return \OCP\Server::get(IConfig::class)->getAppValue('core', 'remote_' . $service); |
|
94 | 94 | } |
95 | 95 | |
96 | 96 | try { |
97 | - require_once __DIR__ . '/lib/base.php'; |
|
98 | - |
|
99 | - // All resources served via the DAV endpoint should have the strictest possible |
|
100 | - // policy. Exempted from this is the SabreDAV browser plugin which overwrites |
|
101 | - // this policy with a softer one if debug mode is enabled. |
|
102 | - header("Content-Security-Policy: default-src 'none';"); |
|
103 | - |
|
104 | - if (Util::needUpgrade()) { |
|
105 | - // since the behavior of apps or remotes are unpredictable during |
|
106 | - // an upgrade, return a 503 directly |
|
107 | - throw new RemoteException('Service unavailable', 503); |
|
108 | - } |
|
109 | - |
|
110 | - $request = \OCP\Server::get(IRequest::class); |
|
111 | - $pathInfo = $request->getPathInfo(); |
|
112 | - if ($pathInfo === false || $pathInfo === '') { |
|
113 | - throw new RemoteException('Path not found', 404); |
|
114 | - } |
|
115 | - if (!$pos = strpos($pathInfo, '/', 1)) { |
|
116 | - $pos = strlen($pathInfo); |
|
117 | - } |
|
118 | - $service = substr($pathInfo, 1, $pos - 1); |
|
119 | - |
|
120 | - $file = resolveService($service); |
|
121 | - |
|
122 | - if (is_null($file)) { |
|
123 | - throw new RemoteException('Path not found', 404); |
|
124 | - } |
|
125 | - |
|
126 | - $file = ltrim($file, '/'); |
|
127 | - |
|
128 | - $parts = explode('/', $file, 2); |
|
129 | - $app = $parts[0]; |
|
130 | - |
|
131 | - // Load all required applications |
|
132 | - \OC::$REQUESTEDAPP = $app; |
|
133 | - $appManager = \OCP\Server::get(IAppManager::class); |
|
134 | - $appManager->loadApps(['authentication']); |
|
135 | - $appManager->loadApps(['extended_authentication']); |
|
136 | - $appManager->loadApps(['filesystem', 'logging']); |
|
137 | - |
|
138 | - switch ($app) { |
|
139 | - case 'core': |
|
140 | - $file = OC::$SERVERROOT . '/' . $file; |
|
141 | - break; |
|
142 | - default: |
|
143 | - if (!$appManager->isEnabledForUser($app)) { |
|
144 | - throw new RemoteException('App not installed: ' . $app); |
|
145 | - } |
|
146 | - $appManager->loadApp($app); |
|
147 | - $file = $appManager->getAppPath($app) . '/' . ($parts[1] ?? ''); |
|
148 | - break; |
|
149 | - } |
|
150 | - $baseuri = OC::$WEBROOT . '/remote.php/' . $service . '/'; |
|
151 | - require_once $file; |
|
97 | + require_once __DIR__ . '/lib/base.php'; |
|
98 | + |
|
99 | + // All resources served via the DAV endpoint should have the strictest possible |
|
100 | + // policy. Exempted from this is the SabreDAV browser plugin which overwrites |
|
101 | + // this policy with a softer one if debug mode is enabled. |
|
102 | + header("Content-Security-Policy: default-src 'none';"); |
|
103 | + |
|
104 | + if (Util::needUpgrade()) { |
|
105 | + // since the behavior of apps or remotes are unpredictable during |
|
106 | + // an upgrade, return a 503 directly |
|
107 | + throw new RemoteException('Service unavailable', 503); |
|
108 | + } |
|
109 | + |
|
110 | + $request = \OCP\Server::get(IRequest::class); |
|
111 | + $pathInfo = $request->getPathInfo(); |
|
112 | + if ($pathInfo === false || $pathInfo === '') { |
|
113 | + throw new RemoteException('Path not found', 404); |
|
114 | + } |
|
115 | + if (!$pos = strpos($pathInfo, '/', 1)) { |
|
116 | + $pos = strlen($pathInfo); |
|
117 | + } |
|
118 | + $service = substr($pathInfo, 1, $pos - 1); |
|
119 | + |
|
120 | + $file = resolveService($service); |
|
121 | + |
|
122 | + if (is_null($file)) { |
|
123 | + throw new RemoteException('Path not found', 404); |
|
124 | + } |
|
125 | + |
|
126 | + $file = ltrim($file, '/'); |
|
127 | + |
|
128 | + $parts = explode('/', $file, 2); |
|
129 | + $app = $parts[0]; |
|
130 | + |
|
131 | + // Load all required applications |
|
132 | + \OC::$REQUESTEDAPP = $app; |
|
133 | + $appManager = \OCP\Server::get(IAppManager::class); |
|
134 | + $appManager->loadApps(['authentication']); |
|
135 | + $appManager->loadApps(['extended_authentication']); |
|
136 | + $appManager->loadApps(['filesystem', 'logging']); |
|
137 | + |
|
138 | + switch ($app) { |
|
139 | + case 'core': |
|
140 | + $file = OC::$SERVERROOT . '/' . $file; |
|
141 | + break; |
|
142 | + default: |
|
143 | + if (!$appManager->isEnabledForUser($app)) { |
|
144 | + throw new RemoteException('App not installed: ' . $app); |
|
145 | + } |
|
146 | + $appManager->loadApp($app); |
|
147 | + $file = $appManager->getAppPath($app) . '/' . ($parts[1] ?? ''); |
|
148 | + break; |
|
149 | + } |
|
150 | + $baseuri = OC::$WEBROOT . '/remote.php/' . $service . '/'; |
|
151 | + require_once $file; |
|
152 | 152 | } catch (Exception $ex) { |
153 | - handleException($ex); |
|
153 | + handleException($ex); |
|
154 | 154 | } catch (Error $e) { |
155 | - handleException($e); |
|
155 | + handleException($e); |
|
156 | 156 | } |
@@ -9,7 +9,7 @@ discard block |
||
9 | 9 | * SPDX-FileCopyrightText: 2016 ownCloud, Inc. |
10 | 10 | * SPDX-License-Identifier: AGPL-3.0-only |
11 | 11 | */ |
12 | -require_once __DIR__ . '/lib/versioncheck.php'; |
|
12 | +require_once __DIR__.'/lib/versioncheck.php'; |
|
13 | 13 | |
14 | 14 | use OCA\DAV\Connector\Sabre\ExceptionLoggerPlugin; |
15 | 15 | use OCP\App\IAppManager; |
@@ -27,7 +27,7 @@ discard block |
||
27 | 27 | class RemoteException extends \Exception { |
28 | 28 | } |
29 | 29 | |
30 | -function handleException(Exception|Error $e): void { |
|
30 | +function handleException(Exception | Error $e): void { |
|
31 | 31 | try { |
32 | 32 | $request = \OCP\Server::get(IRequest::class); |
33 | 33 | // in case the request content type is text/xml - we assume it's a WebDAV request |
@@ -39,7 +39,7 @@ discard block |
||
39 | 39 | // we shall not log on RemoteException |
40 | 40 | $server->addPlugin(new ExceptionLoggerPlugin('webdav', \OCP\Server::get(LoggerInterface::class))); |
41 | 41 | } |
42 | - $server->on('beforeMethod:*', function () use ($e): void { |
|
42 | + $server->on('beforeMethod:*', function() use ($e): void { |
|
43 | 43 | if ($e instanceof RemoteException) { |
44 | 44 | switch ($e->getCode()) { |
45 | 45 | case 503: |
@@ -62,7 +62,7 @@ discard block |
||
62 | 62 | // we shall not log on RemoteException |
63 | 63 | \OCP\Server::get(ITemplateManager::class)->printErrorPage($e->getMessage(), '', $e->getCode()); |
64 | 64 | } else { |
65 | - \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['app' => 'remote','exception' => $e]); |
|
65 | + \OCP\Server::get(LoggerInterface::class)->error($e->getMessage(), ['app' => 'remote', 'exception' => $e]); |
|
66 | 66 | \OCP\Server::get(ITemplateManager::class)->printExceptionErrorPage($e, $statusCode); |
67 | 67 | } |
68 | 68 | } |
@@ -90,11 +90,11 @@ discard block |
||
90 | 90 | return $services[$service]; |
91 | 91 | } |
92 | 92 | |
93 | - return \OCP\Server::get(IConfig::class)->getAppValue('core', 'remote_' . $service); |
|
93 | + return \OCP\Server::get(IConfig::class)->getAppValue('core', 'remote_'.$service); |
|
94 | 94 | } |
95 | 95 | |
96 | 96 | try { |
97 | - require_once __DIR__ . '/lib/base.php'; |
|
97 | + require_once __DIR__.'/lib/base.php'; |
|
98 | 98 | |
99 | 99 | // All resources served via the DAV endpoint should have the strictest possible |
100 | 100 | // policy. Exempted from this is the SabreDAV browser plugin which overwrites |
@@ -137,17 +137,17 @@ discard block |
||
137 | 137 | |
138 | 138 | switch ($app) { |
139 | 139 | case 'core': |
140 | - $file = OC::$SERVERROOT . '/' . $file; |
|
140 | + $file = OC::$SERVERROOT.'/'.$file; |
|
141 | 141 | break; |
142 | 142 | default: |
143 | 143 | if (!$appManager->isEnabledForUser($app)) { |
144 | - throw new RemoteException('App not installed: ' . $app); |
|
144 | + throw new RemoteException('App not installed: '.$app); |
|
145 | 145 | } |
146 | 146 | $appManager->loadApp($app); |
147 | - $file = $appManager->getAppPath($app) . '/' . ($parts[1] ?? ''); |
|
147 | + $file = $appManager->getAppPath($app).'/'.($parts[1] ?? ''); |
|
148 | 148 | break; |
149 | 149 | } |
150 | - $baseuri = OC::$WEBROOT . '/remote.php/' . $service . '/'; |
|
150 | + $baseuri = OC::$WEBROOT.'/remote.php/'.$service.'/'; |
|
151 | 151 | require_once $file; |
152 | 152 | } catch (Exception $ex) { |
153 | 153 | handleException($ex); |
@@ -21,83 +21,83 @@ |
||
21 | 21 | use Psr\Log\LoggerInterface; |
22 | 22 | |
23 | 23 | function resolveService(string $service): string { |
24 | - $services = [ |
|
25 | - 'webdav' => 'dav/appinfo/v1/publicwebdav.php', |
|
26 | - 'dav' => 'dav/appinfo/v2/publicremote.php', |
|
27 | - ]; |
|
28 | - if (isset($services[$service])) { |
|
29 | - return $services[$service]; |
|
30 | - } |
|
31 | - |
|
32 | - return Server::get(IConfig::class)->getAppValue('core', 'remote_' . $service); |
|
24 | + $services = [ |
|
25 | + 'webdav' => 'dav/appinfo/v1/publicwebdav.php', |
|
26 | + 'dav' => 'dav/appinfo/v2/publicremote.php', |
|
27 | + ]; |
|
28 | + if (isset($services[$service])) { |
|
29 | + return $services[$service]; |
|
30 | + } |
|
31 | + |
|
32 | + return Server::get(IConfig::class)->getAppValue('core', 'remote_' . $service); |
|
33 | 33 | } |
34 | 34 | |
35 | 35 | try { |
36 | - require_once __DIR__ . '/lib/base.php'; |
|
37 | - |
|
38 | - // All resources served via the DAV endpoint should have the strictest possible |
|
39 | - // policy. Exempted from this is the SabreDAV browser plugin which overwrites |
|
40 | - // this policy with a softer one if debug mode is enabled. |
|
41 | - header("Content-Security-Policy: default-src 'none';"); |
|
42 | - |
|
43 | - // Check if Nextcloud is in maintenance mode |
|
44 | - if (Util::needUpgrade()) { |
|
45 | - // since the behavior of apps or remotes are unpredictable during |
|
46 | - // an upgrade, return a 503 directly |
|
47 | - throw new \Exception('Service unavailable', 503); |
|
48 | - } |
|
49 | - |
|
50 | - $request = Server::get(IRequest::class); |
|
51 | - $pathInfo = $request->getPathInfo(); |
|
52 | - if ($pathInfo === false || $pathInfo === '') { |
|
53 | - throw new \Exception('Path not found', 404); |
|
54 | - } |
|
55 | - |
|
56 | - // Extract the service from the path |
|
57 | - if (!$pos = strpos($pathInfo, '/', 1)) { |
|
58 | - $pos = strlen($pathInfo); |
|
59 | - } |
|
60 | - $service = substr($pathInfo, 1, $pos - 1); |
|
61 | - |
|
62 | - // Resolve the service to a file |
|
63 | - $file = resolveService($service); |
|
64 | - if (!$file) { |
|
65 | - throw new \Exception('Path not found', 404); |
|
66 | - } |
|
67 | - |
|
68 | - // Extract the app from the service file |
|
69 | - $file = ltrim($file, '/'); |
|
70 | - $parts = explode('/', $file, 2); |
|
71 | - $app = $parts[0]; |
|
72 | - |
|
73 | - // Load all required applications |
|
74 | - $appManager = Server::get(IAppManager::class); |
|
75 | - \OC::$REQUESTEDAPP = $app; |
|
76 | - $appManager->loadApps(['authentication']); |
|
77 | - $appManager->loadApps(['extended_authentication']); |
|
78 | - $appManager->loadApps(['filesystem', 'logging']); |
|
79 | - |
|
80 | - // Check if the app is enabled |
|
81 | - if (!$appManager->isEnabledForUser($app)) { |
|
82 | - throw new \Exception('App not installed: ' . $app); |
|
83 | - } |
|
84 | - |
|
85 | - // Load the app |
|
86 | - $appManager->loadApp($app); |
|
87 | - OC_User::setIncognitoMode(true); |
|
88 | - |
|
89 | - $baseuri = OC::$WEBROOT . '/public.php/' . $service . '/'; |
|
90 | - require_once $file; |
|
36 | + require_once __DIR__ . '/lib/base.php'; |
|
37 | + |
|
38 | + // All resources served via the DAV endpoint should have the strictest possible |
|
39 | + // policy. Exempted from this is the SabreDAV browser plugin which overwrites |
|
40 | + // this policy with a softer one if debug mode is enabled. |
|
41 | + header("Content-Security-Policy: default-src 'none';"); |
|
42 | + |
|
43 | + // Check if Nextcloud is in maintenance mode |
|
44 | + if (Util::needUpgrade()) { |
|
45 | + // since the behavior of apps or remotes are unpredictable during |
|
46 | + // an upgrade, return a 503 directly |
|
47 | + throw new \Exception('Service unavailable', 503); |
|
48 | + } |
|
49 | + |
|
50 | + $request = Server::get(IRequest::class); |
|
51 | + $pathInfo = $request->getPathInfo(); |
|
52 | + if ($pathInfo === false || $pathInfo === '') { |
|
53 | + throw new \Exception('Path not found', 404); |
|
54 | + } |
|
55 | + |
|
56 | + // Extract the service from the path |
|
57 | + if (!$pos = strpos($pathInfo, '/', 1)) { |
|
58 | + $pos = strlen($pathInfo); |
|
59 | + } |
|
60 | + $service = substr($pathInfo, 1, $pos - 1); |
|
61 | + |
|
62 | + // Resolve the service to a file |
|
63 | + $file = resolveService($service); |
|
64 | + if (!$file) { |
|
65 | + throw new \Exception('Path not found', 404); |
|
66 | + } |
|
67 | + |
|
68 | + // Extract the app from the service file |
|
69 | + $file = ltrim($file, '/'); |
|
70 | + $parts = explode('/', $file, 2); |
|
71 | + $app = $parts[0]; |
|
72 | + |
|
73 | + // Load all required applications |
|
74 | + $appManager = Server::get(IAppManager::class); |
|
75 | + \OC::$REQUESTEDAPP = $app; |
|
76 | + $appManager->loadApps(['authentication']); |
|
77 | + $appManager->loadApps(['extended_authentication']); |
|
78 | + $appManager->loadApps(['filesystem', 'logging']); |
|
79 | + |
|
80 | + // Check if the app is enabled |
|
81 | + if (!$appManager->isEnabledForUser($app)) { |
|
82 | + throw new \Exception('App not installed: ' . $app); |
|
83 | + } |
|
84 | + |
|
85 | + // Load the app |
|
86 | + $appManager->loadApp($app); |
|
87 | + OC_User::setIncognitoMode(true); |
|
88 | + |
|
89 | + $baseuri = OC::$WEBROOT . '/public.php/' . $service . '/'; |
|
90 | + require_once $file; |
|
91 | 91 | } catch (Exception $ex) { |
92 | - $status = 500; |
|
93 | - if ($ex instanceof ServiceUnavailableException) { |
|
94 | - $status = 503; |
|
95 | - } |
|
96 | - //show the user a detailed error page |
|
97 | - Server::get(LoggerInterface::class)->error($ex->getMessage(), ['app' => 'public', 'exception' => $ex]); |
|
98 | - Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, $status); |
|
92 | + $status = 500; |
|
93 | + if ($ex instanceof ServiceUnavailableException) { |
|
94 | + $status = 503; |
|
95 | + } |
|
96 | + //show the user a detailed error page |
|
97 | + Server::get(LoggerInterface::class)->error($ex->getMessage(), ['app' => 'public', 'exception' => $ex]); |
|
98 | + Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, $status); |
|
99 | 99 | } catch (Error $ex) { |
100 | - //show the user a detailed error page |
|
101 | - Server::get(LoggerInterface::class)->error($ex->getMessage(), ['app' => 'public', 'exception' => $ex]); |
|
102 | - Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, 500); |
|
100 | + //show the user a detailed error page |
|
101 | + Server::get(LoggerInterface::class)->error($ex->getMessage(), ['app' => 'public', 'exception' => $ex]); |
|
102 | + Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, 500); |
|
103 | 103 | } |
@@ -26,10 +26,10 @@ discard block |
||
26 | 26 | use Psr\Log\LoggerInterface; |
27 | 27 | |
28 | 28 | try { |
29 | - require_once __DIR__ . '/lib/base.php'; |
|
29 | + require_once __DIR__ . '/lib/base.php'; |
|
30 | 30 | |
31 | - if (isset($argv[1]) && ($argv[1] === '-h' || $argv[1] === '--help')) { |
|
32 | - echo 'Description: |
|
31 | + if (isset($argv[1]) && ($argv[1] === '-h' || $argv[1] === '--help')) { |
|
32 | + echo 'Description: |
|
33 | 33 | Run the background job routine |
34 | 34 | |
35 | 35 | Usage: |
@@ -42,224 +42,224 @@ discard block |
||
42 | 42 | Options: |
43 | 43 | -h, --help Display this help message |
44 | 44 | -v, --verbose Output more information' . PHP_EOL; |
45 | - exit(0); |
|
46 | - } |
|
47 | - |
|
48 | - if (Util::needUpgrade()) { |
|
49 | - Server::get(LoggerInterface::class)->debug('Update required, skipping cron', ['app' => 'cron']); |
|
50 | - exit; |
|
51 | - } |
|
52 | - |
|
53 | - $config = Server::get(IConfig::class); |
|
54 | - |
|
55 | - if ($config->getSystemValueBool('maintenance', false)) { |
|
56 | - Server::get(LoggerInterface::class)->debug('We are in maintenance mode, skipping cron', ['app' => 'cron']); |
|
57 | - exit; |
|
58 | - } |
|
59 | - |
|
60 | - // Don't do anything if Nextcloud has not been installed |
|
61 | - if (!$config->getSystemValueBool('installed', false)) { |
|
62 | - exit(0); |
|
63 | - } |
|
64 | - |
|
65 | - // load all apps to get all api routes properly setup |
|
66 | - Server::get(IAppManager::class)->loadApps(); |
|
67 | - Server::get(ISession::class)->close(); |
|
68 | - |
|
69 | - $verbose = isset($argv[1]) && ($argv[1] === '-v' || $argv[1] === '--verbose'); |
|
70 | - |
|
71 | - // initialize a dummy memory session |
|
72 | - $session = new Memory(); |
|
73 | - $cryptoWrapper = Server::get(CryptoWrapper::class); |
|
74 | - $session = $cryptoWrapper->wrapSession($session); |
|
75 | - \OC::$server->setSession($session); |
|
76 | - |
|
77 | - $logger = Server::get(LoggerInterface::class); |
|
78 | - $appConfig = Server::get(IAppConfig::class); |
|
79 | - $tempManager = Server::get(ITempManager::class); |
|
80 | - |
|
81 | - $tempManager->cleanOld(); |
|
82 | - |
|
83 | - // Exit if background jobs are disabled! |
|
84 | - $appMode = $appConfig->getValueString('core', 'backgroundjobs_mode', 'ajax'); |
|
85 | - if ($appMode === 'none') { |
|
86 | - if (OC::$CLI) { |
|
87 | - echo 'Background Jobs are disabled!' . PHP_EOL; |
|
88 | - } else { |
|
89 | - OC_JSON::error(['data' => ['message' => 'Background jobs disabled!']]); |
|
90 | - } |
|
91 | - exit(1); |
|
92 | - } |
|
93 | - |
|
94 | - if (OC::$CLI) { |
|
95 | - // set to run indefinitely if needed |
|
96 | - if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { |
|
97 | - @set_time_limit(0); |
|
98 | - } |
|
99 | - |
|
100 | - // the cron job must be executed with the right user |
|
101 | - if (!function_exists('posix_getuid')) { |
|
102 | - echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php' . PHP_EOL; |
|
103 | - exit(1); |
|
104 | - } |
|
105 | - |
|
106 | - $user = posix_getuid(); |
|
107 | - $configUser = fileowner(OC::$configDir . 'config.php'); |
|
108 | - if ($user !== $configUser) { |
|
109 | - echo 'Console has to be executed with the user that owns the file config/config.php' . PHP_EOL; |
|
110 | - echo 'Current user id: ' . $user . PHP_EOL; |
|
111 | - echo 'Owner id of config.php: ' . $configUser . PHP_EOL; |
|
112 | - exit(1); |
|
113 | - } |
|
114 | - |
|
115 | - |
|
116 | - // We call Nextcloud from the CLI (aka cron) |
|
117 | - if ($appMode !== 'cron') { |
|
118 | - $appConfig->setValueString('core', 'backgroundjobs_mode', 'cron'); |
|
119 | - } |
|
120 | - |
|
121 | - // a specific job class list can optionally be given as argument |
|
122 | - $jobClasses = array_slice($argv, $verbose ? 2 : 1); |
|
123 | - $jobClasses = empty($jobClasses) ? null : $jobClasses; |
|
124 | - |
|
125 | - // Low-load hours |
|
126 | - $onlyTimeSensitive = false; |
|
127 | - $startHour = $config->getSystemValueInt('maintenance_window_start', 100); |
|
128 | - if ($jobClasses === null && $startHour <= 23) { |
|
129 | - $date = new \DateTime('now', new \DateTimeZone('UTC')); |
|
130 | - $currentHour = (int)$date->format('G'); |
|
131 | - $endHour = $startHour + 4; |
|
132 | - |
|
133 | - if ($startHour <= 20) { |
|
134 | - // Start time: 01:00 |
|
135 | - // End time: 05:00 |
|
136 | - // Only run sensitive tasks when it's before the start or after the end |
|
137 | - $onlyTimeSensitive = $currentHour < $startHour || $currentHour > $endHour; |
|
138 | - } else { |
|
139 | - // Start time: 23:00 |
|
140 | - // End time: 03:00 |
|
141 | - $endHour -= 24; // Correct the end time from 27:00 to 03:00 |
|
142 | - // Only run sensitive tasks when it's after the end and before the start |
|
143 | - $onlyTimeSensitive = $currentHour > $endHour && $currentHour < $startHour; |
|
144 | - } |
|
145 | - } |
|
146 | - |
|
147 | - // Work |
|
148 | - $jobList = Server::get(IJobList::class); |
|
149 | - |
|
150 | - // We only ask for jobs for 14 minutes, because after 5 minutes the next |
|
151 | - // system cron task should spawn and we want to have at most three |
|
152 | - // cron jobs running in parallel. |
|
153 | - $endTime = time() + 14 * 60; |
|
154 | - |
|
155 | - $executedJobs = []; |
|
156 | - |
|
157 | - while ($job = $jobList->getNext($onlyTimeSensitive, $jobClasses)) { |
|
158 | - if (isset($executedJobs[$job->getId()])) { |
|
159 | - $jobList->unlockJob($job); |
|
160 | - break; |
|
161 | - } |
|
162 | - |
|
163 | - $jobDetails = get_class($job) . ' (id: ' . $job->getId() . ', arguments: ' . json_encode($job->getArgument()) . ')'; |
|
164 | - $logger->debug('CLI cron call has selected job ' . $jobDetails, ['app' => 'cron']); |
|
165 | - |
|
166 | - $timeBefore = time(); |
|
167 | - $memoryBefore = memory_get_usage(); |
|
168 | - $memoryPeakBefore = memory_get_peak_usage(); |
|
169 | - |
|
170 | - if ($verbose) { |
|
171 | - echo 'Starting job ' . $jobDetails . PHP_EOL; |
|
172 | - } |
|
173 | - |
|
174 | - /** @psalm-suppress DeprecatedMethod Calling execute until it is removed, then will switch to start */ |
|
175 | - $job->execute($jobList); |
|
176 | - |
|
177 | - $timeAfter = time(); |
|
178 | - $memoryAfter = memory_get_usage(); |
|
179 | - $memoryPeakAfter = memory_get_peak_usage(); |
|
180 | - |
|
181 | - $cronInterval = 5 * 60; |
|
182 | - $timeSpent = $timeAfter - $timeBefore; |
|
183 | - if ($timeSpent > $cronInterval) { |
|
184 | - $logLevel = match (true) { |
|
185 | - $timeSpent > $cronInterval * 128 => ILogger::FATAL, |
|
186 | - $timeSpent > $cronInterval * 64 => ILogger::ERROR, |
|
187 | - $timeSpent > $cronInterval * 16 => ILogger::WARN, |
|
188 | - $timeSpent > $cronInterval * 8 => ILogger::INFO, |
|
189 | - default => ILogger::DEBUG, |
|
190 | - }; |
|
191 | - $logger->log( |
|
192 | - $logLevel, |
|
193 | - 'Background job ' . $jobDetails . ' ran for ' . $timeSpent . ' seconds', |
|
194 | - ['app' => 'cron'] |
|
195 | - ); |
|
196 | - } |
|
197 | - |
|
198 | - if ($memoryAfter - $memoryBefore > 50_000_000) { |
|
199 | - $message = 'Used memory grew by more than 50 MB when executing job ' . $jobDetails . ': ' . Util::humanFileSize($memoryAfter) . ' (before: ' . Util::humanFileSize($memoryBefore) . ')'; |
|
200 | - $logger->warning($message, ['app' => 'cron']); |
|
201 | - if ($verbose) { |
|
202 | - echo $message . PHP_EOL; |
|
203 | - } |
|
204 | - } |
|
205 | - if ($memoryPeakAfter > 300_000_000 && $memoryPeakBefore <= 300_000_000) { |
|
206 | - $message = 'Cron job used more than 300 MB of ram after executing job ' . $jobDetails . ': ' . Util::humanFileSize($memoryPeakAfter) . ' (before: ' . Util::humanFileSize($memoryPeakBefore) . ')'; |
|
207 | - $logger->warning($message, ['app' => 'cron']); |
|
208 | - if ($verbose) { |
|
209 | - echo $message . PHP_EOL; |
|
210 | - } |
|
211 | - } |
|
212 | - |
|
213 | - // clean up after unclean jobs |
|
214 | - Server::get(SetupManager::class)->tearDown(); |
|
215 | - $tempManager->clean(); |
|
216 | - |
|
217 | - if ($verbose) { |
|
218 | - echo 'Job ' . $jobDetails . ' done in ' . ($timeAfter - $timeBefore) . ' seconds' . PHP_EOL; |
|
219 | - } |
|
220 | - |
|
221 | - $jobList->setLastJob($job); |
|
222 | - $executedJobs[$job->getId()] = true; |
|
223 | - unset($job); |
|
224 | - |
|
225 | - if ($timeAfter > $endTime) { |
|
226 | - break; |
|
227 | - } |
|
228 | - } |
|
229 | - } else { |
|
230 | - // We call cron.php from some website |
|
231 | - if ($appMode === 'cron') { |
|
232 | - // Cron is cron :-P |
|
233 | - OC_JSON::error(['data' => ['message' => 'Backgroundjobs are using system cron!']]); |
|
234 | - } else { |
|
235 | - // Work and success :-) |
|
236 | - $jobList = Server::get(IJobList::class); |
|
237 | - $job = $jobList->getNext(); |
|
238 | - if ($job != null) { |
|
239 | - $logger->debug('WebCron call has selected job with ID ' . strval($job->getId()), ['app' => 'cron']); |
|
240 | - /** @psalm-suppress DeprecatedMethod Calling execute until it is removed, then will switch to start */ |
|
241 | - $job->execute($jobList); |
|
242 | - $jobList->setLastJob($job); |
|
243 | - } |
|
244 | - OC_JSON::success(); |
|
245 | - } |
|
246 | - } |
|
247 | - |
|
248 | - // Log the successful cron execution |
|
249 | - $appConfig->setValueInt('core', 'lastcron', time()); |
|
250 | - exit(); |
|
45 | + exit(0); |
|
46 | + } |
|
47 | + |
|
48 | + if (Util::needUpgrade()) { |
|
49 | + Server::get(LoggerInterface::class)->debug('Update required, skipping cron', ['app' => 'cron']); |
|
50 | + exit; |
|
51 | + } |
|
52 | + |
|
53 | + $config = Server::get(IConfig::class); |
|
54 | + |
|
55 | + if ($config->getSystemValueBool('maintenance', false)) { |
|
56 | + Server::get(LoggerInterface::class)->debug('We are in maintenance mode, skipping cron', ['app' => 'cron']); |
|
57 | + exit; |
|
58 | + } |
|
59 | + |
|
60 | + // Don't do anything if Nextcloud has not been installed |
|
61 | + if (!$config->getSystemValueBool('installed', false)) { |
|
62 | + exit(0); |
|
63 | + } |
|
64 | + |
|
65 | + // load all apps to get all api routes properly setup |
|
66 | + Server::get(IAppManager::class)->loadApps(); |
|
67 | + Server::get(ISession::class)->close(); |
|
68 | + |
|
69 | + $verbose = isset($argv[1]) && ($argv[1] === '-v' || $argv[1] === '--verbose'); |
|
70 | + |
|
71 | + // initialize a dummy memory session |
|
72 | + $session = new Memory(); |
|
73 | + $cryptoWrapper = Server::get(CryptoWrapper::class); |
|
74 | + $session = $cryptoWrapper->wrapSession($session); |
|
75 | + \OC::$server->setSession($session); |
|
76 | + |
|
77 | + $logger = Server::get(LoggerInterface::class); |
|
78 | + $appConfig = Server::get(IAppConfig::class); |
|
79 | + $tempManager = Server::get(ITempManager::class); |
|
80 | + |
|
81 | + $tempManager->cleanOld(); |
|
82 | + |
|
83 | + // Exit if background jobs are disabled! |
|
84 | + $appMode = $appConfig->getValueString('core', 'backgroundjobs_mode', 'ajax'); |
|
85 | + if ($appMode === 'none') { |
|
86 | + if (OC::$CLI) { |
|
87 | + echo 'Background Jobs are disabled!' . PHP_EOL; |
|
88 | + } else { |
|
89 | + OC_JSON::error(['data' => ['message' => 'Background jobs disabled!']]); |
|
90 | + } |
|
91 | + exit(1); |
|
92 | + } |
|
93 | + |
|
94 | + if (OC::$CLI) { |
|
95 | + // set to run indefinitely if needed |
|
96 | + if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { |
|
97 | + @set_time_limit(0); |
|
98 | + } |
|
99 | + |
|
100 | + // the cron job must be executed with the right user |
|
101 | + if (!function_exists('posix_getuid')) { |
|
102 | + echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php' . PHP_EOL; |
|
103 | + exit(1); |
|
104 | + } |
|
105 | + |
|
106 | + $user = posix_getuid(); |
|
107 | + $configUser = fileowner(OC::$configDir . 'config.php'); |
|
108 | + if ($user !== $configUser) { |
|
109 | + echo 'Console has to be executed with the user that owns the file config/config.php' . PHP_EOL; |
|
110 | + echo 'Current user id: ' . $user . PHP_EOL; |
|
111 | + echo 'Owner id of config.php: ' . $configUser . PHP_EOL; |
|
112 | + exit(1); |
|
113 | + } |
|
114 | + |
|
115 | + |
|
116 | + // We call Nextcloud from the CLI (aka cron) |
|
117 | + if ($appMode !== 'cron') { |
|
118 | + $appConfig->setValueString('core', 'backgroundjobs_mode', 'cron'); |
|
119 | + } |
|
120 | + |
|
121 | + // a specific job class list can optionally be given as argument |
|
122 | + $jobClasses = array_slice($argv, $verbose ? 2 : 1); |
|
123 | + $jobClasses = empty($jobClasses) ? null : $jobClasses; |
|
124 | + |
|
125 | + // Low-load hours |
|
126 | + $onlyTimeSensitive = false; |
|
127 | + $startHour = $config->getSystemValueInt('maintenance_window_start', 100); |
|
128 | + if ($jobClasses === null && $startHour <= 23) { |
|
129 | + $date = new \DateTime('now', new \DateTimeZone('UTC')); |
|
130 | + $currentHour = (int)$date->format('G'); |
|
131 | + $endHour = $startHour + 4; |
|
132 | + |
|
133 | + if ($startHour <= 20) { |
|
134 | + // Start time: 01:00 |
|
135 | + // End time: 05:00 |
|
136 | + // Only run sensitive tasks when it's before the start or after the end |
|
137 | + $onlyTimeSensitive = $currentHour < $startHour || $currentHour > $endHour; |
|
138 | + } else { |
|
139 | + // Start time: 23:00 |
|
140 | + // End time: 03:00 |
|
141 | + $endHour -= 24; // Correct the end time from 27:00 to 03:00 |
|
142 | + // Only run sensitive tasks when it's after the end and before the start |
|
143 | + $onlyTimeSensitive = $currentHour > $endHour && $currentHour < $startHour; |
|
144 | + } |
|
145 | + } |
|
146 | + |
|
147 | + // Work |
|
148 | + $jobList = Server::get(IJobList::class); |
|
149 | + |
|
150 | + // We only ask for jobs for 14 minutes, because after 5 minutes the next |
|
151 | + // system cron task should spawn and we want to have at most three |
|
152 | + // cron jobs running in parallel. |
|
153 | + $endTime = time() + 14 * 60; |
|
154 | + |
|
155 | + $executedJobs = []; |
|
156 | + |
|
157 | + while ($job = $jobList->getNext($onlyTimeSensitive, $jobClasses)) { |
|
158 | + if (isset($executedJobs[$job->getId()])) { |
|
159 | + $jobList->unlockJob($job); |
|
160 | + break; |
|
161 | + } |
|
162 | + |
|
163 | + $jobDetails = get_class($job) . ' (id: ' . $job->getId() . ', arguments: ' . json_encode($job->getArgument()) . ')'; |
|
164 | + $logger->debug('CLI cron call has selected job ' . $jobDetails, ['app' => 'cron']); |
|
165 | + |
|
166 | + $timeBefore = time(); |
|
167 | + $memoryBefore = memory_get_usage(); |
|
168 | + $memoryPeakBefore = memory_get_peak_usage(); |
|
169 | + |
|
170 | + if ($verbose) { |
|
171 | + echo 'Starting job ' . $jobDetails . PHP_EOL; |
|
172 | + } |
|
173 | + |
|
174 | + /** @psalm-suppress DeprecatedMethod Calling execute until it is removed, then will switch to start */ |
|
175 | + $job->execute($jobList); |
|
176 | + |
|
177 | + $timeAfter = time(); |
|
178 | + $memoryAfter = memory_get_usage(); |
|
179 | + $memoryPeakAfter = memory_get_peak_usage(); |
|
180 | + |
|
181 | + $cronInterval = 5 * 60; |
|
182 | + $timeSpent = $timeAfter - $timeBefore; |
|
183 | + if ($timeSpent > $cronInterval) { |
|
184 | + $logLevel = match (true) { |
|
185 | + $timeSpent > $cronInterval * 128 => ILogger::FATAL, |
|
186 | + $timeSpent > $cronInterval * 64 => ILogger::ERROR, |
|
187 | + $timeSpent > $cronInterval * 16 => ILogger::WARN, |
|
188 | + $timeSpent > $cronInterval * 8 => ILogger::INFO, |
|
189 | + default => ILogger::DEBUG, |
|
190 | + }; |
|
191 | + $logger->log( |
|
192 | + $logLevel, |
|
193 | + 'Background job ' . $jobDetails . ' ran for ' . $timeSpent . ' seconds', |
|
194 | + ['app' => 'cron'] |
|
195 | + ); |
|
196 | + } |
|
197 | + |
|
198 | + if ($memoryAfter - $memoryBefore > 50_000_000) { |
|
199 | + $message = 'Used memory grew by more than 50 MB when executing job ' . $jobDetails . ': ' . Util::humanFileSize($memoryAfter) . ' (before: ' . Util::humanFileSize($memoryBefore) . ')'; |
|
200 | + $logger->warning($message, ['app' => 'cron']); |
|
201 | + if ($verbose) { |
|
202 | + echo $message . PHP_EOL; |
|
203 | + } |
|
204 | + } |
|
205 | + if ($memoryPeakAfter > 300_000_000 && $memoryPeakBefore <= 300_000_000) { |
|
206 | + $message = 'Cron job used more than 300 MB of ram after executing job ' . $jobDetails . ': ' . Util::humanFileSize($memoryPeakAfter) . ' (before: ' . Util::humanFileSize($memoryPeakBefore) . ')'; |
|
207 | + $logger->warning($message, ['app' => 'cron']); |
|
208 | + if ($verbose) { |
|
209 | + echo $message . PHP_EOL; |
|
210 | + } |
|
211 | + } |
|
212 | + |
|
213 | + // clean up after unclean jobs |
|
214 | + Server::get(SetupManager::class)->tearDown(); |
|
215 | + $tempManager->clean(); |
|
216 | + |
|
217 | + if ($verbose) { |
|
218 | + echo 'Job ' . $jobDetails . ' done in ' . ($timeAfter - $timeBefore) . ' seconds' . PHP_EOL; |
|
219 | + } |
|
220 | + |
|
221 | + $jobList->setLastJob($job); |
|
222 | + $executedJobs[$job->getId()] = true; |
|
223 | + unset($job); |
|
224 | + |
|
225 | + if ($timeAfter > $endTime) { |
|
226 | + break; |
|
227 | + } |
|
228 | + } |
|
229 | + } else { |
|
230 | + // We call cron.php from some website |
|
231 | + if ($appMode === 'cron') { |
|
232 | + // Cron is cron :-P |
|
233 | + OC_JSON::error(['data' => ['message' => 'Backgroundjobs are using system cron!']]); |
|
234 | + } else { |
|
235 | + // Work and success :-) |
|
236 | + $jobList = Server::get(IJobList::class); |
|
237 | + $job = $jobList->getNext(); |
|
238 | + if ($job != null) { |
|
239 | + $logger->debug('WebCron call has selected job with ID ' . strval($job->getId()), ['app' => 'cron']); |
|
240 | + /** @psalm-suppress DeprecatedMethod Calling execute until it is removed, then will switch to start */ |
|
241 | + $job->execute($jobList); |
|
242 | + $jobList->setLastJob($job); |
|
243 | + } |
|
244 | + OC_JSON::success(); |
|
245 | + } |
|
246 | + } |
|
247 | + |
|
248 | + // Log the successful cron execution |
|
249 | + $appConfig->setValueInt('core', 'lastcron', time()); |
|
250 | + exit(); |
|
251 | 251 | } catch (Exception $ex) { |
252 | - Server::get(LoggerInterface::class)->error( |
|
253 | - $ex->getMessage(), |
|
254 | - ['app' => 'cron', 'exception' => $ex] |
|
255 | - ); |
|
256 | - echo $ex . PHP_EOL; |
|
257 | - exit(1); |
|
252 | + Server::get(LoggerInterface::class)->error( |
|
253 | + $ex->getMessage(), |
|
254 | + ['app' => 'cron', 'exception' => $ex] |
|
255 | + ); |
|
256 | + echo $ex . PHP_EOL; |
|
257 | + exit(1); |
|
258 | 258 | } catch (Error $ex) { |
259 | - Server::get(LoggerInterface::class)->error( |
|
260 | - $ex->getMessage(), |
|
261 | - ['app' => 'cron', 'exception' => $ex] |
|
262 | - ); |
|
263 | - echo $ex . PHP_EOL; |
|
264 | - exit(1); |
|
259 | + Server::get(LoggerInterface::class)->error( |
|
260 | + $ex->getMessage(), |
|
261 | + ['app' => 'cron', 'exception' => $ex] |
|
262 | + ); |
|
263 | + echo $ex . PHP_EOL; |
|
264 | + exit(1); |
|
265 | 265 | } |
@@ -29,11 +29,11 @@ discard block |
||
29 | 29 | use Symfony\Component\Routing\Exception\ResourceNotFoundException; |
30 | 30 | |
31 | 31 | if (Util::needUpgrade() |
32 | - || Server::get(IConfig::class)->getSystemValueBool('maintenance')) { |
|
33 | - // since the behavior of apps or remotes are unpredictable during |
|
34 | - // an upgrade, return a 503 directly |
|
35 | - ApiHelper::respond(503, 'Service unavailable', ['X-Nextcloud-Maintenance-Mode' => '1'], 503); |
|
36 | - exit; |
|
32 | + || Server::get(IConfig::class)->getSystemValueBool('maintenance')) { |
|
33 | + // since the behavior of apps or remotes are unpredictable during |
|
34 | + // an upgrade, return a 503 directly |
|
35 | + ApiHelper::respond(503, 'Service unavailable', ['X-Nextcloud-Maintenance-Mode' => '1'], 503); |
|
36 | + exit; |
|
37 | 37 | } |
38 | 38 | |
39 | 39 | |
@@ -41,41 +41,41 @@ discard block |
||
41 | 41 | * Try the appframework routes |
42 | 42 | */ |
43 | 43 | try { |
44 | - OC_App::loadApps(['session']); |
|
45 | - OC_App::loadApps(['authentication']); |
|
46 | - OC_App::loadApps(['extended_authentication']); |
|
44 | + OC_App::loadApps(['session']); |
|
45 | + OC_App::loadApps(['authentication']); |
|
46 | + OC_App::loadApps(['extended_authentication']); |
|
47 | 47 | |
48 | - // load all apps to get all api routes properly setup |
|
49 | - // FIXME: this should ideally appear after handleLogin but will cause |
|
50 | - // side effects in existing apps |
|
51 | - OC_App::loadApps(); |
|
48 | + // load all apps to get all api routes properly setup |
|
49 | + // FIXME: this should ideally appear after handleLogin but will cause |
|
50 | + // side effects in existing apps |
|
51 | + OC_App::loadApps(); |
|
52 | 52 | |
53 | - if (!Server::get(IUserSession::class)->isLoggedIn()) { |
|
54 | - OC::handleLogin(Server::get(IRequest::class)); |
|
55 | - } |
|
53 | + if (!Server::get(IUserSession::class)->isLoggedIn()) { |
|
54 | + OC::handleLogin(Server::get(IRequest::class)); |
|
55 | + } |
|
56 | 56 | |
57 | - Server::get(Router::class)->match('/ocsapp' . Server::get(IRequest::class)->getRawPathInfo()); |
|
57 | + Server::get(Router::class)->match('/ocsapp' . Server::get(IRequest::class)->getRawPathInfo()); |
|
58 | 58 | } catch (MaxDelayReached $ex) { |
59 | - ApiHelper::respond(Http::STATUS_TOO_MANY_REQUESTS, $ex->getMessage()); |
|
59 | + ApiHelper::respond(Http::STATUS_TOO_MANY_REQUESTS, $ex->getMessage()); |
|
60 | 60 | } catch (ResourceNotFoundException $e) { |
61 | - $txt = 'Invalid query, please check the syntax. API specifications are here:' |
|
62 | - . ' http://www.freedesktop.org/wiki/Specifications/open-collaboration-services.' . "\n"; |
|
63 | - ApiHelper::respond(OCSController::RESPOND_NOT_FOUND, $txt); |
|
61 | + $txt = 'Invalid query, please check the syntax. API specifications are here:' |
|
62 | + . ' http://www.freedesktop.org/wiki/Specifications/open-collaboration-services.' . "\n"; |
|
63 | + ApiHelper::respond(OCSController::RESPOND_NOT_FOUND, $txt); |
|
64 | 64 | } catch (MethodNotAllowedException $e) { |
65 | - ApiHelper::setContentType(); |
|
66 | - http_response_code(405); |
|
65 | + ApiHelper::setContentType(); |
|
66 | + http_response_code(405); |
|
67 | 67 | } catch (LoginException $e) { |
68 | - ApiHelper::respond(OCSController::RESPOND_UNAUTHORISED, 'Unauthorised'); |
|
68 | + ApiHelper::respond(OCSController::RESPOND_UNAUTHORISED, 'Unauthorised'); |
|
69 | 69 | } catch (\Exception $e) { |
70 | - Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]); |
|
70 | + Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]); |
|
71 | 71 | |
72 | - $txt = 'Internal Server Error' . "\n"; |
|
73 | - try { |
|
74 | - if (Server::get(SystemConfig::class)->getValue('debug', false)) { |
|
75 | - $txt .= $e->getMessage(); |
|
76 | - } |
|
77 | - } catch (\Throwable $e) { |
|
78 | - // Just to be save |
|
79 | - } |
|
80 | - ApiHelper::respond(OCSController::RESPOND_SERVER_ERROR, $txt); |
|
72 | + $txt = 'Internal Server Error' . "\n"; |
|
73 | + try { |
|
74 | + if (Server::get(SystemConfig::class)->getValue('debug', false)) { |
|
75 | + $txt .= $e->getMessage(); |
|
76 | + } |
|
77 | + } catch (\Throwable $e) { |
|
78 | + // Just to be save |
|
79 | + } |
|
80 | + ApiHelper::respond(OCSController::RESPOND_SERVER_ERROR, $txt); |
|
81 | 81 | } |
@@ -16,8 +16,8 @@ discard block |
||
16 | 16 | * SPDX-License-Identifier: AGPL-3.0-only |
17 | 17 | */ |
18 | 18 | |
19 | -require_once __DIR__ . '/../lib/versioncheck.php'; |
|
20 | -require_once __DIR__ . '/../lib/base.php'; |
|
19 | +require_once __DIR__.'/../lib/versioncheck.php'; |
|
20 | +require_once __DIR__.'/../lib/base.php'; |
|
21 | 21 | |
22 | 22 | use OC\OCS\ApiHelper; |
23 | 23 | use OCP\AppFramework\Http; |
@@ -54,12 +54,12 @@ discard block |
||
54 | 54 | OC::handleLogin(Server::get(IRequest::class)); |
55 | 55 | } |
56 | 56 | |
57 | - Server::get(Router::class)->match('/ocsapp' . Server::get(IRequest::class)->getRawPathInfo()); |
|
57 | + Server::get(Router::class)->match('/ocsapp'.Server::get(IRequest::class)->getRawPathInfo()); |
|
58 | 58 | } catch (MaxDelayReached $ex) { |
59 | 59 | ApiHelper::respond(Http::STATUS_TOO_MANY_REQUESTS, $ex->getMessage()); |
60 | 60 | } catch (ResourceNotFoundException $e) { |
61 | 61 | $txt = 'Invalid query, please check the syntax. API specifications are here:' |
62 | - . ' http://www.freedesktop.org/wiki/Specifications/open-collaboration-services.' . "\n"; |
|
62 | + . ' http://www.freedesktop.org/wiki/Specifications/open-collaboration-services.'."\n"; |
|
63 | 63 | ApiHelper::respond(OCSController::RESPOND_NOT_FOUND, $txt); |
64 | 64 | } catch (MethodNotAllowedException $e) { |
65 | 65 | ApiHelper::setContentType(); |
@@ -69,7 +69,7 @@ discard block |
||
69 | 69 | } catch (\Exception $e) { |
70 | 70 | Server::get(LoggerInterface::class)->error($e->getMessage(), ['exception' => $e]); |
71 | 71 | |
72 | - $txt = 'Internal Server Error' . "\n"; |
|
72 | + $txt = 'Internal Server Error'."\n"; |
|
73 | 73 | try { |
74 | 74 | if (Server::get(SystemConfig::class)->getValue('debug', false)) { |
75 | 75 | $txt .= $e->getMessage(); |
@@ -8,14 +8,14 @@ |
||
8 | 8 | * SPDX-FileCopyrightText: 2016 ownCloud, Inc. |
9 | 9 | * SPDX-License-Identifier: AGPL-3.0-only |
10 | 10 | */ |
11 | -require_once __DIR__ . '/../lib/versioncheck.php'; |
|
12 | -require_once __DIR__ . '/../lib/base.php'; |
|
11 | +require_once __DIR__.'/../lib/versioncheck.php'; |
|
12 | +require_once __DIR__.'/../lib/base.php'; |
|
13 | 13 | |
14 | 14 | header('Content-type: application/xml'); |
15 | 15 | |
16 | 16 | $request = Server::get(IRequest::class); |
17 | 17 | |
18 | -$url = $request->getServerProtocol() . '://' . substr($request->getServerHost() . $request->getRequestUri(), 0, -17) . 'ocs/v1.php/'; |
|
18 | +$url = $request->getServerProtocol().'://'.substr($request->getServerHost().$request->getRequestUri(), 0, -17).'ocs/v1.php/'; |
|
19 | 19 | |
20 | 20 | $writer = new XMLWriter(); |
21 | 21 | $writer->openURI('php://output'); |
@@ -23,90 +23,90 @@ |
||
23 | 23 | define('OC_CONSOLE', 1); |
24 | 24 | |
25 | 25 | function exceptionHandler($exception) { |
26 | - echo 'An unhandled exception has been thrown:' . PHP_EOL; |
|
27 | - echo $exception; |
|
28 | - exit(1); |
|
26 | + echo 'An unhandled exception has been thrown:' . PHP_EOL; |
|
27 | + echo $exception; |
|
28 | + exit(1); |
|
29 | 29 | } |
30 | 30 | try { |
31 | - require_once __DIR__ . '/lib/base.php'; |
|
32 | - |
|
33 | - // set to run indefinitely if needed |
|
34 | - if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { |
|
35 | - @set_time_limit(0); |
|
36 | - } |
|
37 | - |
|
38 | - if (!OC::$CLI) { |
|
39 | - echo 'This script can be run from the command line only' . PHP_EOL; |
|
40 | - exit(1); |
|
41 | - } |
|
42 | - |
|
43 | - $config = Server::get(IConfig::class); |
|
44 | - set_exception_handler('exceptionHandler'); |
|
45 | - |
|
46 | - if (!function_exists('posix_getuid')) { |
|
47 | - echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php' . PHP_EOL; |
|
48 | - exit(1); |
|
49 | - } |
|
50 | - |
|
51 | - $user = posix_getuid(); |
|
52 | - $configUser = fileowner(OC::$configDir . 'config.php'); |
|
53 | - if ($user !== $configUser) { |
|
54 | - echo 'Console has to be executed with the user that owns the file config/config.php' . PHP_EOL; |
|
55 | - echo 'Current user id: ' . $user . PHP_EOL; |
|
56 | - echo 'Owner id of config.php: ' . $configUser . PHP_EOL; |
|
57 | - echo "Try adding 'sudo -u #" . $configUser . "' to the beginning of the command (without the single quotes)" . PHP_EOL; |
|
58 | - echo "If running with 'docker exec' try adding the option '-u " . $configUser . "' to the docker command (without the single quotes)" . PHP_EOL; |
|
59 | - exit(1); |
|
60 | - } |
|
61 | - |
|
62 | - $oldWorkingDir = getcwd(); |
|
63 | - if ($oldWorkingDir === false) { |
|
64 | - echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL; |
|
65 | - echo "Can't determine current working dir - the script will continue to work but be aware of the above fact." . PHP_EOL; |
|
66 | - } elseif ($oldWorkingDir !== __DIR__ && !chdir(__DIR__)) { |
|
67 | - echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL; |
|
68 | - echo "Can't change to Nextcloud root directory." . PHP_EOL; |
|
69 | - exit(1); |
|
70 | - } |
|
71 | - |
|
72 | - if (!(function_exists('pcntl_signal') && function_exists('pcntl_signal_dispatch')) && !in_array('--no-warnings', $argv)) { |
|
73 | - echo 'The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see https://www.php.net/manual/en/book.pcntl.php' . PHP_EOL; |
|
74 | - echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini." . PHP_EOL; |
|
75 | - } |
|
76 | - |
|
77 | - $eventLogger = Server::get(IEventLogger::class); |
|
78 | - $eventLogger->start('console:build_application', 'Build Application instance and load commands'); |
|
79 | - |
|
80 | - $application = Server::get(Application::class); |
|
81 | - /* base.php will have removed eventual debug options from argv in $_SERVER */ |
|
82 | - $argv = $_SERVER['argv']; |
|
83 | - $input = new ArgvInput($argv); |
|
84 | - $application->loadCommands($input, new ConsoleOutput()); |
|
85 | - |
|
86 | - $eventLogger->end('console:build_application'); |
|
87 | - $eventLogger->start('console:run', 'Run the command'); |
|
88 | - |
|
89 | - $application->setAutoExit(false); |
|
90 | - $exitCode = $application->run($input); |
|
91 | - |
|
92 | - $eventLogger->end('console:run'); |
|
93 | - |
|
94 | - $profiler = Server::get(IProfiler::class); |
|
95 | - if ($profiler->isEnabled()) { |
|
96 | - $eventLogger->end('runtime'); |
|
97 | - $profile = $profiler->collect(Server::get(IRequest::class), new Response()); |
|
98 | - $profile->setMethod('occ'); |
|
99 | - $profile->setUrl(implode(' ', $argv)); |
|
100 | - $profiler->saveProfile($profile); |
|
101 | - } |
|
102 | - |
|
103 | - if ($exitCode > 255) { |
|
104 | - $exitCode = 255; |
|
105 | - } |
|
106 | - |
|
107 | - exit($exitCode); |
|
31 | + require_once __DIR__ . '/lib/base.php'; |
|
32 | + |
|
33 | + // set to run indefinitely if needed |
|
34 | + if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { |
|
35 | + @set_time_limit(0); |
|
36 | + } |
|
37 | + |
|
38 | + if (!OC::$CLI) { |
|
39 | + echo 'This script can be run from the command line only' . PHP_EOL; |
|
40 | + exit(1); |
|
41 | + } |
|
42 | + |
|
43 | + $config = Server::get(IConfig::class); |
|
44 | + set_exception_handler('exceptionHandler'); |
|
45 | + |
|
46 | + if (!function_exists('posix_getuid')) { |
|
47 | + echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php' . PHP_EOL; |
|
48 | + exit(1); |
|
49 | + } |
|
50 | + |
|
51 | + $user = posix_getuid(); |
|
52 | + $configUser = fileowner(OC::$configDir . 'config.php'); |
|
53 | + if ($user !== $configUser) { |
|
54 | + echo 'Console has to be executed with the user that owns the file config/config.php' . PHP_EOL; |
|
55 | + echo 'Current user id: ' . $user . PHP_EOL; |
|
56 | + echo 'Owner id of config.php: ' . $configUser . PHP_EOL; |
|
57 | + echo "Try adding 'sudo -u #" . $configUser . "' to the beginning of the command (without the single quotes)" . PHP_EOL; |
|
58 | + echo "If running with 'docker exec' try adding the option '-u " . $configUser . "' to the docker command (without the single quotes)" . PHP_EOL; |
|
59 | + exit(1); |
|
60 | + } |
|
61 | + |
|
62 | + $oldWorkingDir = getcwd(); |
|
63 | + if ($oldWorkingDir === false) { |
|
64 | + echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL; |
|
65 | + echo "Can't determine current working dir - the script will continue to work but be aware of the above fact." . PHP_EOL; |
|
66 | + } elseif ($oldWorkingDir !== __DIR__ && !chdir(__DIR__)) { |
|
67 | + echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL; |
|
68 | + echo "Can't change to Nextcloud root directory." . PHP_EOL; |
|
69 | + exit(1); |
|
70 | + } |
|
71 | + |
|
72 | + if (!(function_exists('pcntl_signal') && function_exists('pcntl_signal_dispatch')) && !in_array('--no-warnings', $argv)) { |
|
73 | + echo 'The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see https://www.php.net/manual/en/book.pcntl.php' . PHP_EOL; |
|
74 | + echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini." . PHP_EOL; |
|
75 | + } |
|
76 | + |
|
77 | + $eventLogger = Server::get(IEventLogger::class); |
|
78 | + $eventLogger->start('console:build_application', 'Build Application instance and load commands'); |
|
79 | + |
|
80 | + $application = Server::get(Application::class); |
|
81 | + /* base.php will have removed eventual debug options from argv in $_SERVER */ |
|
82 | + $argv = $_SERVER['argv']; |
|
83 | + $input = new ArgvInput($argv); |
|
84 | + $application->loadCommands($input, new ConsoleOutput()); |
|
85 | + |
|
86 | + $eventLogger->end('console:build_application'); |
|
87 | + $eventLogger->start('console:run', 'Run the command'); |
|
88 | + |
|
89 | + $application->setAutoExit(false); |
|
90 | + $exitCode = $application->run($input); |
|
91 | + |
|
92 | + $eventLogger->end('console:run'); |
|
93 | + |
|
94 | + $profiler = Server::get(IProfiler::class); |
|
95 | + if ($profiler->isEnabled()) { |
|
96 | + $eventLogger->end('runtime'); |
|
97 | + $profile = $profiler->collect(Server::get(IRequest::class), new Response()); |
|
98 | + $profile->setMethod('occ'); |
|
99 | + $profile->setUrl(implode(' ', $argv)); |
|
100 | + $profiler->saveProfile($profile); |
|
101 | + } |
|
102 | + |
|
103 | + if ($exitCode > 255) { |
|
104 | + $exitCode = 255; |
|
105 | + } |
|
106 | + |
|
107 | + exit($exitCode); |
|
108 | 108 | } catch (Exception $ex) { |
109 | - exceptionHandler($ex); |
|
109 | + exceptionHandler($ex); |
|
110 | 110 | } catch (Error $ex) { |
111 | - exceptionHandler($ex); |
|
111 | + exceptionHandler($ex); |
|
112 | 112 | } |
@@ -10,7 +10,7 @@ discard block |
||
10 | 10 | * SPDX-FileCopyrightText: 2016 ownCloud, Inc. |
11 | 11 | * SPDX-License-Identifier: AGPL-3.0-only |
12 | 12 | */ |
13 | -require_once __DIR__ . '/lib/versioncheck.php'; |
|
13 | +require_once __DIR__.'/lib/versioncheck.php'; |
|
14 | 14 | |
15 | 15 | use OC\Console\Application; |
16 | 16 | use OCP\AppFramework\Http\Response; |
@@ -23,12 +23,12 @@ discard block |
||
23 | 23 | define('OC_CONSOLE', 1); |
24 | 24 | |
25 | 25 | function exceptionHandler($exception) { |
26 | - echo 'An unhandled exception has been thrown:' . PHP_EOL; |
|
26 | + echo 'An unhandled exception has been thrown:'.PHP_EOL; |
|
27 | 27 | echo $exception; |
28 | 28 | exit(1); |
29 | 29 | } |
30 | 30 | try { |
31 | - require_once __DIR__ . '/lib/base.php'; |
|
31 | + require_once __DIR__.'/lib/base.php'; |
|
32 | 32 | |
33 | 33 | // set to run indefinitely if needed |
34 | 34 | if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { |
@@ -36,7 +36,7 @@ discard block |
||
36 | 36 | } |
37 | 37 | |
38 | 38 | if (!OC::$CLI) { |
39 | - echo 'This script can be run from the command line only' . PHP_EOL; |
|
39 | + echo 'This script can be run from the command line only'.PHP_EOL; |
|
40 | 40 | exit(1); |
41 | 41 | } |
42 | 42 | |
@@ -44,34 +44,34 @@ discard block |
||
44 | 44 | set_exception_handler('exceptionHandler'); |
45 | 45 | |
46 | 46 | if (!function_exists('posix_getuid')) { |
47 | - echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php' . PHP_EOL; |
|
47 | + echo 'The posix extensions are required - see https://www.php.net/manual/en/book.posix.php'.PHP_EOL; |
|
48 | 48 | exit(1); |
49 | 49 | } |
50 | 50 | |
51 | 51 | $user = posix_getuid(); |
52 | - $configUser = fileowner(OC::$configDir . 'config.php'); |
|
52 | + $configUser = fileowner(OC::$configDir.'config.php'); |
|
53 | 53 | if ($user !== $configUser) { |
54 | - echo 'Console has to be executed with the user that owns the file config/config.php' . PHP_EOL; |
|
55 | - echo 'Current user id: ' . $user . PHP_EOL; |
|
56 | - echo 'Owner id of config.php: ' . $configUser . PHP_EOL; |
|
57 | - echo "Try adding 'sudo -u #" . $configUser . "' to the beginning of the command (without the single quotes)" . PHP_EOL; |
|
58 | - echo "If running with 'docker exec' try adding the option '-u " . $configUser . "' to the docker command (without the single quotes)" . PHP_EOL; |
|
54 | + echo 'Console has to be executed with the user that owns the file config/config.php'.PHP_EOL; |
|
55 | + echo 'Current user id: '.$user.PHP_EOL; |
|
56 | + echo 'Owner id of config.php: '.$configUser.PHP_EOL; |
|
57 | + echo "Try adding 'sudo -u #".$configUser."' to the beginning of the command (without the single quotes)".PHP_EOL; |
|
58 | + echo "If running with 'docker exec' try adding the option '-u ".$configUser."' to the docker command (without the single quotes)".PHP_EOL; |
|
59 | 59 | exit(1); |
60 | 60 | } |
61 | 61 | |
62 | 62 | $oldWorkingDir = getcwd(); |
63 | 63 | if ($oldWorkingDir === false) { |
64 | - echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL; |
|
65 | - echo "Can't determine current working dir - the script will continue to work but be aware of the above fact." . PHP_EOL; |
|
64 | + echo 'This script can be run from the Nextcloud root directory only.'.PHP_EOL; |
|
65 | + echo "Can't determine current working dir - the script will continue to work but be aware of the above fact.".PHP_EOL; |
|
66 | 66 | } elseif ($oldWorkingDir !== __DIR__ && !chdir(__DIR__)) { |
67 | - echo 'This script can be run from the Nextcloud root directory only.' . PHP_EOL; |
|
68 | - echo "Can't change to Nextcloud root directory." . PHP_EOL; |
|
67 | + echo 'This script can be run from the Nextcloud root directory only.'.PHP_EOL; |
|
68 | + echo "Can't change to Nextcloud root directory.".PHP_EOL; |
|
69 | 69 | exit(1); |
70 | 70 | } |
71 | 71 | |
72 | 72 | if (!(function_exists('pcntl_signal') && function_exists('pcntl_signal_dispatch')) && !in_array('--no-warnings', $argv)) { |
73 | - echo 'The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see https://www.php.net/manual/en/book.pcntl.php' . PHP_EOL; |
|
74 | - echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini." . PHP_EOL; |
|
73 | + echo 'The process control (PCNTL) extensions are required in case you want to interrupt long running commands - see https://www.php.net/manual/en/book.pcntl.php'.PHP_EOL; |
|
74 | + echo "Additionally the function 'pcntl_signal' and 'pcntl_signal_dispatch' need to be enabled in your php.ini.".PHP_EOL; |
|
75 | 75 | } |
76 | 76 | |
77 | 77 | $eventLogger = Server::get(IEventLogger::class); |