Completed
Push — master ( 236086...24f965 )
by Morris
14:23
created

Client::getRequestOptions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 0
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2016, ownCloud, Inc.
5
 *
6
 * @author Lukas Reschke <[email protected]>
7
 * @author Robin Appelman <[email protected]>
8
 *
9
 * @license AGPL-3.0
10
 *
11
 * This code is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU Affero General Public License, version 3,
13
 * as published by the Free Software Foundation.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Affero General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Affero General Public License, version 3,
21
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
22
 *
23
 */
24
25
namespace OC\Http\Client;
26
27
use GuzzleHttp\Client as GuzzleClient;
28
use GuzzleHttp\HandlerStack;
29
use GuzzleHttp\Middleware;
30
use OCP\Http\Client\IClient;
31
use OCP\Http\Client\IResponse;
32
use OCP\ICertificateManager;
33
use OCP\IConfig;
34
use Psr\Http\Message\RequestInterface;
35
36
/**
37
 * Class Client
38
 *
39
 * @package OC\Http
40
 */
41
class Client implements IClient {
42
	/** @var GuzzleClient */
43
	private $client;
44
	/** @var IConfig */
45
	private $config;
46
	/** @var ICertificateManager */
47
	private $certificateManager;
48
	private $configured = false;
49
	/** @var HandlerStack */
50
	private $stack;
51
52
	/**
53
	 * @param IConfig $config
54
	 * @param ICertificateManager $certificateManager
55
	 * @param GuzzleClient $client
56
	 */
57
	public function __construct(
58
		IConfig $config,
59
		ICertificateManager $certificateManager,
60
		GuzzleClient $client,
61
		HandlerStack $stack
62
	) {
63
		$this->config = $config;
64
		$this->client = $client;
65
		$this->stack = $stack;
66
		$this->certificateManager = $certificateManager;
67
	}
68
69
	/**
70
	 * Sets the default options to the client
71
	 */
72
	private function setDefaultOptions() {
73
		if ($this->configured) {
74
			return;
75
		}
76
		$this->configured = true;
77
78
		$this->stack->push(Middleware::mapRequest(function (RequestInterface $request) {
79
			return $request
80
				->withHeader('User-Agent', 'Nextcloud Server Crawler');
81
		}));
82
	}
83
84
	private function getRequestOptions() {
85
		$options = [
86
			'verify' => $this->getCertBundle(),
87
		];
88
		$proxyUri = $this->getProxyUri();
89
		if ($proxyUri !== '') {
90
			$options['proxy'] = $proxyUri;
91
		}
92
		return $options;
93
	}
94
95
	private function getCertBundle() {
96
		if ($this->certificateManager->listCertificates() !== []) {
97
			return $this->certificateManager->getAbsoluteBundlePath();
98
		} else {
99
			// If the instance is not yet setup we need to use the static path as
100
			// $this->certificateManager->getAbsoluteBundlePath() tries to instantiiate
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
101
			// a view
102
			if ($this->config->getSystemValue('installed', false)) {
103
				return $this->certificateManager->getAbsoluteBundlePath(null);
104
			} else {
105
				return \OC::$SERVERROOT . '/resources/config/ca-bundle.crt';
106
			}
107
		}
108
	}
109
110
	/**
111
	 * Get the proxy URI
112
	 *
113
	 * @return string
114
	 */
115
	private function getProxyUri(): string {
116
		$proxyHost = $this->config->getSystemValue('proxy', null);
117
		$proxyUserPwd = $this->config->getSystemValue('proxyuserpwd', null);
118
		$proxyUri = '';
119
120
		if ($proxyUserPwd !== null) {
121
			$proxyUri .= $proxyUserPwd . '@';
122
		}
123
		if ($proxyHost !== null) {
124
			$proxyUri .= $proxyHost;
125
		}
126
127
		return $proxyUri;
128
	}
129
130
	/**
131
	 * Sends a GET request
132
	 *
133
	 * @param string $uri
134
	 * @param array $options Array such as
135
	 *              'query' => [
136
	 *                  'field' => 'abc',
137
	 *                  'other_field' => '123',
138
	 *                  'file_name' => fopen('/path/to/file', 'r'),
139
	 *              ],
140
	 *              'headers' => [
141
	 *                  'foo' => 'bar',
142
	 *              ],
143
	 *              'cookies' => ['
144
	 *                  'foo' => 'bar',
145
	 *              ],
146
	 *              'allow_redirects' => [
147
	 *                   'max'       => 10,  // allow at most 10 redirects.
148
	 *                   'strict'    => true,     // use "strict" RFC compliant redirects.
149
	 *                   'referer'   => true,     // add a Referer header
150
	 *                   'protocols' => ['https'] // only allow https URLs
151
	 *              ],
152
	 *              'save_to' => '/path/to/file', // save to a file or a stream
153
	 *              'verify' => true, // bool or string to CA file
154
	 *              'debug' => true,
155
	 *              'timeout' => 5,
156
	 * @return IResponse
157
	 * @throws \Exception If the request could not get completed
158
	 */
159
	public function get(string $uri, array $options = []): IResponse {
160
		$this->setDefaultOptions();
161
		$response = $this->client->request('get', $uri, array_merge($options, $this->getRequestOptions()));
162
		$isStream = isset($options['stream']) && $options['stream'];
163
		return new Response($response, $isStream);
164
	}
165
166
	/**
167
	 * Sends a HEAD request
168
	 *
169
	 * @param string $uri
170
	 * @param array $options Array such as
171
	 *              'headers' => [
172
	 *                  'foo' => 'bar',
173
	 *              ],
174
	 *              'cookies' => ['
175
	 *                  'foo' => 'bar',
176
	 *              ],
177
	 *              'allow_redirects' => [
178
	 *                   'max'       => 10,  // allow at most 10 redirects.
179
	 *                   'strict'    => true,     // use "strict" RFC compliant redirects.
180
	 *                   'referer'   => true,     // add a Referer header
181
	 *                   'protocols' => ['https'] // only allow https URLs
182
	 *              ],
183
	 *              'save_to' => '/path/to/file', // save to a file or a stream
184
	 *              'verify' => true, // bool or string to CA file
185
	 *              'debug' => true,
186
	 *              'timeout' => 5,
187
	 * @return IResponse
188
	 * @throws \Exception If the request could not get completed
189
	 */
190
	public function head(string $uri, array $options = []): IResponse {
191
		$this->setDefaultOptions();
192
		$response = $this->client->request('head', $uri, array_merge($options, $this->getRequestOptions()));
193
		return new Response($response);
194
	}
195
196
	/**
197
	 * Sends a POST request
198
	 *
199
	 * @param string $uri
200
	 * @param array $options Array such as
201
	 *              'body' => [
202
	 *                  'field' => 'abc',
203
	 *                  'other_field' => '123',
204
	 *                  'file_name' => fopen('/path/to/file', 'r'),
205
	 *              ],
206
	 *              'headers' => [
207
	 *                  'foo' => 'bar',
208
	 *              ],
209
	 *              'cookies' => ['
210
	 *                  'foo' => 'bar',
211
	 *              ],
212
	 *              'allow_redirects' => [
213
	 *                   'max'       => 10,  // allow at most 10 redirects.
214
	 *                   'strict'    => true,     // use "strict" RFC compliant redirects.
215
	 *                   'referer'   => true,     // add a Referer header
216
	 *                   'protocols' => ['https'] // only allow https URLs
217
	 *              ],
218
	 *              'save_to' => '/path/to/file', // save to a file or a stream
219
	 *              'verify' => true, // bool or string to CA file
220
	 *              'debug' => true,
221
	 *              'timeout' => 5,
222
	 * @return IResponse
223
	 * @throws \Exception If the request could not get completed
224
	 */
225
	public function post(string $uri, array $options = []): IResponse {
226
		$this->setDefaultOptions();
227
		if (isset($options['body']) && is_array($options['body'])) {
228
			$options['form_params'] = $options['body'];
229
			unset($options['body']);
230
		}
231
		$response = $this->client->request('post', $uri, array_merge($options, $this->getRequestOptions()));
232
		return new Response($response);
233
	}
234
235
	/**
236
	 * Sends a PUT request
237
	 *
238
	 * @param string $uri
239
	 * @param array $options Array such as
240
	 *              'body' => [
241
	 *                  'field' => 'abc',
242
	 *                  'other_field' => '123',
243
	 *                  'file_name' => fopen('/path/to/file', 'r'),
244
	 *              ],
245
	 *              'headers' => [
246
	 *                  'foo' => 'bar',
247
	 *              ],
248
	 *              'cookies' => ['
249
	 *                  'foo' => 'bar',
250
	 *              ],
251
	 *              'allow_redirects' => [
252
	 *                   'max'       => 10,  // allow at most 10 redirects.
253
	 *                   'strict'    => true,     // use "strict" RFC compliant redirects.
254
	 *                   'referer'   => true,     // add a Referer header
255
	 *                   'protocols' => ['https'] // only allow https URLs
256
	 *              ],
257
	 *              'save_to' => '/path/to/file', // save to a file or a stream
258
	 *              'verify' => true, // bool or string to CA file
259
	 *              'debug' => true,
260
	 *              'timeout' => 5,
261
	 * @return IResponse
262
	 * @throws \Exception If the request could not get completed
263
	 */
264
	public function put(string $uri, array $options = []): IResponse {
265
		$this->setDefaultOptions();
266
		$response = $this->client->request('put', $uri, array_merge($options, $this->getRequestOptions()));
267
		return new Response($response);
268
	}
269
270
	/**
271
	 * Sends a DELETE request
272
	 *
273
	 * @param string $uri
274
	 * @param array $options Array such as
275
	 *              'body' => [
276
	 *                  'field' => 'abc',
277
	 *                  'other_field' => '123',
278
	 *                  'file_name' => fopen('/path/to/file', 'r'),
279
	 *              ],
280
	 *              'headers' => [
281
	 *                  'foo' => 'bar',
282
	 *              ],
283
	 *              'cookies' => ['
284
	 *                  'foo' => 'bar',
285
	 *              ],
286
	 *              'allow_redirects' => [
287
	 *                   'max'       => 10,  // allow at most 10 redirects.
288
	 *                   'strict'    => true,     // use "strict" RFC compliant redirects.
289
	 *                   'referer'   => true,     // add a Referer header
290
	 *                   'protocols' => ['https'] // only allow https URLs
291
	 *              ],
292
	 *              'save_to' => '/path/to/file', // save to a file or a stream
293
	 *              'verify' => true, // bool or string to CA file
294
	 *              'debug' => true,
295
	 *              'timeout' => 5,
296
	 * @return IResponse
297
	 * @throws \Exception If the request could not get completed
298
	 */
299
	public function delete(string $uri, array $options = []): IResponse {
300
		$this->setDefaultOptions();
301
		$response = $this->client->request('delete', $uri, array_merge($options, $this->getRequestOptions()));
302
		return new Response($response);
303
	}
304
305
306
	/**
307
	 * Sends a options request
308
	 *
309
	 * @param string $uri
310
	 * @param array $options Array such as
311
	 *              'body' => [
312
	 *                  'field' => 'abc',
313
	 *                  'other_field' => '123',
314
	 *                  'file_name' => fopen('/path/to/file', 'r'),
315
	 *              ],
316
	 *              'headers' => [
317
	 *                  'foo' => 'bar',
318
	 *              ],
319
	 *              'cookies' => ['
320
	 *                  'foo' => 'bar',
321
	 *              ],
322
	 *              'allow_redirects' => [
323
	 *                   'max'       => 10,  // allow at most 10 redirects.
324
	 *                   'strict'    => true,     // use "strict" RFC compliant redirects.
325
	 *                   'referer'   => true,     // add a Referer header
326
	 *                   'protocols' => ['https'] // only allow https URLs
327
	 *              ],
328
	 *              'save_to' => '/path/to/file', // save to a file or a stream
329
	 *              'verify' => true, // bool or string to CA file
330
	 *              'debug' => true,
331
	 *              'timeout' => 5,
332
	 * @return IResponse
333
	 * @throws \Exception If the request could not get completed
334
	 */
335
	public function options(string $uri, array $options = []): IResponse {
336
		$this->setDefaultOptions();
337
		$response = $this->client->request('options', $uri, array_merge($options, $this->getRequestOptions()));
338
		return new Response($response);
339
	}
340
}
341