1
|
|
|
<?php |
|
|
|
|
2
|
|
|
|
3
|
|
|
ar_pinp::allow( 'ar_http'); |
4
|
|
|
ar_pinp::allow( 'ar_httpClientStream' ); |
5
|
|
|
|
6
|
|
|
/* |
7
|
|
|
* prevent mess detector from warning for the private static fields |
8
|
|
|
* @SuppressWarnings(PHPMD.UnusedPrivateField) |
9
|
|
|
*/ |
10
|
|
|
class ar_http extends arBase { |
11
|
|
|
|
12
|
|
|
private static $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE; //needed to make __get() work |
|
|
|
|
13
|
|
|
public static $tainting = true; |
14
|
|
|
|
15
|
|
|
public function __get($var) { |
16
|
|
|
switch ($var) { |
17
|
|
|
case '_GET' : |
|
|
|
|
18
|
|
|
return $this->getvar( null, 'GET'); |
19
|
|
|
break; |
20
|
|
|
case '_POST' : |
|
|
|
|
21
|
|
|
return $this->getvar( null, 'POST'); |
22
|
|
|
break; |
23
|
|
|
case '_REQUEST' : |
|
|
|
|
24
|
|
|
return $this->getvar(); |
25
|
|
|
break; |
26
|
|
|
case '_SERVER' : |
|
|
|
|
27
|
|
|
return $this->getvar( null, 'SERVER'); |
28
|
|
|
break; |
29
|
|
|
case '_COOKIE' : |
|
|
|
|
30
|
|
|
return $this->getvar( null, 'COOKIE'); |
31
|
|
|
break; |
32
|
|
|
case 'tainting' : |
|
|
|
|
33
|
|
|
return self::$tainting; |
34
|
|
|
break; |
35
|
|
|
} |
36
|
|
|
} |
37
|
|
|
|
38
|
|
|
public function __set( $var, $value ) { |
39
|
|
|
if ($var=='tainting') { |
40
|
|
|
self::$tainting = (bool) $value; |
41
|
|
|
} |
42
|
|
|
} |
43
|
|
|
|
44
|
24 |
|
public static function getvar( $name = null, $method = null) { |
|
|
|
|
45
|
|
|
/* |
46
|
|
|
The full list of field-name characters that PHP converts to _ (underscore) is the following (not just dot): |
47
|
|
|
|
48
|
|
|
chr(32) ( ) (space) |
49
|
|
|
chr(46) (.) (dot) |
50
|
|
|
chr(91) ([) (open square bracket) |
51
|
|
|
chr(128) - chr(159) (various) |
52
|
|
|
PHP irreversibly modifies field names containing these characters in an attempt to maintain compatibility with the deprecated register_globals feature. |
53
|
|
|
*/ |
54
|
24 |
|
if (isset($name) ) { |
55
|
24 |
|
$name = preg_replace("/[ \.\[\x80-\x9f]/", "_", $name); |
56
|
12 |
|
} |
57
|
|
|
|
58
|
|
|
switch($method) { |
59
|
24 |
|
case 'GET' : |
|
|
|
|
60
|
|
|
$result = isset($name) ? $_GET[$name] : $_GET; |
61
|
|
|
break; |
62
|
24 |
|
case 'POST' : |
|
|
|
|
63
|
|
|
$result = isset($name) ? $_POST[$name] : $_POST; |
64
|
|
|
break; |
65
|
24 |
|
case 'COOKIE' : |
|
|
|
|
66
|
|
|
$result = isset($name) ? $_COOKIE[$name] : $_COOKIE; |
67
|
|
|
break; |
68
|
24 |
|
case 'SERVER' : |
|
|
|
|
69
|
|
|
$result = isset($name) ? $_SERVER[$name] : $_SERVER; |
70
|
|
|
break; |
71
|
12 |
|
default : |
|
|
|
|
72
|
24 |
|
$result = !isset($name) ? $_REQUEST : |
73
|
24 |
|
( isset($_POST[$name]) ? $_POST[$name] : $_GET[$name] ); |
74
|
24 |
|
break; |
75
|
12 |
|
} |
76
|
24 |
|
if (self::$tainting) { |
77
|
24 |
|
ar::taint( $result ); |
78
|
12 |
|
} |
79
|
24 |
|
return $result; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
public static function request( $method = null, $url = null, $postdata = null, $options = array() ) { |
83
|
|
|
$client = new ar_httpClientStream(); //$method, $url, $postdata, $port); |
|
|
|
|
84
|
|
|
return $client->send( $method, $url, $postdata, $options ); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
public static function client( $options = array() ) { |
88
|
|
|
return new ar_httpClientStream( $options ); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
public static function configure( $option, $value ) { |
92
|
|
|
switch ( $option ) { |
93
|
|
|
case 'tainting' : |
|
|
|
|
94
|
|
|
self::$tainting = $value; |
95
|
|
|
break; |
96
|
|
|
} |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
public static function header( $header ) { |
100
|
|
|
return ar_http_headers::header( $header ); |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
public static function get( $url, $request = null, $options = array() ) { |
104
|
|
|
return self::request( 'GET', $url, $request, $options); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
public static function post( $url, $request = null, $options = array() ) { |
108
|
|
|
return self::request( 'POST', $url, $request, $options); |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
interface ar_httpClient { |
|
|
|
|
114
|
|
|
|
115
|
|
|
public function get( $url, $request = null, $options = array() ); |
116
|
|
|
|
117
|
|
|
public function post( $url, $request = null, $options = array() ); |
118
|
|
|
|
119
|
|
|
public function put( $url, $request = null, $options = array() ); |
120
|
|
|
|
121
|
|
|
public function delete( $url, $request = null, $options = array() ); |
122
|
|
|
|
123
|
|
|
public function send( $type, $url, $request = null, $options = array() ); |
124
|
|
|
|
125
|
|
|
public function headers( $headers ); |
126
|
|
|
|
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
class ar_httpClientStream extends arBase implements ar_httpClient { |
|
|
|
|
130
|
|
|
|
131
|
|
|
private $options = array(); |
132
|
|
|
|
133
|
|
|
public $responseHeaders = null; |
134
|
|
|
|
135
|
|
|
/* FIXME: function not used, is it still relevant? |
|
|
|
|
136
|
|
|
private function parseRequestURL( $url ) { |
137
|
|
|
$request = explode( '?', (string) $url ); |
138
|
|
|
if ( isset($request[1]) ) { |
139
|
|
|
return $request[1]; |
140
|
|
|
} else { |
141
|
|
|
return null; |
142
|
|
|
} |
143
|
|
|
} |
144
|
|
|
*/ |
145
|
|
|
|
146
|
|
|
private function compileRequest( array $request ) { |
147
|
|
|
$result = ""; |
148
|
|
|
foreach ( $request as $key => $value ) { |
149
|
|
|
if ( !is_integer( $key ) ) { |
150
|
|
|
$result .= urlencode($key) . "=" . urlencode($value) . "&"; |
151
|
|
|
} |
152
|
|
|
} |
153
|
|
|
return substr( $result, 0, -1); |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
private function mergeOptions( ) { |
157
|
|
|
$args = func_get_args(); |
158
|
|
|
array_unshift( $args, $this->options ); |
159
|
|
|
return call_user_func_array( 'array_merge', $args ); |
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
public function send( $type, $url, $request = null, $options = array() ) { |
163
|
|
|
if ( is_array( $request ) ) { |
164
|
|
|
$request = $this->compileRequest( $request ); |
165
|
|
|
} |
166
|
|
|
$options = $this->mergeOptions( array( |
167
|
|
|
'method' => $type, |
168
|
|
|
'content' => $request |
169
|
|
|
), $options ); |
170
|
|
|
|
171
|
|
|
if ( $options['method'] == 'GET' && $options['content'] ) { |
172
|
|
|
if ( strpos( $url, '?' ) === false ) { |
173
|
|
|
$url = $url . '?' . $options['content']; |
174
|
|
|
} else { |
175
|
|
|
$url = $url . '&' . $options['content']; |
176
|
|
|
} |
177
|
|
|
$options['content'] = ''; |
178
|
|
|
} |
179
|
|
|
$context = stream_context_create( array( 'http' => $options ) ); |
180
|
|
|
$result = @file_get_contents( (string) $url, false, $context ); |
181
|
|
|
|
182
|
|
|
$this->responseHeaders = $http_response_header; //magic php variable set by file_get_contents. |
183
|
|
|
if (is_array($this->responseHeaders) && isset($this->responseHeaders[0])) { |
184
|
|
|
$statusLine = explode(" ", $this->responseHeaders[0]); |
185
|
|
|
$this->statusCode = $statusLine[1]; |
|
|
|
|
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
$this->requestHeaders = $options['header']; |
|
|
|
|
189
|
|
|
return $result; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
public function __construct( $options = array() ) { |
193
|
|
|
$this->options = $options; |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
public function get( $url, $request = null, $options = array() ) { |
197
|
|
|
return $this->send( 'GET', $url, $request, $options ); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
public function post( $url, $request = null, $options = array() ) { |
201
|
|
|
return $this->send( 'POST', $url, $request, $options ); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
public function put( $url, $request = null, $options = array() ) { |
205
|
|
|
return $this->send( 'PUT', $url, $request, $options ); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
public function delete( $url, $request = null, $options = array() ) { |
209
|
|
|
return $this->send( 'DELETE', $url, $request, $options ); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
public function headers( $headers ) { |
213
|
|
|
if (is_array($headers)) { |
214
|
|
|
$headers = join("\r\n", $headers); |
215
|
|
|
} |
216
|
|
|
$this->options['header'] = $this->options['headers'].$headers; |
217
|
|
|
return $this; |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.