|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* TRequestConnectionUpgrade class file. |
|
4
|
|
|
* |
|
5
|
|
|
* @author Brad Anderson <[email protected]> |
|
6
|
|
|
* @link https://github.com/pradosoft/prado |
|
7
|
|
|
* @license https://github.com/pradosoft/prado/blob/master/LICENSE |
|
8
|
|
|
*/ |
|
9
|
|
|
|
|
10
|
|
|
namespace Prado\Web\Behaviors; |
|
11
|
|
|
|
|
12
|
|
|
use Prado\Prado; |
|
13
|
|
|
|
|
14
|
|
|
/** |
|
15
|
|
|
* TRequestConnectionUpgrade class. |
|
16
|
|
|
* |
|
17
|
|
|
* This is a behavior for {@see THttpRequest} that adds the "Connection: Upgrade" |
|
18
|
|
|
* header "Upgrade: <service>" to the URL Parameters of the request. |
|
19
|
|
|
* |
|
20
|
|
|
* For example, a URL parameter could be used to select the PRADO "websocket" service. |
|
21
|
|
|
* But this class allows selection of the "websocket" service from the injection of the |
|
22
|
|
|
* "Upgrade" HTTP headers into the URL parameters without the need for specifying |
|
23
|
|
|
* URL parameters. |
|
24
|
|
|
* |
|
25
|
|
|
* ```xml |
|
26
|
|
|
* <behavior name="httpUpgrader" Class="Prado\Web\Behaviors\TRequestConnectionUpgrade" AttachToClass="Prado\Web\THttpRequest" /> |
|
27
|
|
|
* ``` |
|
28
|
|
|
* |
|
29
|
|
|
* @author Brad Anderson <[email protected]> |
|
30
|
|
|
* @since 4.2.3 |
|
31
|
|
|
*/ |
|
32
|
|
|
class TRequestConnectionUpgrade extends \Prado\Util\TBehavior |
|
33
|
|
|
{ |
|
34
|
|
|
public function events() |
|
35
|
|
|
{ |
|
36
|
|
|
return ['onResolveRequest' => 'processHeaders']; |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* Move the contents of the Upgrade header to the urlParams. |
|
41
|
|
|
* The Service can select on the "Upgrade" HTTP header like "websocket". |
|
42
|
|
|
* @param \Prado\Web\THttpRequest $request |
|
43
|
|
|
* @param \Prado\Web\THttpRequestParameter $param |
|
44
|
|
|
*/ |
|
45
|
|
|
public function processHeaders($request, $param) |
|
46
|
|
|
{ |
|
47
|
|
|
$urlParams = $param->getParameter(); |
|
48
|
|
|
if (!is_array($urlParams)) { |
|
49
|
|
|
return; |
|
50
|
|
|
} |
|
51
|
|
|
$headers = $request->getHeaders(CASE_LOWER); |
|
52
|
|
|
if (!isset($headers['connection'])) { |
|
53
|
|
|
return; |
|
54
|
|
|
} |
|
55
|
|
|
$connections = array_map('trim', explode(',', strtolower($headers['connection']))); |
|
56
|
|
|
if (!in_array('upgrade', $connections)) { |
|
57
|
|
|
return; |
|
58
|
|
|
} |
|
59
|
|
|
if (!isset($headers['upgrade'])) { |
|
60
|
|
|
Prado::log("'Connection: Upgrade' without 'Upgrade' Header from " . $_SERVER['REMOTE_ADDR'], \Prado\Util\TLogger::NOTICE, static::class); |
|
61
|
|
|
return; |
|
62
|
|
|
} |
|
63
|
|
|
$upgrade = $headers['upgrade']; |
|
64
|
|
|
if (is_array($upgrade)) { |
|
65
|
|
|
$upgrade = implode(',', $upgrade); |
|
66
|
|
|
} |
|
67
|
|
|
$requestedUpgrade = array_map('trim', explode(',', $upgrade)); |
|
68
|
|
|
|
|
69
|
|
|
if ($requestedUpgrade) { |
|
|
|
|
|
|
70
|
|
|
$urlParams = array_merge(array_flip($requestedUpgrade), $urlParams); |
|
71
|
|
|
$param->setParameter($urlParams); // Forward results |
|
72
|
|
|
return $urlParams; // return for use |
|
73
|
|
|
} |
|
74
|
|
|
} |
|
75
|
|
|
} |
|
76
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)or! empty(...)instead.