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 | namespace Fwlib\Net; |
||
3 | |||
4 | use Fwlib\Util\UtilContainer; |
||
5 | |||
6 | /** |
||
7 | * Helper class for easy curl usage |
||
8 | * |
||
9 | * @copyright Copyright 2007-2015 Fwolf |
||
10 | * @license http://www.gnu.org/licenses/lgpl.html LGPL-3.0+ |
||
11 | */ |
||
12 | class Curl |
||
13 | { |
||
14 | /** |
||
15 | * File to save cookie |
||
16 | * |
||
17 | * @var string |
||
18 | */ |
||
19 | protected $cookieFile = ''; |
||
20 | |||
21 | /** |
||
22 | * Debug mode, will log more information, like get/post url |
||
23 | * |
||
24 | * @var boolean |
||
25 | */ |
||
26 | protected $debug = false; |
||
27 | |||
28 | /** |
||
29 | * cURL handle |
||
30 | * |
||
31 | * @var resource |
||
32 | */ |
||
33 | protected $handle; |
||
34 | |||
35 | /** |
||
36 | * Result read from web server |
||
37 | * |
||
38 | * @var string |
||
39 | */ |
||
40 | protected $html = ''; |
||
41 | |||
42 | /** |
||
43 | * File to save log |
||
44 | * |
||
45 | * Empty for direct print out(default), or set to a valid file to save, or |
||
46 | * set to /dev/null to do nothing. |
||
47 | * |
||
48 | * @var string |
||
49 | */ |
||
50 | protected $logFile = null; |
||
51 | |||
52 | |||
53 | /** |
||
54 | * Destructor |
||
55 | */ |
||
56 | public function __destruct() |
||
57 | { |
||
58 | curl_close($this->getHandle()); |
||
59 | } |
||
60 | |||
61 | |||
62 | /** |
||
63 | * Http get method |
||
64 | * |
||
65 | * @param string $url Host address |
||
66 | * @param string|array $param Get parameter |
||
67 | * @return string |
||
68 | */ |
||
69 | public function get($url, $param = null) |
||
70 | { |
||
71 | $handle = $this->getHandle(); |
||
72 | |||
73 | curl_setopt($handle, CURLOPT_HTTPGET, true); |
||
74 | |||
75 | // Remove tailing '?" from url |
||
76 | View Code Duplication | if ('?' == substr($url, -1, 1)) { |
|
0 ignored issues
–
show
|
|||
77 | $url = substr($url, 0, strlen($url) - 1); |
||
78 | } |
||
79 | |||
80 | // Char used between url & param |
||
81 | $linker = (false === strpos($url, '?')) ? '?' : '&'; |
||
82 | |||
83 | // Parse param, join array and fix linker char with url |
||
84 | if (!empty($param)) { |
||
85 | View Code Duplication | if (is_array($param)) { |
|
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. ![]() |
|||
86 | $queryString = ''; |
||
87 | foreach ($param as $k => $v) { |
||
88 | $queryString .= '&' . urlencode($k) . '=' . urlencode($v); |
||
89 | } |
||
90 | $param = $queryString; |
||
91 | } |
||
92 | |||
93 | $param{0} = $linker; |
||
94 | } |
||
95 | |||
96 | curl_setopt($handle, CURLOPT_URL, $url . $param); |
||
97 | $this->html = curl_exec($handle); |
||
98 | |||
99 | if ($this->debug) { |
||
100 | $this->log('Get: ' . $url . $param); |
||
101 | } |
||
102 | |||
103 | if (0 != curl_errno($handle)) { |
||
104 | $this->log(curl_error($handle)); |
||
105 | } |
||
106 | |||
107 | return $this->html; |
||
108 | } |
||
109 | |||
110 | |||
111 | /** |
||
112 | * Get and initialize curl handle |
||
113 | * |
||
114 | * @return resource |
||
115 | */ |
||
116 | public function getHandle() |
||
117 | { |
||
118 | if (is_null($this->handle)) { |
||
119 | $this->handle = curl_init(); |
||
120 | $this->setDefaultOptions($this->handle); |
||
121 | } |
||
122 | |||
123 | return $this->handle; |
||
124 | } |
||
125 | |||
126 | |||
127 | /** |
||
128 | * Get server return code of last curl_exec |
||
129 | * |
||
130 | * 200-ok, 404-missing file, etc |
||
131 | * |
||
132 | * @return int |
||
133 | */ |
||
134 | public function getLastCode() |
||
135 | { |
||
136 | $handle = $this->getHandle(); |
||
137 | |||
138 | $code = curl_getinfo($handle, CURLINFO_HTTP_CODE); |
||
139 | |||
140 | return intval($code); |
||
141 | } |
||
142 | |||
143 | |||
144 | /** |
||
145 | * Get server return content type of last curl_exec |
||
146 | * |
||
147 | * text/html, image/png, etc |
||
148 | * |
||
149 | * @return string |
||
150 | */ |
||
151 | public function getLastContentType() |
||
152 | { |
||
153 | $handle = $this->getHandle(); |
||
154 | |||
155 | $type = curl_getinfo($handle, CURLINFO_CONTENT_TYPE); |
||
156 | |||
157 | return $type; |
||
158 | } |
||
159 | |||
160 | |||
161 | /** |
||
162 | * Log curl action |
||
163 | * |
||
164 | * @param string $msg |
||
165 | */ |
||
166 | protected function log($msg) |
||
167 | { |
||
168 | // Prepend msg with time, append with newline |
||
169 | $msg = date('[Y-m-d H:i:s] ') . $msg . PHP_EOL; |
||
170 | |||
171 | if (empty($this->logFile)) { |
||
172 | |||
173 | UtilContainer::getInstance()->getEnv()->ecl($msg); |
||
174 | |||
175 | } elseif (is_writable($this->logFile)) { |
||
176 | // Write to log file |
||
177 | file_put_contents($this->logFile, $msg, FILE_APPEND); |
||
178 | } |
||
179 | |||
180 | // Invalid $this->logFile will do nothing. |
||
181 | } |
||
182 | |||
183 | |||
184 | /** |
||
185 | * Match content to variables using preg |
||
186 | * |
||
187 | * Return value maybe string(for single result) or array(for multiple |
||
188 | * result), use carefully and remind which value you use it for. |
||
189 | * |
||
190 | * Regex should surround wih '/', and mark match target with '()'. |
||
191 | * |
||
192 | * @param string $preg |
||
193 | * @param string $html If omitted, use $this->html |
||
194 | * @return string|array |
||
195 | */ |
||
196 | public function match($preg, $html = '') |
||
197 | { |
||
198 | // Param check |
||
199 | if (empty($preg)) { |
||
200 | return null; |
||
201 | } |
||
202 | if (empty($html)) { |
||
203 | $html = $this->html; |
||
204 | } |
||
205 | |||
206 | |||
207 | $matchCount = preg_match_all($preg, $html, $matches, PREG_SET_ORDER); |
||
208 | if (0 == $matchCount || false === $matchCount) { |
||
209 | // Got none match or Got error |
||
210 | $matches = null; |
||
211 | |||
212 | } elseif (1 == $matchCount) { |
||
213 | // Got 1 match, return as string or array(2 value in 1 match) |
||
214 | $matches = $matches[0]; |
||
215 | array_shift($matches); |
||
216 | if (1 == count($matches)) { |
||
217 | $matches = $matches[0]; |
||
218 | } |
||
219 | |||
220 | } else { |
||
221 | // Got more than 1 match return array contains string or sub-array |
||
222 | View Code Duplication | foreach ($matches as &$row) { |
|
0 ignored issues
–
show
The expression
$matches of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() 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. ![]() |
|||
223 | array_shift($row); |
||
224 | if (1 == count($row)) { |
||
225 | $row = $row[0]; |
||
226 | } |
||
227 | } |
||
228 | } |
||
229 | |||
230 | return $matches; |
||
231 | } |
||
232 | |||
233 | |||
234 | /** |
||
235 | * Http post method |
||
236 | * |
||
237 | * @param string $url Host address |
||
238 | * @param string|array $params Post parameter, prefer array |
||
239 | * @return string |
||
240 | */ |
||
241 | public function post($url, $params = []) |
||
242 | { |
||
243 | $handle = $this->getHandle(); |
||
244 | |||
245 | curl_setopt($handle, CURLOPT_POST, true); |
||
246 | |||
247 | curl_setopt($handle, CURLOPT_POSTFIELDS, $params); |
||
248 | curl_setopt($handle, CURLOPT_URL, $url); |
||
249 | $this->html = curl_exec($handle); |
||
250 | |||
251 | if (is_array($params)) { |
||
252 | $params = implode('&', array_keys($params)); |
||
253 | } |
||
254 | $linker = (false === strpos($url, '?')) ? '?' : '&'; |
||
255 | $params = rtrim($linker . ltrim($params, '&'), '?&'); |
||
256 | |||
257 | if ($this->debug) { |
||
258 | $this->log('Post: ' . $url . $params); |
||
259 | } |
||
260 | |||
261 | if (0 != curl_errno($handle)) { |
||
262 | $this->log(curl_error($handle), 4); |
||
0 ignored issues
–
show
The call to
Curl::log() has too many arguments starting with 4 .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the ![]() |
|||
263 | } |
||
264 | |||
265 | return $this->html; |
||
266 | } |
||
267 | |||
268 | |||
269 | /** |
||
270 | * Renew handle |
||
271 | * |
||
272 | * This is useful when cookie file is used, and want to reload cookies, |
||
273 | * eg: after login, reload cookie then they will be used in next operation. |
||
274 | * |
||
275 | * @return static |
||
276 | */ |
||
277 | public function renewHandle() |
||
278 | { |
||
279 | if (!is_null($this->handle)) { |
||
280 | curl_close($this->handle); |
||
281 | $this->handle = null; |
||
282 | |||
283 | $this->getHandle(); |
||
284 | |||
285 | // Re-assign options |
||
286 | if (!is_null($this->cookieFile)) { |
||
287 | $this->setCookieFile($this->cookieFile); |
||
288 | } |
||
289 | |||
290 | // More option to set ? |
||
291 | } |
||
292 | |||
293 | return $this; |
||
294 | } |
||
295 | |||
296 | |||
297 | /** |
||
298 | * Set cookie option |
||
299 | * |
||
300 | * If filename is not given, use default, |
||
301 | * If file is given, use & set it as default. |
||
302 | * |
||
303 | * @param string $cookieFile |
||
304 | */ |
||
305 | public function setCookieFile($cookieFile = '') |
||
306 | { |
||
307 | $handle = $this->getHandle(); |
||
308 | |||
309 | $this->cookieFile = $cookieFile; |
||
310 | |||
311 | if (!empty($cookieFile) && (is_writable($cookieFile))) { |
||
312 | curl_setopt($handle, CURLOPT_COOKIEFILE, $cookieFile); |
||
313 | curl_setopt($handle, CURLOPT_COOKIEJAR, $cookieFile); |
||
314 | } |
||
315 | } |
||
316 | |||
317 | |||
318 | /** |
||
319 | * Setter of $debug |
||
320 | * |
||
321 | * @param boolean $debug |
||
322 | * @return static |
||
323 | */ |
||
324 | public function setDebug($debug) |
||
325 | { |
||
326 | $this->debug = $debug; |
||
327 | |||
328 | return $this; |
||
329 | } |
||
330 | |||
331 | |||
332 | /** |
||
333 | * Set default options |
||
334 | * |
||
335 | * @param resource $handle |
||
336 | * @return static |
||
337 | */ |
||
338 | protected function setDefaultOptions($handle) |
||
339 | { |
||
340 | curl_setopt($handle, CURLOPT_AUTOREFERER, true); |
||
341 | // If got http error, report. |
||
342 | curl_setopt($handle, CURLOPT_FAILONERROR, true); |
||
343 | |||
344 | // CURLOPT_FOLLOWLOCATION cannot set when open_basedir is set. |
||
345 | // Also safe_mode, which are DEPRECATED in 5.3.0 and REMOVED in 5.4.0. |
||
346 | if ('' == ini_get('open_basedir')) { |
||
347 | curl_setopt($handle, CURLOPT_FOLLOWLOCATION, true); |
||
348 | } |
||
349 | |||
350 | // Return result instead of display it. |
||
351 | curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); |
||
352 | curl_setopt($handle, CURLOPT_CONNECTTIMEOUT, 300); |
||
353 | curl_setopt($handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); |
||
354 | curl_setopt($handle, CURLOPT_MAXREDIRS, 10); |
||
355 | curl_setopt($handle, CURLOPT_TIMEOUT, 300); |
||
356 | |||
357 | // Accept all supported encoding(identity, deflate, gzip) |
||
358 | // See CURLOPT_ACCEPT_ENCODING in libcurl |
||
359 | // Set this to get uncompressed html content |
||
360 | curl_setopt($handle, CURLOPT_ENCODING, ''); |
||
361 | |||
362 | // Cipher list depends on curl lib use OpenSSL or NSS module |
||
363 | // @see https://github.com/PayU/openpayu_php/issues/38 |
||
364 | // Wrong cipher will got error: Unknown cipher in list: ... |
||
365 | $cipher = ('NSS' == substr(curl_version()['ssl_version'], 0, 3)) |
||
366 | ? 'rsa_aes_128_sha' |
||
367 | : 'TLSv1'; |
||
368 | curl_setopt($handle, CURLOPT_SSL_CIPHER_LIST, $cipher); |
||
369 | |||
370 | return $this; |
||
371 | } |
||
372 | |||
373 | |||
374 | /** |
||
375 | * Setter of $logFile |
||
376 | * |
||
377 | * @param string $logFile |
||
378 | * @return static |
||
379 | */ |
||
380 | public function setLogFile($logFile) |
||
381 | { |
||
382 | $this->logFile = $logFile; |
||
383 | |||
384 | return $this; |
||
385 | } |
||
386 | |||
387 | |||
388 | /** |
||
389 | * Set proxy option |
||
390 | * |
||
391 | * @param int $type 0-no proxy, 1-http, 2-socks5 |
||
392 | * @param string $host |
||
393 | * @param int $port |
||
394 | * @param string $auth [username]:[password] |
||
395 | */ |
||
396 | public function setProxy($type, $host, $port, $auth = '') |
||
397 | { |
||
398 | $handle = $this->getHandle(); |
||
399 | |||
400 | if (0 == $type) { |
||
401 | // Some server refuse http proxy tunnel, it's useless settings. |
||
402 | //curl_setopt($handle, CURLOPT_HTTPPROXYTUNNEL, false); |
||
403 | curl_setopt($handle, CURLOPT_PROXY, null); |
||
404 | |||
405 | } else { |
||
406 | //curl_setopt($handle, CURLOPT_HTTPPROXYTUNNEL, true); |
||
407 | |||
408 | curl_setopt($handle, CURLOPT_PROXY, $host); |
||
409 | |||
410 | curl_setopt( |
||
411 | $handle, |
||
412 | CURLOPT_PROXYTYPE, |
||
413 | (1 == $type) ? CURLPROXY_HTTP : CURLPROXY_SOCKS5 |
||
414 | ); |
||
415 | |||
416 | curl_setopt($handle, CURLOPT_PROXYPORT, $port); |
||
417 | if (!empty($auth)) { |
||
418 | curl_setopt($handle, CURLOPT_PROXYUSERPWD, $auth); |
||
419 | } |
||
420 | } |
||
421 | } |
||
422 | |||
423 | |||
424 | /** |
||
425 | * Set http referrer url |
||
426 | * |
||
427 | * @param string $url |
||
428 | */ |
||
429 | public function setReferrer($url = null) |
||
430 | { |
||
431 | $handle = $this->getHandle(); |
||
432 | |||
433 | if (!empty($url)) { |
||
434 | curl_setopt($handle, CURLOPT_REFERER, $url); |
||
435 | } |
||
436 | } |
||
437 | |||
438 | |||
439 | /** |
||
440 | * Enable or disable ssl verify function |
||
441 | * |
||
442 | * Ssl verify is enabled by curl in default. |
||
443 | * |
||
444 | * @param boolean $enable |
||
445 | */ |
||
446 | public function setSslVerify($enable = true) |
||
447 | { |
||
448 | $handle = $this->getHandle(); |
||
449 | |||
450 | curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, $enable); |
||
451 | curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, $enable); |
||
452 | } |
||
453 | |||
454 | |||
455 | /** |
||
456 | * Set browser agent option |
||
457 | * |
||
458 | * @param string $userAgent |
||
459 | */ |
||
460 | public function setUserAgent($userAgent = 'curl') |
||
461 | { |
||
462 | $handle = $this->getHandle(); |
||
463 | |||
464 | curl_setopt($handle, CURLOPT_USERAGENT, $userAgent); |
||
465 | } |
||
466 | } |
||
467 |
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.