Bearsampp 2026.7.11
Loading...
Searching...
No Matches
class.httpclient.php
Go to the documentation of this file.
1<?php
2/*
3 *
4 * * Copyright (c) 2022-2025 Bearsampp
5 * * License: GNU General Public License version 3 or later; see LICENSE.txt
6 * * Website: https://bearsampp.com
7 * * Github: https://github.com/Bearsampp
8 *
9 */
10
20{
28 public static function getHttpHeaders($pingUrl)
29 {
30 if (function_exists('curl_version')) {
32 } else {
34 }
35
36 if (!empty($result)) {
37 $rebuildResult = array();
38 foreach ($result as $row) {
39 $row = trim($row);
40 if (!empty($row)) {
41 $rebuildResult[] = $row;
42 }
43 }
44 $result = $rebuildResult;
45
46 Log::debug('getHttpHeaders:');
47 foreach ($result as $header) {
48 Log::debug('-> ' . $header);
49 }
50 }
51
52 return $result;
53 }
54
66 public static function getFopenHttpHeaders($url)
67 {
68 $result = array();
69
70 $context = stream_context_create(array(
71 'ssl' => array(
72 'verify_peer' => false,
73 'verify_peer_name' => false,
74 'allow_self_signed' => true,
75 )
76 ));
77
78 $fp = @fopen($url, 'r', false, $context);
79 if ($fp) {
80 $meta = stream_get_meta_data($fp);
81 $result = isset($meta['wrapper_data']) ? $meta['wrapper_data'] : $result;
82 fclose($fp);
83 }
84
85 return $result;
86 }
87
99 public static function getCurlHttpHeaders($url)
100 {
101 $result = array();
102
103 $ch = curl_init();
104 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
105 curl_setopt($ch, CURLOPT_VERBOSE, true);
106 curl_setopt($ch, CURLOPT_HEADER, true);
107 curl_setopt($ch, CURLOPT_URL, $url);
108 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
109 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
110
111 $response = @curl_exec($ch);
112 if (empty($response)) {
113 return $result;
114 }
115
116 Log::trace('getCurlHttpHeaders:' . $response);
117 $responseHeaders = explode("\r\n\r\n", $response, 2);
118 if (!isset($responseHeaders[0]) || empty($responseHeaders[0])) {
119 return $result;
120 }
121
122 return explode("\n", $responseHeaders[0]);
123 }
124
134 public static function getWebsiteUrl($path = '', $fragment = '', $utmSource = true)
135 {
136 global $bearsamppCore;
137
138 $url = APP_WEBSITE;
139 if (!empty($path)) {
140 $url .= '/' . ltrim($path, '/');
141 }
142 if ($utmSource) {
143 $url = rtrim($url, '/') . '/?utm_source=bearsampp-' . $bearsamppCore->getAppVersion();
144 }
145 if (!empty($fragment)) {
146 $url .= $fragment;
147 }
148
149 return $url;
150 }
151
160 public static function getWebsiteUrlNoUtm($path = '', $fragment = '')
161 {
162 return self::getWebsiteUrl($path, $fragment, false);
163 }
164
172 public static function getChangelogUrl($utmSource = true)
173 {
174 return self::getWebsiteUrl('doc/changelog', null, $utmSource);
175 }
176
187 public static function getGithubUrl($type = 'user', $user = APP_GITHUB_USER, $repo = null, $branch = null, $path = null) {
188 if (empty($user) || !is_string($user)) {
189 return false;
190 }
191
192 // Encode as URL path segment (not query encoding)
193 $user = rawurlencode($user);
194
195 switch ($type) {
196 case 'user':
197 return "https://github.com/{$user}";
198
199 case 'repo':
200 if (empty($repo) || !is_string($repo)) {
201 return false;
202 }
203 $repo = rawurlencode($repo);
204 return "https://github.com/{$user}/{$repo}";
205
206 case 'issues':
207 if (empty($repo) || !is_string($repo)) {
208 return false;
209 }
210 $repo = rawurlencode($repo);
211 return "https://github.com/{$user}/{$repo}/issues";
212
213 case 'raw':
214 if (empty($repo) || empty($branch) || empty($path) || !is_string($repo) || !is_string($branch) || !is_string($path)) {
215 return false;
216 }
217 $repo = rawurlencode($repo);
218 $branch = rawurlencode($branch);
219
220 $path = ltrim($path, '/');
221 $segments = array_map('rawurlencode', explode('/', $path));
222 $pathEncoded = implode('/', $segments);
223
224 return "https://raw.githubusercontent.com/{$user}/{$repo}/{$branch}/{$pathEncoded}";
225
226 default:
227 return false;
228 }
229 }
230
236 public static function getGithubUserUrl()
237 {
238 return self::getGithubUrl('user', APP_GITHUB_USER);
239 }
240
254 public static function getHeaders($host, $port, $ssl = false)
255 {
256 $result = array();
257 $context = stream_context_create(array(
258 'ssl' => array(
259 'verify_peer' => false,
260 'verify_peer_name' => false,
261 'allow_self_signed' => true,
262 )
263 ));
264
265 $fp = @stream_socket_client(($ssl ? 'ssl://' : '') . $host . ':' . $port, $errno, $errstr, 5, STREAM_CLIENT_CONNECT, $context);
266 if ($fp) {
267 $out = fgets($fp);
268 $result = explode(PHP_EOL, $out);
269 @fclose($fp);
270 }
271
272 if (!empty($result)) {
273 $rebuildResult = array();
274 foreach ($result as $row) {
275 $row = trim($row);
276 if (!empty($row)) {
277 $rebuildResult[] = $row;
278 }
279 }
280 $result = $rebuildResult;
281
282 Log::debug('getHeaders:');
283 foreach ($result as $header) {
284 Log::debug('-> ' . $header);
285 }
286 }
287
288 return $result;
289 }
290
298 public static function getApiJson($url)
299 {
301
302 $ch = curl_init();
303 curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
304 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
305 curl_setopt($ch, CURLOPT_VERBOSE, false); // Set to false to avoid polluting logs unless needed
306 curl_setopt($ch, CURLOPT_URL, $url);
307 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
308 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
309 curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
310 $data = curl_exec($ch);
311 if (curl_errno($ch)) {
312 Log::error('CURL Error (' . curl_errno($ch) . '): ' . curl_error($ch) . ' (URL: ' . $url . ')');
313 }
314
315 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
316 if ($httpCode >= 400) {
317 Log::error('HTTP Error ' . $httpCode . ' for URL: ' . $url);
318 }
319
320 // curl_close() is deprecated in PHP 8.5+ as it has no effect since PHP 8.0
321 // The resource is automatically closed when it goes out of scope
322 if (PHP_VERSION_ID < 80500) {
323 curl_close($ch);
324 }
325
326 return $data === false ? '' : trim($data);
327 }
328
336 public static function getLatestVersion($url)
337 {
339 if (empty($result)) {
340 Log::error('Cannot retrieve latest github info: empty result or error for URL: ' . $url);
341
342 return null;
343 }
344
345 $resultArray = json_decode($result, true);
346 if ($resultArray === null) {
347 Log::error('Failed to decode JSON response from: ' . $url . '. Response snippet: ' . substr($result, 0, 100));
348 return null;
349 }
350
351 if (isset($resultArray['tag_name']) && isset($resultArray['assets'][0]['browser_download_url'])) {
352 $tagName = $resultArray['tag_name'];
353 $downloadUrl = $resultArray['assets'][0]['browser_download_url'];
354 $name = $resultArray['name'];
355 Log::debug('Latest version tag name: ' . $tagName);
356 Log::debug('Download URL: ' . $downloadUrl);
357 Log::debug('Name: ' . $name);
358
359 return ['version' => $tagName, 'html_url' => $downloadUrl, 'name' => $name];
360 } else {
361 Log::error('Tag name, download URL, or name not found in the response: ' . $result);
362
363 return null;
364 }
365 }
366
372 public static function setupCurlHeaderWithToken()
373 {
374 // Return headers with User-Agent, which is required by GitHub API
375 return array(
376 'User-Agent: ' . APP_GITHUB_USERAGENT . ' (https://github.com/' . APP_GITHUB_USER . '/' . APP_GITHUB_REPO . ')',
377 'Accept: application/vnd.github.v3+json'
378 );
379 }
380
389 public static function getRemoteFilesize($url, $humanFileSize = true)
390 {
391 $size = 0;
392
393 $data = get_headers($url, true);
394 if (isset($data['Content-Length'])) {
395 $size = intval($data['Content-Length']);
396 }
397
398 return $humanFileSize ? Util::humanFileSize($size) : $size;
399 }
400
409 public static function checkInternetState()
410 {
411 $connected = @fsockopen('www.google.com', 80);
412 if ($connected) {
413 fclose($connected);
414
415 return true; // Internet connection is active
416 } else {
417 return false; // Internet connection is not active
418 }
419 }
420}
421
$result
$port
global $bearsamppCore
static getWebsiteUrlNoUtm($path='', $fragment='')
static getRemoteFilesize($url, $humanFileSize=true)
static getGithubUrl($type='user', $user=APP_GITHUB_USER, $repo=null, $branch=null, $path=null)
static getHeaders($host, $port, $ssl=false)
static getHttpHeaders($pingUrl)
static getLatestVersion($url)
static getGithubUserUrl()
static getChangelogUrl($utmSource=true)
static getWebsiteUrl($path='', $fragment='', $utmSource=true)
static getApiJson($url)
static setupCurlHeaderWithToken()
static getFopenHttpHeaders($url)
static getCurlHttpHeaders($url)
static checkInternetState()
static debug($data, $file=null)
static trace($data, $file=null)
static error($data, $file=null)
static humanFileSize(int $size, string $unit='')
const APP_GITHUB_USERAGENT
Definition root.php:18
const APP_WEBSITE
Definition root.php:14
const APP_GITHUB_USER
Definition root.php:16
const APP_GITHUB_REPO
Definition root.php:17