GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Http::getQueryString()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 6
ccs 3
cts 3
cp 1
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Nip\Http\Request;
4
5
/**
6
 * Nip Framework
7
 *
8
 * @category   Nip
9
 * @copyright  2009 Nip Framework
10
 * @license    http://www.opensource.org/licenses/mit-license.php The MIT License
11
 * @version    SVN: $Id: Http.php 135 2009-05-27 16:48:23Z victor.stanciu $
12
 */
13
14
class Http
15
{
16
17
    protected $request;
18
19
    /**
20
     * @var string
21
     */
22
    protected $pathInfo;
23
24
    /**
25
     * @var string
26
     */
27
    protected $requestUri;
28
    /**
29
     * @var string
30
     */
31
    protected $baseUrl;
32
33
    /**
34
     * Normalizes a query string.
35
     *
36
     * It builds a normalized query string, where keys/value pairs are alphabetized,
37
     * have consistent escaping and unneeded delimiters are removed.
38
     *
39
     * @param string $qs Query string
40
     *
41
     * @return string A normalized query string for the Request
42
     */
43 1
    public static function normalizeQueryString($qs)
44
    {
45 1
        if ('' == $qs) {
46
            return '';
47
        }
48 1
        $parts = [];
49 1
        $order = [];
50 1
        foreach (explode('&', $qs) as $param) {
51 1
            if ('' === $param || '=' === $param[0]) {
52
                // Ignore useless delimiters, e.g. "x=y&".
53
                // Also ignore pairs with empty key, even if there was a value, e.g. "=value",
54
                // as such nameless values cannot be retrieved anyway.
55
                // PHP also does not include them when building _GET.
56
                continue;
57
            }
58 1
            $keyValuePair = explode('=', $param, 2);
59
            // GET parameters, that are submitted from a HTML form, encode spaces as "+" by default
60
            // (as defined in enctype application/x-www-form-urlencoded).
61
            // PHP also converts "+" to spaces when filling the global _GET or when using the function parse_str.
62
            // This is why we use urldecode and then normalize to
63
            // RFC 3986 with rawurlencode.
64 1
            $parts[] = isset($keyValuePair[1]) ?
65 1
                rawurlencode(urldecode($keyValuePair[0])) . '=' . rawurlencode(urldecode($keyValuePair[1])) :
66
                rawurlencode(urldecode($keyValuePair[0]));
67 1
            $order[] = urldecode($keyValuePair[0]);
68
        }
69 1
        array_multisort($order, SORT_ASC, $parts);
70
71 1
        return implode('&', $parts);
72
    }
73
74
    /**
75
     * Generates a normalized URI (URL) for the Request.
76
     *
77
     * @return string A normalized URI (URL) for the Request
78
     *
79
     * @see getQueryString()
80
     */
81 1
    public function getUri()
82
    {
83 1
        if (null !== $qs = $this->getQueryString()) {
84 1
            $qs = '?' . $qs;
85
        }
86 1
        return $this->getSchemeAndHttpHost() . $this->getBaseUrl() . $this->getRequest()->getPathInfo() . $qs;
87
    }
88
89
    /**
90
     * Generates the normalized query string for the Request.
91
     *
92
     * It builds a normalized query string, where keys/value pairs are alphabetized
93
     * and have consistent escaping.
94
     *
95
     * @return string|null A normalized query string for the Request
96
     */
97 1
    public function getQueryString()
98
    {
99 1
        $qs = static::normalizeQueryString($this->getRequest()->server->get('QUERY_STRING'));
100
101 1
        return '' === $qs ? null : $qs;
102
    }
103
104
    /**
105
     * @return mixed
106
     */
107 8
    public function getRequest()
108
    {
109 8
        return $this->request;
110
    }
111
112
    /*
113
     * The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24)
114
     *
115
     * Code subject to the new BSD license (http://framework.zend.com/license/new-bsd).
116
     *
117
     * Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
118
     */
119
120
    /**
121
     * @param mixed $request
122
     */
123 8
    public function setRequest($request)
124
    {
125 8
        $this->request = $request;
126 8
    }
127
128
    /**
129
     * Gets the scheme and HTTP host.
130
     *
131
     * If the URL was called with basic authentication, the user
132
     * and the password are not added to the generated string.
133
     *
134
     * @return string The scheme and HTTP host
135
     */
136 8
    public function getSchemeAndHttpHost()
137
    {
138 8
        return $this->getScheme() . '://' . $this->getHttpHost();
139
    }
140
141
    /**
142
     * Gets the request's scheme.
143
     *
144
     * @return string
145
     */
146 8
    public function getScheme()
147
    {
148 8
        return $this->isSecure() ? 'https' : 'http';
149
    }
150
151
    /**
152
     * @return bool
153
     */
154 8
    public function isSecure()
155
    {
156 8
        $https = $this->getRequest()->server->get('HTTPS');
157
158 8
        return !empty($https) && 'off' !== strtolower($https);
159
    }
160
161
    /**
162
     * Returns the HTTP host being requested.
163
     *
164
     * The port name will be appended to the host if it's non-standard.
165
     *
166
     * @return string
167
     */
168 8
    public function getHttpHost()
169
    {
170 8
        $scheme = $this->getScheme();
171 8
        $port = $this->getPort();
172 8
        if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) {
173 8
            return $this->getHost();
174
        }
175
176
        return $this->getHost() . ':' . $port;
177
    }
178
179
    /**
180
     * @return mixed
181
     */
182 8
    public function getPort()
183
    {
184 8
        return $this->getRequest()->server->get('SERVER_PORT');
185
    }
186
187
    /**
188
     * Returns the host name.
189
     *
190
     * This method can read the client host name from the "X-Forwarded-Host" header
191
     * when trusted proxies were set via "setTrustedProxies()".
192
     *
193
     * The "X-Forwarded-Host" header must contain the client host name.
194
     *
195
     * If your reverse proxy uses a different header name than "X-Forwarded-Host",
196
     * configure it via "setTrustedHeaderName()" with the "client-host" key.
197
     *
198
     * @return string
199
     *
200
     * @throws \UnexpectedValueException when the host name is invalid
201
     */
202 8
    public function getHost()
203
    {
204 8
        if (!$host = $this->getRequest()->headers->get('HOST')) {
205
            if (!$host = $this->getRequest()->server->get('SERVER_NAME')) {
206
                $host = $this->getRequest()->server->get('SERVER_ADDR', '');
207
            }
208
        }
209
        // trim and remove port number from host
210
        // host is lowercase as per RFC 952/2181
211 8
        $host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
212
213
        // as the host can come from the user (HTTP_HOST and depending on the configuration,
214
        // SERVER_NAME too can come from the user)
215
        // check that it does not contain forbidden characters (see RFC 952 and RFC 2181)
216
        // use preg_replace() instead of preg_match() to prevent DoS attacks with long host names
217 8
        if ($host && '' !== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/', '', $host)) {
218
            throw new \UnexpectedValueException(sprintf('Invalid Host "%s"', $host));
219
        }
220
221 8
        return $host;
222
    }
223
224
    /**
225
     * Returns the root URL from which this request is executed.
226
     *
227
     * The base URL never ends with a /.
228
     *
229
     * This is similar to getBasePath(), except that it also includes the
230
     * script filename (e.g. index.php) if one exists.
231
     *
232
     * @return string The raw URL (i.e. not urldecoded)
233
     */
234 8
    public function getBaseUrl()
235
    {
236 8
        if (null === $this->baseUrl) {
237 8
            $this->baseUrl = $this->prepareBaseUrl();
238
        }
239 8
        return $this->baseUrl;
240
    }
241
242
    /**
243
     * Returns the requested URI (path and query string).
244
     *
245
     * @return string The raw URI (i.e. not URI decoded)
246
     */
247 8
    public function getRequestUri()
248
    {
249 8
        if (null === $this->requestUri) {
250 8
            $this->requestUri = $this->prepareRequestUri();
251
        }
252 8
        return $this->requestUri;
253
    }
254
255
    /**
256
     * @return bool|mixed
257
     */
258 View Code Duplication
    public function getSubdomain()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
259
    {
260
        $name = $this->getServerName();
261
        if ($name) {
262
            if (substr_count($name, '.') > 1) {
263
                $parts = explode('.', $name);
264
                return reset($parts);
265
            }
266
        }
267
268
        return false;
269
    }
270
271
    /**
272
     * @return mixed
273
     */
274
    public function getServerName()
275
    {
276
        return $this->getRequest()->server->get('SERVER_NAME');
277
    }
278
279
    /**
280
     * @return bool|mixed|string
281
     */
282 View Code Duplication
    public function getRootDomain()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
283
    {
284
        $name = $this->getServerName();
285
        if ($name) {
286
            if (substr_count($name, '.') > 1) {
287
                $parts = explode('.', $name);
288
                array_shift($parts);
289
                return implode('.', $parts);
290
            }
291
            return $name;
292
        }
293
294
        return false;
295
    }
296
297
    /*
298
     * Returns the prefix as encoded in the string when the string starts with
299
     * the given prefix, false otherwise.
300
     *
301
     * @param string $string The urlencoded string
302
     * @param string $prefix The prefix not encoded
303
     *
304
     * @return string|false The prefix as it is encoded in $string, or false
305
     */
306
307
    /**
308
     * @return bool
309
     */
310
    public function isConsole()
311
    {
312
        if (php_sapi_name() === 'cli') {
313
            return true;
314
        }
315
        if (php_sapi_name() === 'cgi-fcgi') {
316
            return true;
317
        }
318
319
        return false;
320
    }
321
322
    /**
323
     * Prepares the base URL.
324
     *
325
     * @return string
326
     */
327 8
    protected function prepareBaseUrl()
328
    {
329 8
        $filename = basename($this->getRequest()->server->get('SCRIPT_FILENAME'));
330 8
        if (basename($this->getRequest()->server->get('SCRIPT_NAME')) === $filename) {
331 8
            $baseUrl = $this->getRequest()->server->get('SCRIPT_NAME');
332
        } elseif (basename($this->getRequest()->server->get('PHP_SELF')) === $filename) {
333
            $baseUrl = $this->getRequest()->server->get('PHP_SELF');
334
        } elseif (basename($this->getRequest()->server->get('ORIG_SCRIPT_NAME')) === $filename) {
335
            $baseUrl = $this->getRequest()->server->get('ORIG_SCRIPT_NAME'); // 1and1 shared hosting compatibility
336
        } else {
337
            // Backtrack up the script_filename to find the portion matching
338
            // php_self
339
            $path = $this->getRequest()->server->get('PHP_SELF', '');
340
            $file = $this->getRequest()->server->get('SCRIPT_FILENAME', '');
341
            $segs = explode('/', trim($file, '/'));
342
            $segs = array_reverse($segs);
343
            $index = 0;
344
            $last = count($segs);
345
            $baseUrl = '';
346
            do {
347
                $seg = $segs[$index];
348
                $baseUrl = '/' . $seg . $baseUrl;
349
                ++$index;
350
            } while ($last > $index && (false !== $pos = strpos($path, $baseUrl)) && 0 != $pos);
351
        }
352
        // Does the baseUrl have anything in common with the request_uri?
353 8
        $requestUri = $this->getRequestUri();
354 8
        if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri, $baseUrl)) {
355
            // full $baseUrl matches
356 2
            return $prefix;
357
        }
358 6
        if ($baseUrl && false !== $prefix = $this->getUrlencodedPrefix($requestUri,
359 6
                rtrim(dirname($baseUrl), '/' . DIRECTORY_SEPARATOR) . '/')
360
        ) {
361
            // directory portion of $baseUrl matches
362 5
            return rtrim($prefix, '/' . DIRECTORY_SEPARATOR);
363
        }
364 1
        $truncatedRequestUri = $requestUri;
365 1
        if (false !== $pos = strpos($requestUri, '?')) {
366 1
            $truncatedRequestUri = substr($requestUri, 0, $pos);
367
        }
368 1
        $basename = basename($baseUrl);
369 1
        if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
370
            // no match whatsoever; set it blank
371 1
            return '';
372
        }
373
        // If using mod_rewrite or ISAPI_Rewrite strip the script filename
374
        // out of baseUrl. $pos !== 0 makes sure it is not matching a value
375
        // from PATH_INFO or QUERY_STRING
376
        if (strlen($requestUri) >= strlen($baseUrl) && (false !== $pos = strpos($requestUri, $baseUrl)) && $pos !== 0) {
377
            $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
378
        }
379
        return rtrim($baseUrl, '/' . DIRECTORY_SEPARATOR);
380
    }
381
382
    /**
383
     * @return string
384
     */
385 8
    protected function prepareRequestUri()
386
    {
387 8
        $requestUri = '';
388 8
        if ($this->getRequest()->headers->has('X_ORIGINAL_URL')) {
389
            // IIS with Microsoft Rewrite Module
390
            $requestUri = $this->getRequest()->headers->get('X_ORIGINAL_URL');
391
            $this->getRequest()->headers->remove('X_ORIGINAL_URL');
392
            $this->getRequest()->server->remove('HTTP_X_ORIGINAL_URL');
393
            $this->getRequest()->server->remove('UNENCODED_URL');
394
            $this->getRequest()->server->remove('IIS_WasUrlRewritten');
395 8
        } elseif ($this->getRequest()->headers->has('X_REWRITE_URL')) {
396
            // IIS with ISAPI_Rewrite
397
            $requestUri = $this->getRequest()->headers->get('X_REWRITE_URL');
398
            $this->getRequest()->headers->remove('X_REWRITE_URL');
399 8 View Code Duplication
        } elseif ($this->getRequest()->server->get('IIS_WasUrlRewritten') == '1' && $this->getRequest()->server->get('UNENCODED_URL') != '') {
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...
400
            // IIS7 with URL Rewrite: make sure we get the unencoded URL (double slash problem)
401
            $requestUri = $this->getRequest()->server->get('UNENCODED_URL');
402
            $this->getRequest()->server->remove('UNENCODED_URL');
403
            $this->getRequest()->server->remove('IIS_WasUrlRewritten');
404 8
        } elseif ($this->getRequest()->server->has('REQUEST_URI')) {
405 8
            $requestUri = $this->getRequest()->server->get('REQUEST_URI');
406
            // HTTP proxy reqs setup request URI with scheme and host [and port] + the URL path, only use URL path
407 8
            $schemeAndHttpHost = $this->getSchemeAndHttpHost();
408 8
            if (strpos($requestUri, $schemeAndHttpHost) === 0) {
409 8
                $requestUri = substr($requestUri, strlen($schemeAndHttpHost));
410
            }
411 View Code Duplication
        } elseif ($this->getRequest()->server->has('ORIG_PATH_INFO')) {
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...
412
            // IIS 5.0, PHP as CGI
413
            $requestUri = $this->getRequest()->server->get('ORIG_PATH_INFO');
414
            if ('' != $this->getRequest()->server->get('QUERY_STRING')) {
415
                $requestUri .= '?' . $this->getRequest()->server->get('QUERY_STRING');
416
            }
417
            $this->getRequest()->server->remove('ORIG_PATH_INFO');
418
        }
419
        // normalize the request URI to ease creating sub-requests from this request
420 8
        $this->getRequest()->server->set('REQUEST_URI', $requestUri);
421 8
        return $requestUri;
422
    }
423
424
    /**
425
     * @param $string
426
     * @param $prefix
427
     * @return bool
428
     */
429 7
    private function getUrlencodedPrefix($string, $prefix)
430
    {
431 7
        if (0 !== strpos(rawurldecode($string), $prefix)) {
432 5
            return false;
433
        }
434 7
        $len = strlen($prefix);
435 7
        if (preg_match(sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) {
436 7
            return $match[0];
437
        }
438
439
        return false;
440
    }
441
}
442