Requests_Transport_fsockopen::format_get()   B
last analyzed

Complexity

Conditions 5
Paths 9

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 9
nop 2
dl 0
loc 22
rs 8.6737
c 0
b 0
f 0
1
<?php
2
/**
3
 * fsockopen HTTP transport
4
 *
5
 * @package Requests
6
 * @subpackage Transport
7
 */
8
9
/**
10
 * fsockopen HTTP transport
11
 *
12
 * @package Requests
13
 * @subpackage Transport
14
 */
15
class Requests_Transport_fsockopen implements Requests_Transport {
0 ignored issues
show
Coding Style introduced by
The property $max_bytes is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $connect_error is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
Coding Style introduced by
This class is not in CamelCase format.

Classes in PHP are usually named in CamelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. The whole name starts with a capital letter as well.

Thus the name database provider becomes DatabaseProvider.

Loading history...
16
	/**
17
	 * Second to microsecond conversion
18
	 *
19
	 * @var integer
20
	 */
21
	const SECOND_IN_MICROSECONDS = 1000000;
22
23
	/**
24
	 * Raw HTTP data
25
	 *
26
	 * @var string
27
	 */
28
	public $headers = '';
29
30
	/**
31
	 * Stream metadata
32
	 *
33
	 * @var array Associative array of properties, see {@see https://secure.php.net/stream_get_meta_data}
34
	 */
35
	public $info;
36
37
	/**
38
	 * What's the maximum number of bytes we should keep?
39
	 *
40
	 * @var int|bool Byte count, or false if no limit.
41
	 */
42
	protected $max_bytes = false;
43
44
	protected $connect_error = '';
45
46
	/**
47
	 * Perform a request
48
	 *
49
	 * @throws Requests_Exception On failure to connect to socket (`fsockopenerror`)
50
	 * @throws Requests_Exception On socket timeout (`timeout`)
51
	 *
52
	 * @param string $url URL to request
53
	 * @param array $headers Associative array of request headers
54
	 * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
55
	 * @param array $options Request options, see {@see Requests::response()} for documentation
56
	 * @return string Raw HTTP result
57
	 */
58
	public function request($url, $headers = array(), $data = array(), $options = array()) {
59
		$options['hooks']->dispatch('fsockopen.before_request');
60
61
		$url_parts = parse_url($url);
62
		if (empty($url_parts)) {
63
			throw new Requests_Exception('Invalid URL.', 'invalidurl', $url);
64
		}
65
		$host = $url_parts['host'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 21 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
66
		$context = stream_context_create();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 18 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
67
		$verifyname = false;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 15 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
68
		$case_insensitive_headers = new Requests_Utility_CaseInsensitiveDictionary($headers);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $case_insensitive_headers exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
69
70
		// HTTPS support
71
		if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
72
			$remote_socket = 'ssl://' . $host;
73
			if (!isset($url_parts['port'])) {
74
				$url_parts['port'] = 443;
75
			}
76
77
			$context_options = array(
78
				'verify_peer' => true,
79
				// 'CN_match' => $host,
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
80
				'capture_peer_cert' => true
81
			);
82
			$verifyname = true;
83
84
			// SNI, if enabled (OpenSSL >=0.9.8j)
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...
85
			if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
86
				$context_options['SNI_enabled'] = true;
87 View Code Duplication
				if (isset($options['verifyname']) && $options['verifyname'] === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
88
					$context_options['SNI_enabled'] = false;
89
				}
90
			}
91
92
			if (isset($options['verify'])) {
93
				if ($options['verify'] === false) {
94
					$context_options['verify_peer'] = false;
95
				}
96
				elseif (is_string($options['verify'])) {
97
					$context_options['cafile'] = $options['verify'];
98
				}
99
			}
100
101 View Code Duplication
			if (isset($options['verifyname']) && $options['verifyname'] === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
				$context_options['verify_peer_name'] = false;
103
				$verifyname = false;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 26 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
104
			}
105
106
			stream_context_set_option($context, array('ssl' => $context_options));
107
		}
108
		else {
109
			$remote_socket = 'tcp://' . $host;
110
		}
111
112
		$this->max_bytes = $options['max_bytes'];
113
114
		if (!isset($url_parts['port'])) {
115
			$url_parts['port'] = 80;
116
		}
117
		$remote_socket .= ':' . $url_parts['port'];
118
119
		set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE);
120
121
		$options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket));
122
123
		$socket = stream_socket_client($remote_socket, $errno, $errstr, ceil($options['connect_timeout']), STREAM_CLIENT_CONNECT, $context);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 134 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
124
125
		restore_error_handler();
126
127
		if ($verifyname && !$this->verify_certificate_from_context($host, $context)) {
128
			throw new Requests_Exception('SSL certificate did not match the requested domain name', 'ssl.no_match');
129
		}
130
131
		if (!$socket) {
132
			if ($errno === 0) {
133
				// Connection issue
134
				throw new Requests_Exception(rtrim($this->connect_error), 'fsockopen.connect_error');
135
			}
136
137
			throw new Requests_Exception($errstr, 'fsockopenerror', null, $errno);
138
		}
139
140
		$data_format = $options['data_format'];
141
142
		if ($data_format === 'query') {
143
			$path = self::format_get($url_parts, $data);
0 ignored issues
show
Bug introduced by
It seems like $data defined by parameter $data on line 58 can also be of type string; however, Requests_Transport_fsockopen::format_get() does only seem to accept array|object, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
144
			$data = '';
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $data. This often makes code more readable.
Loading history...
145
		}
146
		else {
147
			$path = self::format_get($url_parts, array());
148
		}
149
150
		$options['hooks']->dispatch('fsockopen.remote_host_path', array(&$path, $url));
151
152
		$request_body = '';
153
		$out = sprintf("%s %s HTTP/%.1f\r\n", $options['type'], $path, $options['protocol_version']);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
154
155
		if ($options['type'] !== Requests::TRACE) {
156
			if (is_array($data)) {
157
				$request_body = http_build_query($data, null, '&');
158
			}
159
			else {
160
				$request_body = $data;
161
			}
162
163
			if (!empty($data)) {
164
				if (!isset($case_insensitive_headers['Content-Length'])) {
165
					$headers['Content-Length'] = strlen($request_body);
166
				}
167
168
				if (!isset($case_insensitive_headers['Content-Type'])) {
169
					$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
170
				}
171
			}
172
		}
173
174
		if (!isset($case_insensitive_headers['Host'])) {
175
			$out .= sprintf('Host: %s', $url_parts['host']);
176
177
			if (( 'http' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 80 ) || ( 'https' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 443 )) {
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 168 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
178
				$out .= ':' . $url_parts['port'];
179
			}
180
			$out .= "\r\n";
181
		}
182
183
		if (!isset($case_insensitive_headers['User-Agent'])) {
184
			$out .= sprintf("User-Agent: %s\r\n", $options['useragent']);
185
		}
186
187
		$accept_encoding = $this->accept_encoding();
188
		if (!isset($case_insensitive_headers['Accept-Encoding']) && !empty($accept_encoding)) {
189
			$out .= sprintf("Accept-Encoding: %s\r\n", $accept_encoding);
190
		}
191
192
		$headers = Requests::flatten($headers);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $headers. This often makes code more readable.
Loading history...
193
194
		if (!empty($headers)) {
195
			$out .= implode($headers, "\r\n") . "\r\n";
196
		}
197
198
		$options['hooks']->dispatch('fsockopen.after_headers', array(&$out));
199
200
		if (substr($out, -2) !== "\r\n") {
201
			$out .= "\r\n";
202
		}
203
204
		if (!isset($case_insensitive_headers['Connection'])) {
205
			$out .= "Connection: Close\r\n";
206
		}
207
208
		$out .= "\r\n" . $request_body;
209
210
		$options['hooks']->dispatch('fsockopen.before_send', array(&$out));
211
212
		fwrite($socket, $out);
213
		$options['hooks']->dispatch('fsockopen.after_send', array($out));
214
215
		if (!$options['blocking']) {
216
			fclose($socket);
217
			$fake_headers = '';
218
			$options['hooks']->dispatch('fsockopen.after_request', array(&$fake_headers));
219
			return '';
220
		}
221
222
		$timeout_sec = (int) floor($options['timeout']);
223
		if ($timeout_sec == $options['timeout']) {
224
			$timeout_msec = 0;
225
		}
226
		else {
227
			$timeout_msec = self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
228
		}
229
		stream_set_timeout($socket, $timeout_sec, $timeout_msec);
230
231
		$response = $body = $headers = '';
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $headers. This often makes code more readable.
Loading history...
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
232
		$this->info = stream_get_meta_data($socket);
233
		$size = 0;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
234
		$doingbody = false;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
235
		$download = false;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
236
		if ($options['filename']) {
237
			$download = fopen($options['filename'], 'wb');
238
		}
239
240
		while (!feof($socket)) {
241
			$this->info = stream_get_meta_data($socket);
242
			if ($this->info['timed_out']) {
243
				throw new Requests_Exception('fsocket timed out', 'timeout');
244
			}
245
246
			$block = fread($socket, Requests::BUFFER_SIZE);
247
			if (!$doingbody) {
248
				$response .= $block;
249
				if (strpos($response, "\r\n\r\n")) {
250
					list($headers, $block) = explode("\r\n\r\n", $response, 2);
251
					$doingbody = true;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 13 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
252
				}
253
			}
254
255
			// Are we in body mode now?
256
			if ($doingbody) {
257
				$options['hooks']->dispatch('request.progress', array($block, $size, $this->max_bytes));
258
				$data_length = strlen($block);
259
				if ($this->max_bytes) {
260
					// Have we already hit a limit?
261
					if ($size === $this->max_bytes) {
262
						continue;
263
					}
264
					if (($size + $data_length) > $this->max_bytes) {
265
						// Limit the length
266
						$limited_length = ($this->max_bytes - $size);
267
						$block = substr($block, 0, $limited_length);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 10 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
268
					}
269
				}
270
271
				$size += strlen($block);
272
				if ($download) {
273
					fwrite($download, $block);
274
				}
275
				else {
276
					$body .= $block;
277
				}
278
			}
279
		}
280
		$this->headers = $headers;
281
282
		if ($download) {
283
			fclose($download);
284
		}
285
		else {
286
			$this->headers .= "\r\n\r\n" . $body;
287
		}
288
		fclose($socket);
289
290
		$options['hooks']->dispatch('fsockopen.after_request', array(&$this->headers, &$this->info));
291
		return $this->headers;
292
	}
293
294
	/**
295
	 * Send multiple requests simultaneously
296
	 *
297
	 * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
298
	 * @param array $options Global options, see {@see Requests::response()} for documentation
299
	 * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
300
	 */
301
	public function request_multiple($requests, $options) {
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
302
		$responses = array();
303
		$class = get_class($this);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
304
		foreach ($requests as $id => $request) {
305
			try {
306
				$handler = new $class();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 8 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
307
				$responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
308
309
				$request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
310
			}
311
			catch (Requests_Exception $e) {
312
				$responses[$id] = $e;
313
			}
314
315 View Code Duplication
			if (!is_string($responses[$id])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
316
				$request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id));
317
			}
318
		}
319
320
		return $responses;
321
	}
322
323
	/**
324
	 * Retrieve the encodings we can accept
325
	 *
326
	 * @return string Accept-Encoding header value
327
	 */
328
	protected static function accept_encoding() {
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
329
		$type = array();
330
		if (function_exists('gzinflate')) {
331
			$type[] = 'deflate;q=1.0';
332
		}
333
334
		if (function_exists('gzuncompress')) {
335
			$type[] = 'compress;q=0.5';
336
		}
337
338
		$type[] = 'gzip;q=0.5';
339
340
		return implode(', ', $type);
341
	}
342
343
	/**
344
	 * Format a URL given GET data
345
	 *
346
	 * @param array $url_parts
347
	 * @param array|object $data Data to build query using, see {@see https://secure.php.net/http_build_query}
348
	 * @return string URL with data
349
	 */
350
	protected static function format_get($url_parts, $data) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $url_parts is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
351
		if (!empty($data)) {
352
			if (empty($url_parts['query'])) {
353
				$url_parts['query'] = '';
354
			}
355
356
			$url_parts['query'] .= '&' . http_build_query($data, null, '&');
357
			$url_parts['query'] = trim($url_parts['query'], '&');
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
358
		}
359
		if (isset($url_parts['path'])) {
360
			if (isset($url_parts['query'])) {
361
				$get = $url_parts['path'] . '?' . $url_parts['query'];
362
			}
363
			else {
364
				$get = $url_parts['path'];
365
			}
366
		}
367
		else {
368
			$get = '/';
369
		}
370
		return $get;
371
	}
372
373
	/**
374
	 * Error handler for stream_socket_client()
375
	 *
376
	 * @param int $errno Error number (e.g. E_WARNING)
377
	 * @param string $errstr Error message
378
	 */
379
	public function connect_error_handler($errno, $errstr) {
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
380
		// Double-check we can handle it
381
		if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
382
			// Return false to indicate the default error handler should engage
383
			return false;
384
		}
385
386
		$this->connect_error .= $errstr . "\n";
387
		return true;
388
	}
389
390
	/**
391
	 * Verify the certificate against common name and subject alternative names
392
	 *
393
	 * Unfortunately, PHP doesn't check the certificate against the alternative
394
	 * names, leading things like 'https://www.github.com/' to be invalid.
395
	 * Instead
396
	 *
397
	 * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
398
	 *
399
	 * @throws Requests_Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`)
400
	 * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
401
	 * @param string $host Host name to verify against
402
	 * @param resource $context Stream context
403
	 * @return bool
404
	 */
405
	public function verify_certificate_from_context($host, $context) {
0 ignored issues
show
Coding Style introduced by
This method is not in camel caps format.

This check looks for method names that are not written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection seeker becomes databaseConnectionSeeker.

Loading history...
406
		$meta = stream_context_get_options($context);
407
408
		// If we don't have SSL options, then we couldn't make the connection at
409
		// all
410
		if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) {
411
			throw new Requests_Exception(rtrim($this->connect_error), 'ssl.connect_error');
412
		}
413
414
		$cert = openssl_x509_parse($meta['ssl']['peer_certificate']);
415
416
		return Requests_SSL::verify_certificate($host, $cert);
417
	}
418
419
	/**
420
	 * Whether this transport is valid
421
	 *
422
	 * @codeCoverageIgnore
423
	 * @return boolean True if the transport is valid, false otherwise.
424
	 */
425
	public static function test($capabilities = array()) {
426
		if (!function_exists('fsockopen')) {
427
			return false;
428
		}
429
430
		// If needed, check that streams support SSL
431
		if (isset($capabilities['ssl']) && $capabilities['ssl']) {
432
			if (!extension_loaded('openssl') || !function_exists('openssl_x509_parse')) {
433
				return false;
434
			}
435
436
			// Currently broken, thanks to https://github.com/facebook/hhvm/issues/2156
437
			if (defined('HHVM_VERSION')) {
438
				return false;
439
			}
440
		}
441
442
		return true;
443
	}
444
}
0 ignored issues
show
Coding Style introduced by
As per coding style, files should not end with a newline character.

This check marks files that end in a newline character, i.e. an empy line.

Loading history...
445