summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorMorris Jobke <hey@morrisjobke.de>2015-03-26 11:06:48 +0100
committerMorris Jobke <hey@morrisjobke.de>2015-03-26 11:06:48 +0100
commit20f5290462cddee766025bd5671430836b054cc8 (patch)
treea0b33a654f6fa2ed4c75dffd9f65ddd437ada90f /lib
parentc8f0cbab5a994aadfaa9c984bb9959ca872fe781 (diff)
parent5f044ebf1bc6f45acec2e79dc05185acd0405f42 (diff)
downloadnextcloud-server-20f5290462cddee766025bd5671430836b054cc8.tar.gz
nextcloud-server-20f5290462cddee766025bd5671430836b054cc8.zip
Merge pull request #15195 from owncloud/reanimate-add-guzzle
Add wrapper for Guzzle
Diffstat (limited to 'lib')
-rw-r--r--lib/private/http/client/client.php268
-rw-r--r--lib/private/http/client/clientservice.php43
-rw-r--r--lib/private/http/client/response.php58
-rw-r--r--lib/private/httphelper.php164
-rw-r--r--lib/private/installer.php5
-rw-r--r--lib/private/ocsclient.php59
-rw-r--r--lib/private/security/certificatemanager.php10
-rw-r--r--lib/private/server.php27
-rw-r--r--lib/private/util.php28
-rw-r--r--lib/public/http/client/iclient.php181
-rw-r--r--lib/public/http/client/iclientservice.php21
-rw-r--r--lib/public/http/client/iresponse.php37
-rw-r--r--lib/public/iservercontainer.php8
-rw-r--r--lib/repair/updatecertificatestore.php77
14 files changed, 812 insertions, 174 deletions
diff --git a/lib/private/http/client/client.php b/lib/private/http/client/client.php
new file mode 100644
index 00000000000..7c022272375
--- /dev/null
+++ b/lib/private/http/client/client.php
@@ -0,0 +1,268 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Http\Client;
+
+use GuzzleHttp\Client as GuzzleClient;
+use OCP\Http\Client\IClient;
+use OCP\ICertificateManager;
+use OCP\IConfig;
+
+/**
+ * Class Client
+ *
+ * @package OC\Http
+ */
+class Client implements IClient {
+ /** @var GuzzleClient */
+ private $client;
+ /** @var IConfig */
+ private $config;
+ /** @var ICertificateManager */
+ private $certificateManager;
+
+ /**
+ * @param IConfig $config
+ * @param ICertificateManager $certificateManager
+ * @param GuzzleClient $client
+ */
+ public function __construct(IConfig $config,
+ ICertificateManager $certificateManager,
+ GuzzleClient $client) {
+ $this->config = $config;
+ $this->client = $client;
+ $this->certificateManager = $certificateManager;
+ $this->setDefaultOptions();
+ }
+
+ /**
+ * Sets the default options to the client
+ */
+ private function setDefaultOptions() {
+ // Either use default bundle or the user bundle if nothing is specified
+ if($this->certificateManager->listCertificates() !== []) {
+ $dataDir = $this->config->getSystemValue('datadirectory');
+ $this->client->setDefaultOption('verify', $dataDir.'/'.$this->certificateManager->getCertificateBundle());
+ } else {
+ $this->client->setDefaultOption('verify', \OC::$SERVERROOT . '/config/ca-bundle.crt');
+ }
+
+ $this->client->setDefaultOption('headers/User-Agent', 'ownCloud Server Crawler');
+ if($this->getProxyUri() !== '') {
+ $this->client->setDefaultOption('proxy', $this->getProxyUri());
+ }
+ }
+
+ /**
+ * Get the proxy URI
+ * @return string
+ */
+ private function getProxyUri() {
+ $proxyHost = $this->config->getSystemValue('proxy', null);
+ $proxyUserPwd = $this->config->getSystemValue('proxyuserpwd', null);
+ $proxyUri = '';
+
+ if(!is_null($proxyUserPwd)) {
+ $proxyUri .= $proxyUserPwd.'@';
+ }
+ if(!is_null($proxyHost)) {
+ $proxyUri .= $proxyHost;
+ }
+
+ return $proxyUri;
+ }
+
+ /**
+ * Sends a GET request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'query' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * 'timeout' => 5,
+ * @return Response
+ * @throws \Exception If the request could not get completed
+ */
+ public function get($uri, array $options = []) {
+ $response = $this->client->get($uri, $options);
+ return new Response($response);
+ }
+
+ /**
+ * Sends a HEAD request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * 'timeout' => 5,
+ * @return Response
+ */
+ public function head($uri, $options = []) {
+ $response = $this->client->head($uri, $options);
+ return new Response($response);
+ }
+
+ /**
+ * Sends a POST request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * 'timeout' => 5,
+ * @return Response
+ */
+ public function post($uri, array $options = []) {
+ $response = $this->client->post($uri, $options);
+ return new Response($response);
+ }
+
+ /**
+ * Sends a PUT request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * 'timeout' => 5,
+ * @return Response
+ */
+ public function put($uri, array $options = []) {
+ $response = $this->client->put($uri, $options);
+ return new Response($response);
+ }
+
+ /**
+ * Sends a DELETE request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * 'timeout' => 5,
+ * @return Response
+ */
+ public function delete($uri, array $options = []) {
+ $response = $this->client->delete($uri, $options);
+ return new Response($response);
+ }
+
+
+ /**
+ * Sends a options request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * 'timeout' => 5,
+ * @return Response
+ */
+ public function options($uri, array $options = []) {
+ $response = $this->client->options($uri, $options);
+ return new Response($response);
+ }
+}
diff --git a/lib/private/http/client/clientservice.php b/lib/private/http/client/clientservice.php
new file mode 100644
index 00000000000..795d508e5f9
--- /dev/null
+++ b/lib/private/http/client/clientservice.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Http\Client;
+
+use GuzzleHttp\Client as GuzzleClient;
+use OCP\Http\Client\IClientService;
+use OCP\ICertificateManager;
+use OCP\IConfig;
+
+/**
+ * Class ClientService
+ *
+ * @package OC\Http
+ */
+class ClientService implements IClientService {
+ /** @var IConfig */
+ private $config;
+ /** @var ICertificateManager */
+ private $certificateManager;
+
+ /**
+ * @param IConfig $config
+ * @param ICertificateManager $certificateManager
+ */
+ public function __construct(IConfig $config,
+ ICertificateManager $certificateManager) {
+ $this->config = $config;
+ $this->certificateManager = $certificateManager;
+ }
+
+ /**
+ * @return Client
+ */
+ public function newClient() {
+ return new Client($this->config, $this->certificateManager, new GuzzleClient());
+ }
+}
diff --git a/lib/private/http/client/response.php b/lib/private/http/client/response.php
new file mode 100644
index 00000000000..54b7a93543c
--- /dev/null
+++ b/lib/private/http/client/response.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Http\Client;
+
+use OCP\Http\Client\IResponse;
+use GuzzleHttp\Message\Response as GuzzleResponse;
+
+/**
+ * Class Response
+ *
+ * @package OC\Http
+ */
+class Response implements IResponse {
+ /** @var GuzzleResponse */
+ private $response;
+
+ /**
+ * @param GuzzleResponse $response
+ */
+ public function __construct(GuzzleResponse $response) {
+ $this->response = $response;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBody() {
+ return $this->response->getBody()->getContents();
+ }
+
+ /**
+ * @return int
+ */
+ public function getStatusCode() {
+ return $this->response->getStatusCode();
+ }
+
+ /**
+ * @param $key
+ * @return string
+ */
+ public function getHeader($key) {
+ return $this->response->getHeader($key);
+ }
+
+ /**
+ * @return array
+ */
+ public function getHeaders() {
+ return $this->response->getHeaders();
+ }
+}
diff --git a/lib/private/httphelper.php b/lib/private/httphelper.php
index 6bb8e1d3ec0..16b824e927f 100644
--- a/lib/private/httphelper.php
+++ b/lib/private/httphelper.php
@@ -1,6 +1,6 @@
<?php
/**
- * Copyright (c) 2014 Lukas Reschke <lukas@owncloud.com>
+ * Copyright (c) 2014-2015 Lukas Reschke <lukas@owncloud.com>
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
@@ -8,41 +8,31 @@
namespace OC;
+use OCP\Http\Client\IClientService;
use OCP\IConfig;
-use OCP\ICertificateManager;
+/**
+ * Class HTTPHelper
+ *
+ * @package OC
+ * @deprecated Use \OCP\Http\Client\IClientService
+ */
class HTTPHelper {
const USER_AGENT = 'ownCloud Server Crawler';
/** @var \OCP\IConfig */
private $config;
-
- /** @var \OC\Security\CertificateManager */
- private $certificateManager;
+ /** @var IClientService */
+ private $clientService;
/**
- * @param \OCP\IConfig $config
+ * @param IConfig $config
+ * @param IClientService $clientService
*/
- public function __construct(IConfig $config, ICertificateManager $certificateManager) {
+ public function __construct(IConfig $config,
+ IClientService $clientService) {
$this->config = $config;
- $this->certificateManager = $certificateManager;
- }
-
- /**
- * Returns the default context array
- * @return array
- */
- public function getDefaultContextArray() {
- return array(
- 'http' => array(
- 'header' => 'User-Agent: ' . self::USER_AGENT . "\r\n",
- 'timeout' => 10,
- 'follow_location' => false, // Do not follow the location since we can't limit the protocol
- ),
- 'ssl' => array(
- 'disable_compression' => true
- )
- );
+ $this->clientService = $clientService;
}
/**
@@ -52,87 +42,28 @@ class HTTPHelper {
* @return string of the response or false on error
* This function get the content of a page via curl, if curl is enabled.
* If not, file_get_contents is used.
+ * @deprecated Use \OCP\Http\Client\IClientService
*/
public function getUrlContent($url) {
- if (!$this->isHTTPURL($url)) {
- throw new \Exception('$url must start with https:// or http://', 1);
- }
-
- $proxy = $this->config->getSystemValue('proxy', null);
- $proxyUserPwd = $this->config->getSystemValue('proxyuserpwd', null);
- $curl = curl_init();
- $max_redirects = 10;
-
- curl_setopt($curl, CURLOPT_HEADER, 0);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
- curl_setopt($curl, CURLOPT_URL, $url);
- curl_setopt($curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
- curl_setopt($curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
-
- curl_setopt($curl, CURLOPT_USERAGENT, self::USER_AGENT);
- if ($proxy !== null) {
- curl_setopt($curl, CURLOPT_PROXY, $proxy);
- }
- if ($proxyUserPwd !== null) {
- curl_setopt($curl, CURLOPT_PROXYUSERPWD, $proxyUserPwd);
- }
-
- if (ini_get('open_basedir') === '') {
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($curl, CURLOPT_MAXREDIRS, $max_redirects);
- $data = curl_exec($curl);
- } else {
- curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
- $mr = $max_redirects;
- if ($mr > 0) {
- $newURL = curl_getinfo($curl, CURLINFO_EFFECTIVE_URL);
- $rCurl = curl_copy_handle($curl);
- curl_setopt($rCurl, CURLOPT_HEADER, true);
- curl_setopt($rCurl, CURLOPT_NOBODY, true);
- curl_setopt($rCurl, CURLOPT_FORBID_REUSE, false);
- curl_setopt($rCurl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($rCurl, CURLOPT_USERAGENT, self::USER_AGENT);
- do {
- curl_setopt($rCurl, CURLOPT_URL, $newURL);
- $header = curl_exec($rCurl);
- if (curl_errno($rCurl)) {
- $code = 0;
- } else {
- $code = curl_getinfo($rCurl, CURLINFO_HTTP_CODE);
- if ($code == 301 || $code == 302) {
- preg_match('/Location:(.*?)\n/', $header, $matches);
- $newURL = trim(array_pop($matches));
- } else {
- $code = 0;
- }
- }
- } while ($code && --$mr);
- curl_close($rCurl);
- if ($mr > 0) {
- curl_setopt($curl, CURLOPT_URL, $newURL);
- }
- }
-
- if ($mr == 0 && $max_redirects > 0) {
- $data = false;
- } else {
- $data = curl_exec($curl);
- }
+ try {
+ $client = $this->clientService->newClient();
+ $response = $client->get($url);
+ return $response->getBody();
+ } catch (\Exception $e) {
+ return false;
}
- curl_close($curl);
-
- return $data;
}
/**
* Returns the response headers of a HTTP URL without following redirects
* @param string $location Needs to be a HTTPS or HTTP URL
* @return array
+ * @deprecated Use \OCP\Http\Client\IClientService
*/
public function getHeaders($location) {
- stream_context_set_default($this->getDefaultContextArray());
- return get_headers($location, 1);
+ $client = $this->clientService->newClient();
+ $response = $client->get($location);
+ return $response->getHeaders();
}
/**
@@ -145,50 +76,23 @@ class HTTPHelper {
}
/**
- * create string of parameters for post request
- *
- * @param array $parameters
- * @return string
- */
- private function assemblePostParameters(array $parameters) {
- $parameterString = '';
- foreach ($parameters as $key => $value) {
- $parameterString .= $key . '=' . urlencode($value) . '&';
- }
-
- return rtrim($parameterString, '&');
- }
-
- /**
* send http post request
*
* @param string $url
* @param array $fields data send by the request
- * @return bool
+ * @return array
+ * @deprecated Use \OCP\Http\Client\IClientService
*/
public function post($url, array $fields) {
+ $client = $this->clientService->newClient();
- $fieldsString = $this->assemblePostParameters($fields);
-
- $certBundle = $this->certificateManager->getCertificateBundle();
-
- $ch = curl_init();
-
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($ch, CURLOPT_POST, count($fields));
- curl_setopt($ch, CURLOPT_POSTFIELDS, (string)$fieldsString);
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
- if (is_readable($certBundle)) {
- curl_setopt($ch, CURLOPT_CAINFO, $certBundle);
+ try {
+ $response = $client->post($url, ['body' => $fields]);
+ } catch (\Exception $e) {
+ return ['success' => false, 'result' => $e->getMessage()];
}
- $result = curl_exec($ch);
- $success = $result ? true : false;
-
- curl_close($ch);
-
- return array('success' => $success, 'result' => $result);
+ return ['success' => true, 'result' => $response->getBody()];
}
}
diff --git a/lib/private/installer.php b/lib/private/installer.php
index 3956e503767..3af8fcf3b23 100644
--- a/lib/private/installer.php
+++ b/lib/private/installer.php
@@ -244,8 +244,9 @@ class OC_Installer{
if(!isset($data['href'])) {
throw new \Exception($l->t("No href specified when installing app from http"));
}
- file_put_contents($path, \OC_Util::getUrlContent($data['href']));
- }else{
+ $client = \OC::$server->getHTTPClientService()->newClient();
+ $client->get($data['href'], ['save_to' => $path]);
+ } else {
if(!isset($data['path'])) {
throw new \Exception($l->t("No path specified when installing app from local file"));
}
diff --git a/lib/private/ocsclient.php b/lib/private/ocsclient.php
index f27ab487efc..1e09d409297 100644
--- a/lib/private/ocsclient.php
+++ b/lib/private/ocsclient.php
@@ -67,16 +67,24 @@ class OCSClient {
return null;
}
$url = self::getAppStoreURL() . '/content/categories';
- $xml = \OC::$server->getHTTPHelper()->getUrlContent($url);
- if ($xml == false) {
+
+ $client = \OC::$server->getHTTPClientService()->newClient();
+ try {
+ $response = $client->get($url, ['timeout' => 5]);
+ } catch(\Exception $e) {
+ return null;
+ }
+
+ if($response->getStatusCode() !== 200) {
return null;
}
+
$loadEntities = libxml_disable_entity_loader(true);
- $data = simplexml_load_string($xml);
+ $data = simplexml_load_string($response->getBody());
libxml_disable_entity_loader($loadEntities);
$tmp = $data->data;
- $cats = array();
+ $cats = [];
foreach ($tmp->category as $value) {
@@ -114,14 +122,21 @@ class OCSClient {
$filterUrl = '&filter=' . urlencode($filter);
$url = self::getAppStoreURL() . '/content/data?categories=' . urlencode($categoriesString)
. '&sortmode=new&page=' . urlencode($page) . '&pagesize=100' . $filterUrl . $version;
- $apps = array();
- $xml = \OC::$server->getHTTPHelper()->getUrlContent($url);
+ $apps = [];
+
+ $client = \OC::$server->getHTTPClientService()->newClient();
+ try {
+ $response = $client->get($url, ['timeout' => 5]);
+ } catch(\Exception $e) {
+ return null;
+ }
- if ($xml == false) {
+ if($response->getStatusCode() !== 200) {
return null;
}
+
$loadEntities = libxml_disable_entity_loader(true);
- $data = simplexml_load_string($xml);
+ $data = simplexml_load_string($response->getBody());
libxml_disable_entity_loader($loadEntities);
$tmp = $data->data->content;
@@ -163,14 +178,19 @@ class OCSClient {
return null;
}
$url = self::getAppStoreURL() . '/content/data/' . urlencode($id);
- $xml = \OC::$server->getHTTPHelper()->getUrlContent($url);
+ $client = \OC::$server->getHTTPClientService()->newClient();
+ try {
+ $response = $client->get($url, ['timeout' => 5]);
+ } catch(\Exception $e) {
+ return null;
+ }
- if ($xml == false) {
- \OC_Log::write('core', 'Unable to parse OCS content for app ' . $id, \OC_Log::FATAL);
+ if($response->getStatusCode() !== 200) {
return null;
}
+
$loadEntities = libxml_disable_entity_loader(true);
- $data = simplexml_load_string($xml);
+ $data = simplexml_load_string($response->getBody());
libxml_disable_entity_loader($loadEntities);
$tmp = $data->data->content;
@@ -178,7 +198,7 @@ class OCSClient {
\OC_Log::write('core', 'Invalid OCS content returned for app ' . $id, \OC_Log::FATAL);
return null;
}
- $app = array();
+ $app = [];
$app['id'] = $tmp->id;
$app['name'] = $tmp->name;
$app['version'] = $tmp->version;
@@ -212,14 +232,19 @@ class OCSClient {
return null;
}
$url = self::getAppStoreURL() . '/content/download/' . urlencode($id) . '/' . urlencode($item);
- $xml = \OC::$server->getHTTPHelper()->getUrlContent($url);
+ $client = \OC::$server->getHTTPClientService()->newClient();
+ try {
+ $response = $client->get($url, ['timeout' => 5]);
+ } catch(\Exception $e) {
+ return null;
+ }
- if ($xml == false) {
- \OC_Log::write('core', 'Unable to parse OCS content', \OC_Log::FATAL);
+ if($response->getStatusCode() !== 200) {
return null;
}
+
$loadEntities = libxml_disable_entity_loader(true);
- $data = simplexml_load_string($xml);
+ $data = simplexml_load_string($response->getBody());
libxml_disable_entity_loader($loadEntities);
$tmp = $data->data->content;
diff --git a/lib/private/security/certificatemanager.php b/lib/private/security/certificatemanager.php
index 7bc83766365..d3a6dcd71eb 100644
--- a/lib/private/security/certificatemanager.php
+++ b/lib/private/security/certificatemanager.php
@@ -63,11 +63,13 @@ class CertificateManager implements ICertificateManager {
/**
* create the certificate bundle of all trusted certificated
*/
- protected function createCertificateBundle() {
+ public function createCertificateBundle() {
$path = $this->getPathToCertificates();
$certs = $this->listCertificates();
$fh_certs = $this->view->fopen($path . '/rootcerts.crt', 'w');
+
+ // Write user certificates
foreach ($certs as $cert) {
$file = $path . '/uploads/' . $cert->getName();
$data = $this->view->file_get_contents($file);
@@ -77,6 +79,9 @@ class CertificateManager implements ICertificateManager {
}
}
+ // Append the default certificates
+ $defaultCertificates = file_get_contents(\OC::$SERVERROOT . '/config/ca-bundle.crt');
+ fwrite($fh_certs, $defaultCertificates);
fclose($fh_certs);
}
@@ -137,6 +142,9 @@ class CertificateManager implements ICertificateManager {
return $this->getPathToCertificates() . 'rootcerts.crt';
}
+ /**
+ * @return string
+ */
private function getPathToCertificates() {
$path = is_null($this->uid) ? '/files_external/' : '/' . $this->uid . '/files_external/';
diff --git a/lib/private/server.php b/lib/private/server.php
index fd7a2bea2d1..1f275d658bf 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -13,6 +13,7 @@ use OC\Diagnostics\EventLogger;
use OC\Diagnostics\QueryLogger;
use OC\Mail\Mailer;
use OC\Memcache\ArrayCache;
+use OC\Http\Client\ClientService;
use OC\Security\CertificateManager;
use OC\Files\Node\Root;
use OC\Files\View;
@@ -236,9 +237,18 @@ class Server extends SimpleContainer implements IServerContainer {
});
$this->registerService('HTTPHelper', function (Server $c) {
$config = $c->getConfig();
- $user = $c->getUserSession()->getUser();
- $uid = $user ? $user->getUID() : null;
- return new HTTPHelper($config, new \OC\Security\CertificateManager($uid, new \OC\Files\View()));
+ return new HTTPHelper(
+ $config,
+ $c->getHTTPClientService()
+ );
+ });
+ $this->registerService('HttpClientService', function (Server $c) {
+ $user = \OC_User::getUser();
+ $uid = $user ? $user : null;
+ return new ClientService(
+ $c->getConfig(),
+ new \OC\Security\CertificateManager($uid, new \OC\Files\View())
+ );
});
$this->registerService('EventLogger', function (Server $c) {
if (defined('DEBUG') and DEBUG) {
@@ -664,7 +674,7 @@ class Server extends SimpleContainer implements IServerContainer {
/**
* Returns an instance of the HTTP helper class
- *
+ * @deprecated Use getHTTPClientService()
* @return \OC\HTTPHelper
*/
function getHTTPHelper() {
@@ -690,6 +700,15 @@ class Server extends SimpleContainer implements IServerContainer {
}
/**
+ * Returns an instance of the HTTP client service
+ *
+ * @return \OCP\Http\Client\IClientService
+ */
+ function getHTTPClientService() {
+ return $this->query('HttpClientService');
+ }
+
+ /**
* Create a new event source
*
* @return \OCP\IEventSource
diff --git a/lib/private/util.php b/lib/private/util.php
index a048996da6e..921bfd8067e 100644
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -1193,33 +1193,21 @@ class OC_Util {
/**
* Check if the ownCloud server can connect to the internet
*
+ * @param \OCP\Http\Client\IClientService $clientService
* @return bool
*/
- public static function isInternetConnectionWorking() {
+ public static function isInternetConnectionWorking(\OCP\Http\Client\IClientService $clientService) {
// in case there is no internet connection on purpose return false
if (self::isInternetConnectionEnabled() === false) {
return false;
}
- // in case the connection is via proxy return true to avoid connecting to owncloud.org
- if (OC_Config::getValue('proxy', '') != '') {
- return true;
- }
-
- // try to connect to owncloud.org to see if http connections to the internet are possible.
- $connected = @fsockopen("www.owncloud.org", 80);
- if ($connected) {
- fclose($connected);
- return true;
- } else {
- // second try in case one server is down
- $connected = @fsockopen("apps.owncloud.com", 80);
- if ($connected) {
- fclose($connected);
- return true;
- } else {
- return false;
- }
+ try {
+ $client = $clientService->newClient();
+ $response = $client->get('https://www.owncloud.org/');
+ return $response->getStatusCode() === 200;
+ } catch (\Exception $e) {
+ return false;
}
}
diff --git a/lib/public/http/client/iclient.php b/lib/public/http/client/iclient.php
new file mode 100644
index 00000000000..2946bcfa18d
--- /dev/null
+++ b/lib/public/http/client/iclient.php
@@ -0,0 +1,181 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Http\Client;
+
+/**
+ * Interface IClient
+ *
+ * @package OCP\Http
+ */
+interface IClient {
+
+ /**
+ * Sends a GET request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'query' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * @return IResponse
+ * @throws \Exception If the request could not get completed
+ */
+ public function get($uri, array $options = []);
+
+ /**
+ * Sends a HEAD request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * @return IResponse
+ */
+ public function head($uri, $options = []);
+
+ /**
+ * Sends a POST request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * @return IResponse
+ */
+ public function post($uri, array $options = []);
+
+ /**
+ * Sends a PUT request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * @return IResponse
+ */
+ public function put($uri, array $options = []);
+
+ /**
+ * Sends a DELETE request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * @return IResponse
+ */
+ public function delete($uri, array $options = []);
+
+ /**
+ * Sends a options request
+ * @param string $uri
+ * @param array $options Array such as
+ * 'body' => [
+ * 'field' => 'abc',
+ * 'other_field' => '123',
+ * 'file_name' => fopen('/path/to/file', 'r'),
+ * ],
+ * 'headers' => [
+ * 'foo' => 'bar',
+ * ],
+ * 'cookies' => ['
+ * 'foo' => 'bar',
+ * ],
+ * 'allow_redirects' => [
+ * 'max' => 10, // allow at most 10 redirects.
+ * 'strict' => true, // use "strict" RFC compliant redirects.
+ * 'referer' => true, // add a Referer header
+ * 'protocols' => ['https'] // only allow https URLs
+ * ],
+ * 'save_to' => '/path/to/file', // save to a file or a stream
+ * 'verify' => true, // bool or string to CA file
+ * 'debug' => true,
+ * @return IResponse
+ */
+ public function options($uri, array $options = []);
+}
diff --git a/lib/public/http/client/iclientservice.php b/lib/public/http/client/iclientservice.php
new file mode 100644
index 00000000000..4dc65f1721e
--- /dev/null
+++ b/lib/public/http/client/iclientservice.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Http\Client;
+
+/**
+ * Interface IClientService
+ *
+ * @package OCP\Http
+ */
+interface IClientService {
+ /**
+ * @return IClient
+ */
+ public function newClient();
+}
diff --git a/lib/public/http/client/iresponse.php b/lib/public/http/client/iresponse.php
new file mode 100644
index 00000000000..5355046a2a7
--- /dev/null
+++ b/lib/public/http/client/iresponse.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Copyright (c) 2015 Lukas Reschke <lukas@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP\Http\Client;
+
+/**
+ * Interface IResponse
+ *
+ * @package OCP\Http
+ */
+interface IResponse {
+ /**
+ * @return string
+ */
+ public function getBody();
+
+ /**
+ * @return int
+ */
+ public function getStatusCode();
+
+ /**
+ * @param $key
+ * @return string
+ */
+ public function getHeader($key);
+
+ /**
+ * @return array
+ */
+ public function getHeaders();
+}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index 20345e61212..a01ae5e200d 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -267,10 +267,18 @@ interface IServerContainer {
/**
* Returns an instance of the HTTP helper class
* @return \OC\HTTPHelper
+ * @deprecated Use \OCP\Http\Client\IClientService
*/
function getHTTPHelper();
/**
+ * Returns an instance of the HTTP client service
+ *
+ * @return \OCP\Http\Client\IClientService
+ */
+ function getHTTPClientService();
+
+ /**
* Get the active event logger
*
* @return \OCP\Diagnostics\IEventLogger
diff --git a/lib/repair/updatecertificatestore.php b/lib/repair/updatecertificatestore.php
new file mode 100644
index 00000000000..e1f6be45ef9
--- /dev/null
+++ b/lib/repair/updatecertificatestore.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * @author Lukas Reschke
+ * @copyright 2015 Lukas Reschke lukas@owncloud.com
+ *
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Repair;
+
+use OC\Files\View;
+use OC\Hooks\BasicEmitter;
+use OC\RepairStep;
+use OC\Server;
+use OCP\IConfig;
+
+/**
+ * Class UpdateCertificateStore rewrites the user specific certificate store after
+ * an update has been performed. This is done because a new root certificate file
+ * might have been added.
+ *
+ * @package OC\Repair
+ */
+class UpdateCertificateStore extends BasicEmitter implements RepairStep {
+ /**
+ * FIXME: The certificate manager does only allow specifying the user
+ * within the constructor. This makes DI impossible.
+ * @var Server
+ */
+ protected $server;
+ /** @var IConfig */
+ protected $config;
+
+ /**
+ * @param Server $server
+ * @param IConfig $config
+ */
+ public function __construct(Server $server,
+ IConfig $config) {
+ $this->server = $server;
+ $this->config = $config;
+ }
+
+ /** {@inheritDoc} */
+ public function getName() {
+ return 'Update user certificate stores with new root certificates';
+ }
+
+ /** {@inheritDoc} */
+ public function run() {
+ $rootView = new View();
+ $dataDirectory = $this->config->getSystemValue('datadirectory', null);
+ if(is_null($dataDirectory)) {
+ throw new \Exception('No data directory specified');
+ }
+
+ $pathToRootCerts = '/files_external/rootcerts.crt';
+
+ foreach($rootView->getDirectoryContent('', 'httpd/unix-directory') as $fileInfo) {
+ $uid = trim($fileInfo->getPath(), '/');
+ if($rootView->file_exists($uid . $pathToRootCerts)) {
+ // Delete the existing root certificate
+ $rootView->unlink($uid . $pathToRootCerts);
+
+ /**
+ * FIXME: The certificate manager does only allow specifying the user
+ * within the constructor. This makes DI impossible.
+ */
+ // Regenerate the certificates
+ $certificateManager = $this->server->getCertificateManager($uid);
+ $certificateManager->createCertificateBundle();
+ }
+ }
+ }
+}