This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | This file is part of Peachy MediaWiki Bot API |
||
5 | |||
6 | Peachy is free software: you can redistribute it and/or modify |
||
7 | it under the terms of the GNU General Public License as published by |
||
8 | the Free Software Foundation, either version 3 of the License, or |
||
9 | (at your option) any later version. |
||
10 | |||
11 | This program is distributed in the hope that it will be useful, |
||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | GNU General Public License for more details. |
||
15 | |||
16 | You should have received a copy of the GNU General Public License |
||
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
18 | */ |
||
19 | |||
20 | /** |
||
21 | * @file |
||
22 | * HTTP object |
||
23 | * Stores all cURL functions |
||
24 | */ |
||
25 | |||
26 | /** |
||
27 | * HTTP Class, stores cURL functions |
||
28 | */ |
||
29 | class HTTP { |
||
30 | |||
31 | /** |
||
32 | * Curl object |
||
33 | * |
||
34 | * @var resource a cURL handle |
||
35 | * @access private |
||
36 | */ |
||
37 | private $curl_instance; |
||
38 | |||
39 | /** |
||
40 | * Hash to use for cookies |
||
41 | * |
||
42 | * @var string |
||
43 | * @access private |
||
44 | */ |
||
45 | private $cookie_hash; |
||
46 | |||
47 | /** |
||
48 | * Whether or not to enable GET:, POST:, and DLOAD: messages being sent to the terminal. |
||
49 | * |
||
50 | * @var bool |
||
51 | * @access private |
||
52 | */ |
||
53 | private $echo; |
||
54 | |||
55 | /** |
||
56 | * Useragent |
||
57 | * |
||
58 | * @var mixed |
||
59 | * @access private |
||
60 | */ |
||
61 | private $user_agent; |
||
62 | |||
63 | /** |
||
64 | * Temporary file where cookies are stored |
||
65 | * |
||
66 | * @var mixed |
||
67 | * @access private |
||
68 | */ |
||
69 | private $cookie_jar; |
||
70 | |||
71 | /** |
||
72 | * @var string|null |
||
73 | */ |
||
74 | private $lastHeader = null; |
||
75 | |||
76 | /** |
||
77 | * Construction method for the HTTP class |
||
78 | * |
||
79 | * @access public |
||
80 | * |
||
81 | * @param bool $echo Whether or not to enable GET:, POST:, and DLOAD: messages being sent to the terminal. Default false; |
||
82 | * |
||
83 | * @note please consider using HTTP::getDefaultInstance() instead |
||
84 | * |
||
85 | * @throws RuntimeException |
||
86 | * @throws DependencyError |
||
87 | * |
||
88 | * @return HTTP |
||
0 ignored issues
–
show
|
|||
89 | */ |
||
90 | public function __construct($echo = false) |
||
91 | { |
||
92 | if( !function_exists( 'curl_init' ) ) { |
||
93 | throw new DependencyError( "cURL", "http://us2.php.net/manual/en/curl.requirements.php" ); |
||
0 ignored issues
–
show
'http://us2.php.net/manu.../curl.requirements.php' is of type string , but the function expects a boolean .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
94 | } |
||
95 | |||
96 | $this->echo = $echo; |
||
97 | $this->curl_instance = curl_init(); |
||
98 | if( $this->curl_instance === false ) { |
||
99 | throw new RuntimeException( 'Failed to initialize curl' ); |
||
100 | } |
||
101 | $this->cookie_hash = md5( time() . '-' . rand( 0, 999 ) ); |
||
102 | $this->cookie_jar = sys_get_temp_dir() . 'peachy.cookies.' . $this->cookie_hash . '.dat'; |
||
103 | |||
104 | $userAgent = 'Peachy MediaWiki Bot API'; |
||
105 | if( defined( 'PEACHYVERSION' ) ) $userAgent .= ' Version ' . PEACHYVERSION; |
||
106 | $this->setUserAgent( $userAgent ); |
||
107 | |||
108 | Hooks::runHook( 'HTTPNewCURLInstance', array( &$this, &$echo ) ); |
||
109 | |||
110 | $this->setCookieJar( $this->cookie_jar ); |
||
111 | |||
112 | curl_setopt( $this->curl_instance, CURLOPT_MAXCONNECTS, 100 ); |
||
113 | curl_setopt( $this->curl_instance, CURLOPT_MAXREDIRS, 10 ); |
||
114 | $this->setCurlHeaders(); |
||
115 | curl_setopt( $this->curl_instance, CURLOPT_ENCODING, 'gzip' ); |
||
116 | curl_setopt( $this->curl_instance, CURLOPT_RETURNTRANSFER, 1 ); |
||
117 | curl_setopt( $this->curl_instance, CURLOPT_HEADER, 1 ); |
||
118 | curl_setopt( $this->curl_instance, CURLOPT_TIMEOUT, 10 ); |
||
119 | curl_setopt( $this->curl_instance, CURLOPT_CONNECTTIMEOUT, 10 ); |
||
120 | |||
121 | global $pgProxy; |
||
122 | if( isset( $pgProxy ) && count( $pgProxy ) ) { |
||
123 | curl_setopt( $this->curl_instance, CURLOPT_PROXY, $pgProxy['addr'] ); |
||
124 | if( isset( $pgProxy['type'] ) ) { |
||
125 | curl_setopt( $this->curl_instance, CURLOPT_PROXYTYPE, $pgProxy['type'] ); |
||
126 | } |
||
127 | if( isset( $pgProxy['userpass'] ) ) { |
||
128 | curl_setopt( $this->curl_instance, CURLOPT_PROXYUSERPWD, $pgProxy['userpass'] ); |
||
129 | } |
||
130 | if( isset( $pgProxy['port'] ) ) { |
||
131 | curl_setopt( $this->curl_instance, CURLOPT_PROXYPORT, $pgProxy['port'] ); |
||
132 | } |
||
133 | } |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * @param array $extraHeaders |
||
138 | */ |
||
139 | private function setCurlHeaders( $extraHeaders = array() ) { |
||
140 | curl_setopt( $this->curl_instance, CURLOPT_HTTPHEADER, array_merge( array( 'Expect:' ), $extraHeaders ) ); |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * @param boolean $verifyssl |
||
145 | */ |
||
146 | private function setVerifySSL( $verifyssl = null ) { |
||
147 | if( is_null( $verifyssl ) ) { |
||
148 | global $verifyssl; |
||
149 | } |
||
150 | if( !$verifyssl ) { |
||
0 ignored issues
–
show
The expression
$verifyssl of type null|boolean is loosely compared to false ; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
![]() |
|||
151 | curl_setopt( $this->curl_instance, CURLOPT_SSL_VERIFYPEER, false ); |
||
152 | curl_setopt( $this->curl_instance, CURLOPT_SSL_VERIFYHOST, 0 ); |
||
153 | } else { |
||
154 | curl_setopt( $this->curl_instance, CURLOPT_SSL_VERIFYPEER, true ); |
||
155 | //support for value of 1 will be removed in cURL 7.28.1 |
||
156 | curl_setopt( $this->curl_instance, CURLOPT_SSL_VERIFYHOST, 2 ); |
||
157 | } |
||
158 | } |
||
159 | |||
160 | /** |
||
161 | * @param string $cookie_file |
||
162 | */ |
||
163 | public function setCookieJar($cookie_file) |
||
164 | { |
||
165 | $this->cookie_jar = $cookie_file; |
||
166 | |||
167 | Hooks::runHook( 'HTTPSetCookieJar', array( &$cookie_file ) ); |
||
168 | |||
169 | curl_setopt( $this->curl_instance, CURLOPT_COOKIEJAR, $cookie_file ); |
||
170 | curl_setopt( $this->curl_instance, CURLOPT_COOKIEFILE, $cookie_file ); |
||
171 | } |
||
172 | |||
173 | /** |
||
174 | * @param null $user_agent |
||
175 | * @throws BadEntryError |
||
176 | * @throws HookError |
||
177 | */ |
||
178 | public function setUserAgent($user_agent = null) |
||
179 | { |
||
180 | $this->user_agent = $user_agent; |
||
181 | |||
182 | Hooks::runHook( 'HTTPSetUserAgent', array( &$user_agent ) ); |
||
183 | |||
184 | curl_setopt( $this->curl_instance, CURLOPT_USERAGENT, $user_agent ); |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * @return string|bool Data. False on failure. |
||
189 | * @throws CURLError |
||
190 | */ |
||
191 | private function doCurlExecWithRetrys() { |
||
192 | $data = false; |
||
193 | for( $i = 0; $i <= 20; $i++ ){ |
||
194 | try{ |
||
195 | $response = curl_exec( $this->curl_instance ); |
||
196 | $header_size = curl_getinfo( $this->curl_instance, CURLINFO_HEADER_SIZE ); |
||
197 | $this->lastHeader = substr( $response, 0, $header_size ); |
||
198 | $data = substr( $response, $header_size ); |
||
199 | } catch( Exception $e ){ |
||
200 | if( curl_errno( $this->curl_instance ) != 0 ) { |
||
201 | throw new CURLError( curl_errno( $this->curl_instance ), curl_error( $this->curl_instance ) ); |
||
202 | } |
||
203 | if( $i == 20 ) { |
||
204 | pecho( "Warning: A CURL error occurred. Attempted 20 times. Terminating attempts.", PECHO_WARN ); |
||
205 | return false; |
||
206 | } else { |
||
207 | pecho( "Warning: A CURL error occurred. Details can be found in the PHP error log. Retrying...", PECHO_WARN ); |
||
208 | } |
||
209 | continue; |
||
210 | } |
||
211 | if( !is_null( $data ) && $data !== false ) { |
||
212 | break; |
||
213 | } |
||
214 | } |
||
215 | return $data; |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * Get an url with HTTP GET |
||
220 | * |
||
221 | * @access public |
||
222 | * |
||
223 | * @param string $url URL to get |
||
224 | * @param array|null $data Array of data to pass. Gets transformed into the URL inside the function. Default null. |
||
225 | * @param array $headers Array of headers to pass to curl |
||
226 | * @param bool $verifyssl override for the global verifyssl value |
||
227 | * |
||
228 | * @return bool|string Result |
||
229 | */ |
||
230 | public function get( $url, $data = null, $headers = array(), $verifyssl = null ) { |
||
231 | global $argv, $displayGetOutData; |
||
232 | |||
233 | if( is_string( $headers ) ) curl_setopt( $this->curl_instance, CURLOPT_HTTPHEADER, array( $headers ) ); |
||
234 | else $this->setCurlHeaders( $headers ); |
||
235 | $this->setVerifySSL( $verifyssl ); |
||
236 | |||
237 | curl_setopt( $this->curl_instance, CURLOPT_FOLLOWLOCATION, 1 ); |
||
238 | curl_setopt( $this->curl_instance, CURLOPT_HTTPGET, 1 ); |
||
239 | curl_setopt( $this->curl_instance, CURLOPT_POST, 0 ); |
||
240 | |||
241 | /*if( !is_null( $this->use_cookie ) ) { |
||
242 | curl_setopt($this->curl_instance,CURLOPT_COOKIE, $this->use_cookie); |
||
243 | }*/ |
||
244 | |||
245 | if( !is_null( $data ) && is_array( $data ) && !empty( $data ) ) { |
||
246 | $url .= '?' . http_build_query( $data ); |
||
247 | } |
||
248 | |||
249 | curl_setopt( $this->curl_instance, CURLOPT_URL, $url ); |
||
250 | |||
251 | if( ( !is_null( $argv ) && in_array( 'peachyecho', $argv ) ) || $this->echo ) { |
||
252 | if( $displayGetOutData ) { |
||
253 | pecho( "GET: $url\n", PECHO_NORMAL ); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | Hooks::runHook( 'HTTPGet', array( &$this, &$url, &$data ) ); |
||
258 | |||
259 | return $this->doCurlExecWithRetrys(); |
||
260 | |||
261 | } |
||
262 | |||
263 | /** |
||
264 | * Returns the HTTP code of the last request |
||
265 | * |
||
266 | * @access public |
||
267 | * @return int HTTP code |
||
268 | */ |
||
269 | public function get_HTTP_code() |
||
270 | { |
||
271 | $ci = curl_getinfo( $this->curl_instance ); |
||
272 | return $ci['http_code']; |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * Sends data via HTTP POST |
||
277 | * |
||
278 | * @access public |
||
279 | * |
||
280 | * @param string $url URL to send |
||
281 | * @param array $data Array of data to pass. |
||
282 | * @param array $headers Array of headers to pass to curl |
||
283 | * |
||
284 | * @param bool|null $verifyssl override for global verifyssl value |
||
285 | * |
||
286 | * @return bool|string Result |
||
287 | */ |
||
288 | public function post($url, $data, $headers = array(), $verifyssl = null) |
||
289 | { |
||
290 | global $argv, $displayPostOutData; |
||
291 | |||
292 | if( is_string( $headers ) ) curl_setopt( $this->curl_instance, CURLOPT_HTTPHEADER, array( $headers ) ); |
||
293 | else $this->setCurlHeaders( $headers ); |
||
294 | $this->setVerifySSL( $verifyssl ); |
||
295 | |||
296 | curl_setopt( $this->curl_instance, CURLOPT_FOLLOWLOCATION, 0 ); |
||
297 | curl_setopt( $this->curl_instance, CURLOPT_HTTPGET, 0 ); |
||
298 | curl_setopt( $this->curl_instance, CURLOPT_POST, 1 ); |
||
299 | curl_setopt( $this->curl_instance, CURLOPT_POSTFIELDS, $data ); |
||
300 | |||
301 | /*if( !is_null( $this->use_cookie ) ) { |
||
302 | curl_setopt($this->curl_instance,CURLOPT_COOKIE, $this->use_cookie); |
||
303 | }*/ |
||
304 | |||
305 | curl_setopt( $this->curl_instance, CURLOPT_URL, $url ); |
||
306 | |||
307 | if( ( !is_null( $argv ) && in_array( 'peachyecho', $argv ) ) || $this->echo ) { |
||
308 | if( $displayPostOutData ) { |
||
309 | pecho( "POST: $url\n", PECHO_NORMAL ); |
||
310 | } |
||
311 | } |
||
312 | |||
313 | Hooks::runHook( 'HTTPPost', array( &$this, &$url, &$data ) ); |
||
314 | |||
315 | return $this->doCurlExecWithRetrys(); |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * Downloads an URL to the local disk |
||
320 | * |
||
321 | * @access public |
||
322 | * |
||
323 | * @param string $url URL to get |
||
324 | * @param string $local Local filename to download to |
||
325 | * @param array $headers Array of headers to pass to curl |
||
326 | * @param bool|null $verifyssl |
||
327 | * |
||
328 | * @return bool |
||
329 | */ |
||
330 | function download( $url, $local, $headers = array(), $verifyssl = null ) { |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
It is recommend to declare an explicit visibility for
download .
Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed. If you are not sure which visibility to choose, it is a good idea to start with
the most restrictive visibility, and then raise visibility as needed, i.e.
start with ![]() |
|||
331 | global $argv; |
||
332 | |||
333 | $out = fopen( $local, 'wb' ); |
||
334 | |||
335 | if( is_string( $headers ) ) curl_setopt( $this->curl_instance, CURLOPT_HTTPHEADER, array( $headers ) ); |
||
336 | else $this->setCurlHeaders( $headers ); |
||
337 | $this->setVerifySSL( $verifyssl ); |
||
338 | |||
339 | // curl_setopt($this->curl_instance, CURLOPT_FILE, $out); |
||
340 | curl_setopt( $this->curl_instance, CURLOPT_HTTPGET, 1 ); |
||
341 | curl_setopt( $this->curl_instance, CURLOPT_POST, 0 ); |
||
342 | curl_setopt( $this->curl_instance, CURLOPT_URL, $url ); |
||
343 | curl_setopt( $this->curl_instance, CURLOPT_HEADER, 0 ); |
||
344 | |||
345 | if( ( !is_null( $argv ) && in_array( 'peachyecho', $argv ) ) || $this->echo ) { |
||
346 | pecho( "DLOAD: $url\n", PECHO_NORMAL ); |
||
347 | } |
||
348 | |||
349 | Hooks::runHook( 'HTTPDownload', array( &$this, &$url, &$local ) ); |
||
350 | |||
351 | fwrite( $out, $this->doCurlExecWithRetrys() ); |
||
352 | fclose( $out ); |
||
353 | |||
354 | return true; |
||
355 | |||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Gets the Header for the last request made |
||
360 | * @return null|string |
||
361 | */ |
||
362 | public function getLastHeader() { |
||
363 | return $this->lastHeader; |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Destructor, deletes cookies and closes cURL class |
||
368 | * |
||
369 | * @access public |
||
370 | * @return void |
||
371 | */ |
||
372 | public function __destruct() |
||
373 | { |
||
374 | Hooks::runHook( 'HTTPClose', array( &$this ) ); |
||
375 | |||
376 | curl_close( $this->curl_instance ); |
||
377 | |||
378 | //@unlink($this->cookie_jar); |
||
379 | } |
||
380 | |||
381 | /** |
||
382 | * The below allows us to only have one instance of this class |
||
383 | */ |
||
384 | private static $defaultInstance = null; |
||
385 | private static $defaultInstanceWithEcho = null; |
||
386 | |||
387 | /** |
||
388 | * @param bool|false $echo |
||
389 | * @return HTTP|null |
||
390 | */ |
||
391 | public static function getDefaultInstance($echo = false) |
||
392 | { |
||
393 | if( $echo ) { |
||
394 | if( is_null( self::$defaultInstanceWithEcho ) ) { |
||
395 | self::$defaultInstanceWithEcho = new Http( $echo ); |
||
396 | } |
||
397 | return self::$defaultInstanceWithEcho; |
||
398 | } else { |
||
399 | if( is_null( self::$defaultInstance ) ) { |
||
400 | self::$defaultInstance = new Http( $echo ); |
||
401 | } |
||
402 | return self::$defaultInstance; |
||
403 | } |
||
404 | } |
||
405 | |||
406 | } |
Adding a
@return
annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.