first commit.

This commit is contained in:
kj
2026-10-05 15:08:39 -03:00
commit b7799f9fff
93 changed files with 8966 additions and 0 deletions
+160
View File
@@ -0,0 +1,160 @@
<?php
namespace Libs;
/**
* PHP Proxy - DuckBrain
*
* Proxy is a library to create a PHP proxy.
* It allows controlling the headers that will be returned to the client,
* in addition to placing filters on the resulting HTML code.
*
* @author KJ
* @website https://kj2.me
* @licence MIT
*/
class Proxy
{
public static $proxied_headers = [
'Set-Cookie',
'Content-Type',
'Cookie',
'Location',
];
public static $proxy_base_url_canonical = '/';
public static $destination_host = SOURCE_URL;
protected static $filters = [];
/**
* Adds a callable (AKA filter) that will receive the content
* and should return a string.
*
* @param callable $cb
* Function that will modify the content.
*
* @return void
*/
public static function add_filter(callable $cb): void
{
static::$filters[] = $cb;
}
/**
* Applies the filters configured with add_filter.
*
* @param string $content
* Content on which the filters will be applied.
*
* @return mixed
* It would be correct to return a string, but
* since the filters might not return correctly,
* to avoid a design error, we specify that it returns mixed.
*/
protected static function apply_filters(string $content): mixed
{
foreach (static::$filters as $filter) {
$content = call_user_func($filter, $content);
}
return $content;
}
/**
* Starts the proxy process.
*
* @param string|null $proxy_request_uri
* The address to which the proxy will be applied.
*
* @return void
*/
public static function run(?string $proxy_request_uri = null): void
{
// Get the URI if not defined
if (is_null($proxy_request_uri)) {
$proxy_request_uri = substr($_SERVER['REQUEST_URI'], strlen(static::$proxy_base_url_canonical));
} elseif (substr($proxy_request_uri, 0, 1) == '/') {
$proxy_request_uri = substr($proxy_request_uri, 1);
}
// Generate the final URL
$proxy_request_url = static::$destination_host . $proxy_request_uri;
// cURL initialization
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $proxy_request_url);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
// Capture client cookies
$hdrs = [];
if (isset($_SERVER['HTTP_COOKIE'])) {
$hdrs[] = "Cookie: " . $_SERVER['HTTP_COOKIE'];
}
// Capture client browser (User-Agent)
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$hdrs[] = "User-Agent: " . $_SERVER['HTTP_USER_AGENT'];
}
// Add captured headers
curl_setopt($ch, CURLOPT_HTTPHEADER, $hdrs);
// Capture all client headers
$hdrs = [];
foreach (\getallheaders() as $name => $value) {
$hdrs[] = "$name: $value";
}
// Add captured headers to the request
curl_setopt($ch, CURLOPT_HTTPHEADER, $hdrs);
// Add POST parameters
if (sizeof($_POST) > 0) {
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($_POST));
}
// Execute the request
$res = curl_exec($ch);
curl_close($ch);
// Parse the response
list($headers, $body) = explode("\r\n\r\n", $res, 2);
$headers = str_replace(static::$destination_host, '/', $headers);
$headers = explode("\r\n", $headers);
$hs = [];
foreach ($headers as $header) {
if (false !== strpos($header, ': ')) {
list($h, $v) = explode(': ', $header);
$hs[$h][] = $v;
} else {
$header1 = $header;
}
}
// Define headers in the client
list($proto, $code, $text) = explode(' ', $header1);
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $code . ' ' . $text);
foreach (static::$proxied_headers as $hname) {
if (isset($hs[$hname])) {
foreach ($hs[$hname] as $v) {
if ($hname === 'Set-Cookie') {
header($hname . ": " . $v, false);
} else {
header($hname . ": " . $v);
}
}
}
}
die(static::apply_filters($body));
}
}