Instance.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OC\Remote;
  7. use OC\Remote\Api\NotFoundException;
  8. use OCP\Http\Client\IClientService;
  9. use OCP\ICache;
  10. use OCP\Remote\IInstance;
  11. /**
  12. * Provides some basic info about a remote Nextcloud instance
  13. */
  14. class Instance implements IInstance {
  15. /** @var string */
  16. private $url;
  17. /** @var ICache */
  18. private $cache;
  19. /** @var IClientService */
  20. private $clientService;
  21. /** @var array|null */
  22. private $status;
  23. /**
  24. * @param string $url
  25. * @param ICache $cache
  26. * @param IClientService $clientService
  27. */
  28. public function __construct($url, ICache $cache, IClientService $clientService) {
  29. $url = str_replace('https://', '', $url);
  30. $this->url = str_replace('http://', '', $url);
  31. $this->cache = $cache;
  32. $this->clientService = $clientService;
  33. }
  34. /**
  35. * @return string The url of the remote server without protocol
  36. */
  37. public function getUrl() {
  38. return $this->url;
  39. }
  40. /**
  41. * @return string The of the remote server with protocol
  42. */
  43. public function getFullUrl() {
  44. return $this->getProtocol() . '://' . $this->getUrl();
  45. }
  46. /**
  47. * @return string The full version string in '13.1.2.3' format
  48. */
  49. public function getVersion() {
  50. $status = $this->getStatus();
  51. return $status['version'];
  52. }
  53. /**
  54. * @return string 'http' or 'https'
  55. */
  56. public function getProtocol() {
  57. $status = $this->getStatus();
  58. return $status['protocol'];
  59. }
  60. /**
  61. * Check that the remote server is installed and not in maintenance mode
  62. *
  63. * @return bool
  64. */
  65. public function isActive() {
  66. $status = $this->getStatus();
  67. return $status['installed'] && !$status['maintenance'];
  68. }
  69. /**
  70. * @return array
  71. * @throws NotFoundException
  72. * @throws \Exception
  73. */
  74. private function getStatus() {
  75. if ($this->status) {
  76. return $this->status;
  77. }
  78. $key = 'remote/' . $this->url . '/status';
  79. $httpsKey = 'remote/' . $this->url . '/https';
  80. $status = $this->cache->get($key);
  81. if (!$status) {
  82. $response = $this->downloadStatus('https://' . $this->getUrl() . '/status.php');
  83. $protocol = 'https';
  84. if (!$response) {
  85. if ($status = $this->cache->get($httpsKey)) {
  86. throw new \Exception('refusing to connect to remote instance(' . $this->url . ') over http that was previously accessible over https');
  87. }
  88. $response = $this->downloadStatus('http://' . $this->getUrl() . '/status.php');
  89. $protocol = 'http';
  90. } else {
  91. $this->cache->set($httpsKey, true, 60 * 60 * 24 * 365);
  92. }
  93. $status = json_decode($response, true);
  94. if ($status) {
  95. $status['protocol'] = $protocol;
  96. }
  97. if ($status) {
  98. $this->cache->set($key, $status, 5 * 60);
  99. $this->status = $status;
  100. } else {
  101. throw new NotFoundException('Remote server not found at address ' . $this->url);
  102. }
  103. }
  104. return $status;
  105. }
  106. /**
  107. * @param string $url
  108. * @return bool|string
  109. */
  110. private function downloadStatus($url) {
  111. try {
  112. $request = $this->clientService->newClient()->get($url);
  113. return $request->getBody();
  114. } catch (\Exception $e) {
  115. return false;
  116. }
  117. }
  118. }