Issues (1191)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

php/Requests/libary/Requests.php (62 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Requests for PHP
4
 *
5
 * Inspired by Requests for Python.
6
 *
7
 * Based on concepts from SimplePie_File, RequestCore and WP_Http.
8
 *
9
 * @package Requests
10
 */
11
12
/**
13
 * Requests for PHP
14
 *
15
 * Inspired by Requests for Python.
16
 *
17
 * Based on concepts from SimplePie_File, RequestCore and WP_Http.
18
 *
19
 * @package Requests
20
 */
21
class Requests {
0 ignored issues
show
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
The property $certificate_path 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...
22
	/**
23
	 * POST method
24
	 *
25
	 * @var string
26
	 */
27
	const POST = 'POST';
28
29
	/**
30
	 * PUT method
31
	 *
32
	 * @var string
33
	 */
34
	const PUT = 'PUT';
35
36
	/**
37
	 * GET method
38
	 *
39
	 * @var string
40
	 */
41
	const GET = 'GET';
42
43
	/**
44
	 * HEAD method
45
	 *
46
	 * @var string
47
	 */
48
	const HEAD = 'HEAD';
49
50
	/**
51
	 * DELETE method
52
	 *
53
	 * @var string
54
	 */
55
	const DELETE = 'DELETE';
56
57
	/**
58
	 * OPTIONS method
59
	 *
60
	 * @var string
61
	 */
62
	const OPTIONS = 'OPTIONS';
63
64
	/**
65
	 * TRACE method
66
	 *
67
	 * @var string
68
	 */
69
	const TRACE = 'TRACE';
70
71
	/**
72
	 * PATCH method
73
	 *
74
	 * @link https://tools.ietf.org/html/rfc5789
75
	 * @var string
76
	 */
77
	const PATCH = 'PATCH';
78
79
	/**
80
	 * Default size of buffer size to read streams
81
	 *
82
	 * @var integer
83
	 */
84
	const BUFFER_SIZE = 1160;
85
86
	/**
87
	 * Current version of Requests
88
	 *
89
	 * @var string
90
	 */
91
	const VERSION = '1.7';
92
93
	/**
94
	 * Registered transport classes
95
	 *
96
	 * @var array
97
	 */
98
	protected static $transports = array();
99
100
	/**
101
	 * Selected transport name
102
	 *
103
	 * Use {@see get_transport()} instead
104
	 *
105
	 * @var array
106
	 */
107
	public static $transport = array();
108
109
	/**
110
	 * Default certificate path.
111
	 *
112
	 * @see Requests::get_certificate_path()
113
	 * @see Requests::set_certificate_path()
114
	 *
115
	 * @var string
116
	 */
117
	protected static $certificate_path;
118
119
	/**
120
	 * This is a static class, do not instantiate it
121
	 *
122
	 * @codeCoverageIgnore
123
	 */
124
	private function __construct() {}
125
126
	/**
127
	 * Autoloader for Requests
128
	 *
129
	 * Register this with {@see register_autoloader()} if you'd like to avoid
130
	 * having to create your own.
131
	 *
132
	 * (You can also use `spl_autoload_register` directly if you'd prefer.)
133
	 *
134
	 * @codeCoverageIgnore
135
	 *
136
	 * @param string $class Class name to load
137
	 */
138
	public static function autoloader($class) {
139
		// Check that the class starts with "Requests"
140
		if (strpos($class, 'Requests') !== 0) {
141
			return;
142
		}
143
144
		$file = str_replace('_', '/', $class);
145
		if (file_exists(dirname(__FILE__) . '/' . $file . '.php')) {
146
			require_once(dirname(__FILE__) . '/' . $file . '.php');
147
		}
148
	}
149
150
	/**
151
	 * Register the built-in autoloader
152
	 *
153
	 * @codeCoverageIgnore
154
	 */
155
	public static function register_autoloader() {
0 ignored issues
show
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...
156
		spl_autoload_register(array('Requests', 'autoloader'));
157
	}
158
159
	/**
160
	 * Register a transport
161
	 *
162
	 * @param string $transport Transport class to add, must support the Requests_Transport interface
163
	 */
164
	public static function add_transport($transport) {
0 ignored issues
show
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...
165
		if (empty(self::$transports)) {
166
			self::$transports = array(
167
				'Requests_Transport_cURL',
168
				'Requests_Transport_fsockopen',
169
			);
170
		}
171
172
		self::$transports = array_merge(self::$transports, array($transport));
173
	}
174
175
	/**
176
	 * Get a working transport
177
	 *
178
	 * @throws Requests_Exception If no valid transport is found (`notransport`)
179
	 * @return Requests_Transport
180
	 */
181
	protected static function get_transport($capabilities = array()) {
0 ignored issues
show
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...
182
		// Caching code, don't bother testing coverage
183
		// @codeCoverageIgnoreStart
184
		// array of capabilities as a string to be used as an array key
185
		ksort($capabilities);
186
		$cap_string = serialize($capabilities);
187
188
		// Don't search for a transport if it's already been done for these $capabilities
189
		if (isset(self::$transport[$cap_string]) && self::$transport[$cap_string] !== null) {
190
			return new self::$transport[$cap_string]();
191
		}
192
		// @codeCoverageIgnoreEnd
193
194
		if (empty(self::$transports)) {
195
			self::$transports = array(
196
				'Requests_Transport_cURL',
197
				'Requests_Transport_fsockopen',
198
			);
199
		}
200
201
		// Find us a working transport
202
		foreach (self::$transports as $class) {
203
			if (!class_exists($class)) {
204
				continue;
205
			}
206
207
			$result = call_user_func(array($class, 'test'), $capabilities);
208
			if ($result) {
209
				self::$transport[$cap_string] = $class;
210
				break;
211
			}
212
		}
213
		if (self::$transport[$cap_string] === null) {
214
			throw new Requests_Exception('No working transports found', 'notransport', self::$transports);
215
		}
216
217
		return new self::$transport[$cap_string]();
218
	}
219
220
	/**#@+
221
	 * @see request()
222
	 * @param string $url
223
	 * @param array $headers
224
	 * @param array $options
225
	 * @return Requests_Response
226
	 */
227
	/**
228
	 * Send a GET request
229
	 */
230
	public static function get($url, $headers = array(), $options = array()) {
231
		return self::request($url, $headers, null, self::GET, $options);
232
	}
233
234
	/**
235
	 * Send a HEAD request
236
	 */
237
	public static function head($url, $headers = array(), $options = array()) {
238
		return self::request($url, $headers, null, self::HEAD, $options);
239
	}
240
241
	/**
242
	 * Send a DELETE request
243
	 */
244
	public static function delete($url, $headers = array(), $options = array()) {
245
		return self::request($url, $headers, null, self::DELETE, $options);
246
	}
247
248
	/**
249
	 * Send a TRACE request
250
	 */
251
	public static function trace($url, $headers = array(), $options = array()) {
252
		return self::request($url, $headers, null, self::TRACE, $options);
253
	}
254
	/**#@-*/
255
256
	/**#@+
257
	 * @see request()
258
	 * @param string $url
259
	 * @param array $headers
260
	 * @param array $data
261
	 * @param array $options
262
	 * @return Requests_Response
263
	 */
264
	/**
265
	 * Send a POST request
266
	 */
267
	public static function post($url, $headers = array(), $data = array(), $options = array()) {
268
		return self::request($url, $headers, $data, self::POST, $options);
269
	}
270
	/**
271
	 * Send a PUT request
272
	 */
273
	public static function put($url, $headers = array(), $data = array(), $options = array()) {
274
		return self::request($url, $headers, $data, self::PUT, $options);
275
	}
276
277
	/**
278
	 * Send an OPTIONS request
279
	 */
280
	public static function options($url, $headers = array(), $data = array(), $options = array()) {
281
		return self::request($url, $headers, $data, self::OPTIONS, $options);
282
	}
283
284
	/**
285
	 * Send a PATCH request
286
	 *
287
	 * Note: Unlike {@see post} and {@see put}, `$headers` is required, as the
288
	 * specification recommends that should send an ETag
289
	 *
290
	 * @link https://tools.ietf.org/html/rfc5789
291
	 */
292
	public static function patch($url, $headers, $data = array(), $options = array()) {
293
		return self::request($url, $headers, $data, self::PATCH, $options);
294
	}
295
	/**#@-*/
296
297
	/**
298
	 * Main interface for HTTP requests
299
	 *
300
	 * This method initiates a request and sends it via a transport before
301
	 * parsing.
302
	 *
303
	 * The `$options` parameter takes an associative array with the following
304
	 * options:
305
	 *
306
	 * - `timeout`: How long should we wait for a response?
307
	 *    Note: for cURL, a minimum of 1 second applies, as DNS resolution
308
	 *    operates at second-resolution only.
309
	 *    (float, seconds with a millisecond precision, default: 10, example: 0.01)
310
	 * - `connect_timeout`: How long should we wait while trying to connect?
311
	 *    (float, seconds with a millisecond precision, default: 10, example: 0.01)
312
	 * - `useragent`: Useragent to send to the server
313
	 *    (string, default: php-requests/$version)
314
	 * - `follow_redirects`: Should we follow 3xx redirects?
315
	 *    (boolean, default: true)
316
	 * - `redirects`: How many times should we redirect before erroring?
317
	 *    (integer, default: 10)
318
	 * - `blocking`: Should we block processing on this request?
319
	 *    (boolean, default: true)
320
	 * - `filename`: File to stream the body to instead.
321
	 *    (string|boolean, default: false)
322
	 * - `auth`: Authentication handler or array of user/password details to use
323
	 *    for Basic authentication
324
	 *    (Requests_Auth|array|boolean, default: false)
325
	 * - `proxy`: Proxy details to use for proxy by-passing and authentication
326
	 *    (Requests_Proxy|array|string|boolean, default: false)
327
	 * - `max_bytes`: Limit for the response body size.
328
	 *    (integer|boolean, default: false)
329
	 * - `idn`: Enable IDN parsing
330
	 *    (boolean, default: true)
331
	 * - `transport`: Custom transport. Either a class name, or a
332
	 *    transport object. Defaults to the first working transport from
333
	 *    {@see getTransport()}
334
	 *    (string|Requests_Transport, default: {@see getTransport()})
335
	 * - `hooks`: Hooks handler.
336
	 *    (Requests_Hooker, default: new Requests_Hooks())
337
	 * - `verify`: Should we verify SSL certificates? Allows passing in a custom
338
	 *    certificate file as a string. (Using true uses the system-wide root
339
	 *    certificate store instead, but this may have different behaviour
340
	 *    across transports.)
341
	 *    (string|boolean, default: library/Requests/Transport/cacert.pem)
342
	 * - `verifyname`: Should we verify the common name in the SSL certificate?
343
	 *    (boolean: default, true)
344
	 * - `data_format`: How should we send the `$data` parameter?
345
	 *    (string, one of 'query' or 'body', default: 'query' for
346
	 *    HEAD/GET/DELETE, 'body' for POST/PUT/OPTIONS/PATCH)
347
	 *
348
	 * @throws Requests_Exception On invalid URLs (`nonhttp`)
349
	 *
350
	 * @param string $url URL to request
351
	 * @param array $headers Extra headers to send with the request
352
	 * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 121 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...
353
	 * @param string $type HTTP request type (use Requests constants)
354
	 * @param array $options Options for the request (see description for more information)
355
	 * @return Requests_Response
356
	 */
357
	public static function request($url, $headers = array(), $data = array(), $type = self::GET, $options = array()) {
358
		if (empty($options['type'])) {
359
			$options['type'] = $type;
360
		}
361
		$options = array_merge(self::get_default_options(), $options);
0 ignored issues
show
Consider using a different name than the parameter $options. This often makes code more readable.
Loading history...
362
363
		self::set_defaults($url, $headers, $data, $type, $options);
364
365
		$options['hooks']->dispatch('requests.before_request', array(&$url, &$headers, &$data, &$type, &$options));
366
367
		if (!empty($options['transport'])) {
368
			$transport = $options['transport'];
369
370
			if (is_string($options['transport'])) {
371
				$transport = new $transport();
372
			}
373
		}
374
		else {
375
			$need_ssl = (0 === stripos($url, 'https://'));
0 ignored issues
show
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...
376
			$capabilities = array('ssl' => $need_ssl);
377
			$transport = self::get_transport($capabilities);
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 4 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...
378
		}
379
		$response = $transport->request($url, $headers, $data, $options);
380
381
		$options['hooks']->dispatch('requests.before_parse', array(&$response, $url, $headers, $data, $type, $options));
382
383
		return self::parse_response($response, $url, $headers, $data, $options);
0 ignored issues
show
It seems like $data defined by parameter $data on line 357 can also be of type null; however, Requests::parse_response() does only seem to accept array, 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...
384
	}
385
386
	/**
387
	 * Send multiple HTTP requests simultaneously
388
	 *
389
	 * The `$requests` parameter takes an associative or indexed array of
390
	 * request fields. The key of each request can be used to match up the
391
	 * request with the returned data, or with the request passed into your
392
	 * `multiple.request.complete` callback.
393
	 *
394
	 * The request fields value is an associative array with the following keys:
395
	 *
396
	 * - `url`: Request URL Same as the `$url` parameter to
397
	 *    {@see Requests::request}
398
	 *    (string, required)
399
	 * - `headers`: Associative array of header fields. Same as the `$headers`
400
	 *    parameter to {@see Requests::request}
401
	 *    (array, default: `array()`)
402
	 * - `data`: Associative array of data fields or a string. Same as the
403
	 *    `$data` parameter to {@see Requests::request}
404
	 *    (array|string, default: `array()`)
405
	 * - `type`: HTTP request type (use Requests constants). Same as the `$type`
406
	 *    parameter to {@see Requests::request}
407
	 *    (string, default: `Requests::GET`)
408
	 * - `cookies`: Associative array of cookie name to value, or cookie jar.
409
	 *    (array|Requests_Cookie_Jar)
410
	 *
411
	 * If the `$options` parameter is specified, individual requests will
412
	 * inherit options from it. This can be used to use a single hooking system,
413
	 * or set all the types to `Requests::POST`, for example.
414
	 *
415
	 * In addition, the `$options` parameter takes the following global options:
416
	 *
417
	 * - `complete`: A callback for when a request is complete. Takes two
418
	 *    parameters, a Requests_Response/Requests_Exception reference, and the
419
	 *    ID from the request array (Note: this can also be overridden on a
420
	 *    per-request basis, although that's a little silly)
421
	 *    (callback)
422
	 *
423
	 * @param array $requests Requests data (see description for more information)
424
	 * @param array $options Global and default options (see {@see Requests::request})
425
	 * @return array Responses (either Requests_Response or a Requests_Exception object)
426
	 */
427
	public static function request_multiple($requests, $options = array()) {
0 ignored issues
show
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...
428
		$options = array_merge(self::get_default_options(true), $options);
0 ignored issues
show
Consider using a different name than the parameter $options. This often makes code more readable.
Loading history...
429
430
		if (!empty($options['hooks'])) {
431
			$options['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
432
			if (!empty($options['complete'])) {
433
				$options['hooks']->register('multiple.request.complete', $options['complete']);
434
			}
435
		}
436
437
		foreach ($requests as $id => &$request) {
438
			if (!isset($request['headers'])) {
439
				$request['headers'] = array();
440
			}
441
			if (!isset($request['data'])) {
442
				$request['data'] = array();
443
			}
444
			if (!isset($request['type'])) {
445
				$request['type'] = self::GET;
446
			}
447
			if (!isset($request['options'])) {
448
				$request['options'] = $options;
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 9 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...
449
				$request['options']['type'] = $request['type'];
450
			}
451
			else {
452
				if (empty($request['options']['type'])) {
453
					$request['options']['type'] = $request['type'];
454
				}
455
				$request['options'] = array_merge($options, $request['options']);
456
			}
457
458
			self::set_defaults($request['url'], $request['headers'], $request['data'], $request['type'], $request['options']);
459
460
			// Ensure we only hook in once
461
			if ($request['options']['hooks'] !== $options['hooks']) {
462
				$request['options']['hooks']->register('transport.internal.parse_response', array('Requests', 'parse_multiple'));
463
				if (!empty($request['options']['complete'])) {
464
					$request['options']['hooks']->register('multiple.request.complete', $request['options']['complete']);
465
				}
466
			}
467
		}
468
		unset($request);
469
470
		if (!empty($options['transport'])) {
471
			$transport = $options['transport'];
472
473
			if (is_string($options['transport'])) {
474
				$transport = new $transport();
475
			}
476
		}
477
		else {
478
			$transport = self::get_transport();
479
		}
480
		$responses = $transport->request_multiple($requests, $options);
481
482
		foreach ($responses as $id => &$response) {
483
			// If our hook got messed with somehow, ensure we end up with the
484
			// correct response
485
			if (is_string($response)) {
486
				$request = $requests[$id];
487
				self::parse_multiple($response, $request);
488
				$request['options']['hooks']->dispatch('multiple.request.complete', array(&$response, $id));
489
			}
490
		}
491
492
		return $responses;
493
	}
494
495
	/**
496
	 * Get the default options
497
	 *
498
	 * @see Requests::request() for values returned by this method
499
	 * @param boolean $multirequest Is this a multirequest?
500
	 * @return array Default option values
0 ignored issues
show
Consider making the return type a bit more specific; maybe use array<string,integer|string|double|boolean|null>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
501
	 */
502
	protected static function get_default_options($multirequest = false) {
0 ignored issues
show
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...
503
		$defaults = array(
504
			'timeout' => 10,
505
			'connect_timeout' => 10,
506
			'useragent' => 'php-requests/' . self::VERSION,
507
			'protocol_version' => 1.1,
508
			'redirected' => 0,
509
			'redirects' => 10,
510
			'follow_redirects' => true,
511
			'blocking' => true,
512
			'type' => self::GET,
513
			'filename' => false,
514
			'auth' => false,
515
			'proxy' => false,
516
			'cookies' => false,
517
			'max_bytes' => false,
518
			'idn' => true,
519
			'hooks' => null,
520
			'transport' => null,
521
			'verify' => Requests::get_certificate_path(),
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
522
			'verifyname' => true,
523
		);
524
		if ($multirequest !== false) {
525
			$defaults['complete'] = null;
526
		}
527
		return $defaults;
528
	}
529
530
	/**
531
	 * Get default certificate path.
532
	 *
533
	 * @return string Default certificate path.
534
	 */
535
	public static function get_certificate_path() {
0 ignored issues
show
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...
536
		if ( ! empty( Requests::$certificate_path ) ) {
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
537
			return Requests::$certificate_path;
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
538
		}
539
540
		return dirname(__FILE__) . '/Requests/Transport/cacert.pem';
541
	}
542
543
	/**
544
	 * Set default certificate path.
545
	 *
546
	 * @param string $path Certificate path, pointing to a PEM file.
547
	 */
548
	public static function set_certificate_path( $path ) {
0 ignored issues
show
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...
549
		Requests::$certificate_path = $path;
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
550
	}
551
552
	/**
553
	 * Set the default values
554
	 *
555
	 * @param string $url URL to request
556
	 * @param array $headers Extra headers to send with the request
557
	 * @param array|null $data Data to send either as a query string for GET/HEAD requests, or in the body for POST requests
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 121 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...
558
	 * @param string $type HTTP request type
559
	 * @param array $options Options for the request
560
	 * @return array $options
0 ignored issues
show
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
561
	 */
562
	protected static function set_defaults(&$url, &$headers, &$data, &$type, &$options) {
0 ignored issues
show
The parameter $headers is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
The parameter $data is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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...
563
		if (!preg_match('/^http(s)?:\/\//i', $url, $matches)) {
564
			throw new Requests_Exception('Only HTTP(S) requests are handled.', 'nonhttp', $url);
565
		}
566
567
		if (empty($options['hooks'])) {
568
			$options['hooks'] = new Requests_Hooks();
569
		}
570
571
		if (is_array($options['auth'])) {
572
			$options['auth'] = new Requests_Auth_Basic($options['auth']);
573
		}
574
		if ($options['auth'] !== false) {
575
			$options['auth']->register($options['hooks']);
576
		}
577
578
		if (is_string($options['proxy']) || is_array($options['proxy'])) {
579
			$options['proxy'] = new Requests_Proxy_HTTP($options['proxy']);
0 ignored issues
show
It seems like $options['proxy'] can also be of type string; however, Requests_Proxy_HTTP::__construct() does only seem to accept array|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
580
		}
581
		if ($options['proxy'] !== false) {
582
			$options['proxy']->register($options['hooks']);
583
		}
584
585
		if (is_array($options['cookies'])) {
586
			$options['cookies'] = new Requests_Cookie_Jar($options['cookies']);
587
		}
588
		elseif (empty($options['cookies'])) {
589
			$options['cookies'] = new Requests_Cookie_Jar();
590
		}
591
		if ($options['cookies'] !== false) {
592
			$options['cookies']->register($options['hooks']);
593
		}
594
595
		if ($options['idn'] !== false) {
596
			$iri = new Requests_IRI($url);
0 ignored issues
show
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...
597
			$iri->host = Requests_IDNAEncoder::encode($iri->ihost);
598
			$url = $iri->uri;
0 ignored issues
show
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...
599
		}
600
601
		// Massage the type to ensure we support it.
602
		$type = strtoupper($type);
603
604
		if (!isset($options['data_format'])) {
605
			if (in_array($type, array(self::HEAD, self::GET, self::DELETE))) {
606
				$options['data_format'] = 'query';
607
			}
608
			else {
609
				$options['data_format'] = 'body';
610
			}
611
		}
612
	}
613
614
	/**
615
	 * HTTP response parser
616
	 *
617
	 * @throws Requests_Exception On missing head/body separator (`requests.no_crlf_separator`)
618
	 * @throws Requests_Exception On missing head/body separator (`noversion`)
619
	 * @throws Requests_Exception On missing head/body separator (`toomanyredirects`)
620
	 *
621
	 * @param string $headers Full response text including headers and body
622
	 * @param string $url Original request URL
623
	 * @param array $req_headers Original $headers array passed to {@link request()}, in case we need to follow redirects
624
	 * @param array $req_data Original $data array passed to {@link request()}, in case we need to follow redirects
625
	 * @param array $options Original $options array passed to {@link request()}, in case we need to follow redirects
626
	 * @return Requests_Response
627
	 */
628
	protected static function parse_response($headers, $url, $req_headers, $req_data, $options) {
0 ignored issues
show
Coding Style Naming introduced by
The parameter $req_headers 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 Naming introduced by
The parameter $req_data 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...
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...
629
		$return = new Requests_Response();
630
		if (!$options['blocking']) {
631
			return $return;
632
		}
633
634
		$return->raw = $headers;
635
		$return->url = $url;
636
637
		if (!$options['filename']) {
638
			if (($pos = strpos($headers, "\r\n\r\n")) === false) {
639
				// Crap!
640
				throw new Requests_Exception('Missing header/body separator', 'requests.no_crlf_separator');
641
			}
642
643
			$headers = substr($return->raw, 0, $pos);
0 ignored issues
show
Consider using a different name than the parameter $headers. This often makes code more readable.
Loading history...
Equals sign not aligned with surrounding assignments; expected 6 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...
644
			$return->body = substr($return->raw, $pos + strlen("\n\r\n\r"));
645
		}
646
		else {
647
			$return->body = '';
648
		}
649
		// Pretend CRLF = LF for compatibility (RFC 2616, section 19.3)
650
		$headers = str_replace("\r\n", "\n", $headers);
0 ignored issues
show
Consider using a different name than the parameter $headers. This often makes code more readable.
Loading history...
651
		// Unfold headers (replace [CRLF] 1*( SP | HT ) with SP) as per RFC 2616 (section 2.2)
652
		$headers = preg_replace('/\n[ \t]/', ' ', $headers);
0 ignored issues
show
Consider using a different name than the parameter $headers. This often makes code more readable.
Loading history...
653
		$headers = explode("\n", $headers);
0 ignored issues
show
Consider using a different name than the parameter $headers. This often makes code more readable.
Loading history...
654
		preg_match('#^HTTP/(1\.\d)[ \t]+(\d+)#i', array_shift($headers), $matches);
655
		if (empty($matches)) {
656
			throw new Requests_Exception('Response could not be parsed', 'noversion', $headers);
657
		}
658
		$return->protocol_version = (float) $matches[1];
659
		$return->status_code = (int) $matches[2];
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 6 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...
660
		if ($return->status_code >= 200 && $return->status_code < 300) {
661
			$return->success = true;
662
		}
663
664
		foreach ($headers as $header) {
665
			list($key, $value) = explode(':', $header, 2);
666
			$value = trim($value);
0 ignored issues
show
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...
667
			preg_replace('#(\s+)#i', ' ', $value);
668
			$return->headers[$key] = $value;
669
		}
670
		if (isset($return->headers['transfer-encoding'])) {
671
			$return->body = self::decode_chunked($return->body);
672
			unset($return->headers['transfer-encoding']);
673
		}
674
		if (isset($return->headers['content-encoding'])) {
675
			$return->body = self::decompress($return->body);
676
		}
677
678
		//fsockopen and cURL compatibility
679
		if (isset($return->headers['connection'])) {
680
			unset($return->headers['connection']);
681
		}
682
683
		$options['hooks']->dispatch('requests.before_redirect_check', array(&$return, $req_headers, $req_data, $options));
684
685
		if ($return->is_redirect() && $options['follow_redirects'] === true) {
686
			if (isset($return->headers['location']) && $options['redirected'] < $options['redirects']) {
687
				if ($return->status_code === 303) {
688
					$options['type'] = self::GET;
689
				}
690
				$options['redirected']++;
691
				$location = $return->headers['location'];
692
				if (strpos($location, 'http://') !== 0 && strpos($location, 'https://') !== 0) {
693
					// relative redirect, for compatibility make it absolute
694
					$location = Requests_IRI::absolutize($url, $location);
695
					$location = $location->uri;
696
				}
697
698
				$hook_args = array(
699
					&$location,
700
					&$req_headers,
701
					&$req_data,
702
					&$options,
703
					$return
704
				);
705
				$options['hooks']->dispatch('requests.before_redirect', $hook_args);
706
				$redirected = self::request($location, $req_headers, $req_data, $options['type'], $options);
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 12 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...
707
				$redirected->history[] = $return;
708
				return $redirected;
709
			}
710
			elseif ($options['redirected'] >= $options['redirects']) {
711
				throw new Requests_Exception('Too many redirects', 'toomanyredirects', $return);
712
			}
713
		}
714
715
		$return->redirects = $options['redirected'];
716
717
		$options['hooks']->dispatch('requests.after_request', array(&$return, $req_headers, $req_data, $options));
718
		return $return;
719
	}
720
721
	/**
722
	 * Callback for `transport.internal.parse_response`
723
	 *
724
	 * Internal use only. Converts a raw HTTP response to a Requests_Response
725
	 * while still executing a multiple request.
726
	 *
727
	 * @param string $response Full response text including headers and body (will be overwritten with Response instance)
728
	 * @param array $request Request data as passed into {@see Requests::request_multiple()}
729
	 * @return null `$response` is either set to a Requests_Response instance, or a Requests_Exception object
730
	 */
731
	public static function parse_multiple(&$response, $request) {
0 ignored issues
show
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...
732
		try {
733
			$url = $request['url'];
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 6 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...
734
			$headers = $request['headers'];
0 ignored issues
show
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...
735
			$data = $request['data'];
0 ignored issues
show
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...
736
			$options = $request['options'];
0 ignored issues
show
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...
737
			$response = self::parse_response($response, $url, $headers, $data, $options);
738
		}
739
		catch (Requests_Exception $e) {
740
			$response = $e;
741
		}
742
	}
743
744
	/**
745
	 * Decoded a chunked body as per RFC 2616
746
	 *
747
	 * @see https://tools.ietf.org/html/rfc2616#section-3.6.1
748
	 * @param string $data Chunked body
749
	 * @return string Decoded body
0 ignored issues
show
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
750
	 */
751
	protected static function decode_chunked($data) {
0 ignored issues
show
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...
752
		if (!preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', trim($data))) {
753
			return $data;
754
		}
755
756
757
758
		$decoded = '';
759
		$encoded = $data;
760
761
		while (true) {
762
			$is_chunked = (bool) preg_match('/^([0-9a-f]+)(?:;(?:[\w-]*)(?:=(?:(?:[\w-]*)*|"(?:[^\r\n])*"))?)*\r\n/i', $encoded, $matches);
0 ignored issues
show
This line exceeds maximum limit of 120 characters; contains 130 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...
763
			if (!$is_chunked) {
764
				// Looks like it's not chunked after all
765
				return $data;
766
			}
767
768
			$length = hexdec(trim($matches[1]));
769
			if ($length === 0) {
770
				// Ignore trailer headers
771
				return $decoded;
772
			}
773
774
			$chunk_length = strlen($matches[0]);
775
			$decoded .= substr($encoded, $chunk_length, $length);
0 ignored issues
show
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...
776
			$encoded = substr($encoded, $chunk_length + $length + 2);
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 6 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...
777
778
			if (trim($encoded) === '0' || empty($encoded)) {
779
				return $decoded;
780
			}
781
		}
782
783
		// We'll never actually get down here
784
		// @codeCoverageIgnoreStart
785
	}
786
	// @codeCoverageIgnoreEnd
787
788
	/**
789
	 * Convert a key => value array to a 'key: value' array for headers
790
	 *
791
	 * @param array $array Dictionary of header values
792
	 * @return array List of headers
793
	 */
794
	public static function flatten($array) {
795
		$return = array();
796
		foreach ($array as $key => $value) {
797
			$return[] = sprintf('%s: %s', $key, $value);
798
		}
799
		return $return;
800
	}
801
802
	/**
803
	 * Convert a key => value array to a 'key: value' array for headers
804
	 *
805
	 * @codeCoverageIgnore
806
	 * @deprecated Misspelling of {@see Requests::flatten}
807
	 * @param array $array Dictionary of header values
808
	 * @return array List of headers
809
	 */
810
	public static function flattern($array) {
811
		return self::flatten($array);
812
	}
813
814
	/**
815
	 * Decompress an encoded body
816
	 *
817
	 * Implements gzip, compress and deflate. Guesses which it is by attempting
818
	 * to decode.
819
	 *
820
	 * @param string $data Compressed data in one of the above formats
821
	 * @return string Decompressed string
822
	 */
823
	public static function decompress($data) {
824
		if (substr($data, 0, 2) !== "\x1f\x8b" && substr($data, 0, 2) !== "\x78\x9c") {
825
			// Not actually compressed. Probably cURL ruining this for us.
826
			return $data;
827
		}
828
829
		if (function_exists('gzdecode') && ($decoded = @gzdecode($data)) !== false) {
830
			return $decoded;
831
		}
832
		elseif (function_exists('gzinflate') && ($decoded = @gzinflate($data)) !== false) {
833
			return $decoded;
834
		}
835
		elseif (($decoded = self::compatible_gzinflate($data)) !== false) {
0 ignored issues
show
Bug Compatibility introduced by
The expression self::compatible_gzinflate($data); of type string|boolean adds the type boolean to the return on line 836 which is incompatible with the return type documented by Requests::decompress of type string.
Loading history...
836
			return $decoded;
837
		}
838
		elseif (function_exists('gzuncompress') && ($decoded = @gzuncompress($data)) !== false) {
839
			return $decoded;
840
		}
841
842
		return $data;
843
	}
844
845
	/**
846
	 * Decompression of deflated string while staying compatible with the majority of servers.
847
	 *
848
	 * Certain Servers will return deflated data with headers which PHP's gzinflate()
849
	 * function cannot handle out of the box. The following function has been created from
850
	 * various snippets on the gzinflate() PHP documentation.
851
	 *
852
	 * Warning: Magic numbers within. Due to the potential different formats that the compressed
853
	 * data may be returned in, some "magic offsets" are needed to ensure proper decompression
854
	 * takes place. For a simple progmatic way to determine the magic offset in use, see:
855
	 * https://core.trac.wordpress.org/ticket/18273
856
	 *
857
	 * @since 2.8.1
858
	 * @link https://core.trac.wordpress.org/ticket/18273
859
	 * @link https://secure.php.net/manual/en/function.gzinflate.php#70875
860
	 * @link https://secure.php.net/manual/en/function.gzinflate.php#77336
861
	 *
862
	 * @param string $gzData String to decompress.
863
	 * @return string|bool False on failure.
864
	 */
865
	public static function compatible_gzinflate($gzData) {
0 ignored issues
show
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...
866
		// Compressed data might contain a full zlib header, if so strip it for
867
		// gzinflate()
868
		if (substr($gzData, 0, 3) == "\x1f\x8b\x08") {
869
			$i = 10;
0 ignored issues
show
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...
870
			$flg = ord(substr($gzData, 3, 1));
871
			if ($flg > 0) {
872
				if ($flg & 4) {
873
					list($xlen) = unpack('v', substr($gzData, $i, 2));
874
					$i = $i + 2 + $xlen;
0 ignored issues
show
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...
875
				}
876
				if ($flg & 8) {
877
					$i = strpos($gzData, "\0", $i) + 1;
878
				}
879
				if ($flg & 16) {
880
					$i = strpos($gzData, "\0", $i) + 1;
881
				}
882
				if ($flg & 2) {
883
					$i = $i + 2;
884
				}
885
			}
886
			$decompressed = self::compatible_gzinflate(substr($gzData, $i));
887
			if (false !== $decompressed) {
888
				return $decompressed;
889
			}
890
		}
891
892
		// If the data is Huffman Encoded, we must first strip the leading 2
893
		// byte Huffman marker for gzinflate()
894
		// The response is Huffman coded by many compressors such as
895
		// java.util.zip.Deflater, Ruby’s Zlib::Deflate, and .NET's
896
		// System.IO.Compression.DeflateStream.
897
		//
898
		// See https://decompres.blogspot.com/ for a quick explanation of this
899
		// data type
900
		$huffman_encoded = false;
901
902
		// low nibble of first byte should be 0x08
903
		list(, $first_nibble)    = unpack('h', $gzData);
0 ignored issues
show
Equals sign not aligned correctly; expected 1 space but found 4 spaces

This check looks for improperly formatted assignments.

Every assignment must have exactly one space before and one space after the equals operator.

To illustrate:

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

will have no issues, while

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

will report issues in lines 1 and 2.

Loading history...
904
905
		// First 2 bytes should be divisible by 0x1F
906
		list(, $first_two_bytes) = unpack('n', $gzData);
907
908
		if (0x08 == $first_nibble && 0 == ($first_two_bytes % 0x1F)) {
909
			$huffman_encoded = true;
910
		}
911
912 View Code Duplication
		if ($huffman_encoded) {
0 ignored issues
show
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...
913
			if (false !== ($decompressed = @gzinflate(substr($gzData, 2)))) {
914
				return $decompressed;
915
			}
916
		}
917
918
		if ("\x50\x4b\x03\x04" == substr($gzData, 0, 4)) {
919
			// ZIP file format header
920
			// Offset 6: 2 bytes, General-purpose field
921
			// Offset 26: 2 bytes, filename length
922
			// Offset 28: 2 bytes, optional field length
923
			// Offset 30: Filename field, followed by optional field, followed
924
			// immediately by data
925
			list(, $general_purpose_flag) = unpack('v', substr($gzData, 6, 2));
926
927
			// If the file has been compressed on the fly, 0x08 bit is set of
928
			// the general purpose field. We can use this to differentiate
929
			// between a compressed document, and a ZIP file
930
			$zip_compressed_on_the_fly = (0x08 == (0x08 & $general_purpose_flag));
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $zip_compressed_on_the_fly 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...
931
932
			if (!$zip_compressed_on_the_fly) {
933
				// Don't attempt to decode a compressed zip file
934
				return $gzData;
935
			}
936
937
			// Determine the first byte of data, based on the above ZIP header
938
			// offsets:
939
			$first_file_start = array_sum(unpack('v2', substr($gzData, 26, 4)));
940 View Code Duplication
			if (false !== ($decompressed = @gzinflate(substr($gzData, 30 + $first_file_start)))) {
0 ignored issues
show
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...
941
				return $decompressed;
942
			}
943
			return false;
944
		}
945
946
		// Finally fall back to straight gzinflate
947
		if (false !== ($decompressed = @gzinflate($gzData))) {
948
			return $decompressed;
949
		}
950
951
		// Fallback for all above failing, not expected, but included for
952
		// debugging and preventing regressions and to track stats
953
		if (false !== ($decompressed = @gzinflate(substr($gzData, 2)))) {
954
			return $decompressed;
955
		}
956
957
		return false;
958
	}
959
960
	public static function match_domain($host, $reference) {
0 ignored issues
show
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...
961
		// Check for a direct match
962
		if ($host === $reference) {
963
			return true;
964
		}
965
966
		// Calculate the valid wildcard match if the host is not an IP address
967
		// Also validates that the host has 3 parts or more, as per Firefox's
968
		// ruleset.
969
		$parts = explode('.', $host);
970 View Code Duplication
		if (ip2long($host) === false && count($parts) >= 3) {
0 ignored issues
show
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...
971
			$parts[0] = '*';
972
			$wildcard = implode('.', $parts);
973
			if ($wildcard === $reference) {
974
				return true;
975
			}
976
		}
977
978
		return false;
979
	}
980
}
0 ignored issues
show
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...
981