mirror of
https://github.com/gnh1201/caterpillar.git
synced 2025-06-18 02:59:07 +00:00
Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
f493d026b8 | |||
f7256c674a | |||
feee46aabd | |||
02554d75a9 | |||
4eea005aa0 | |||
b7f9b96bc4 | |||
75dba7093a | |||
caf0afa73a | |||
4f46d3e75f | |||
6d368eb9e6 | |||
cb215bb423 | |||
efb2401a66 | |||
f2ead73592 | |||
cc41ac4a2e | |||
479eb560da | |||
768dad77cf | |||
3b24c6c209 | |||
54c6f6f33e | |||
4486c1d411 | |||
7efc6612c7 | |||
d34f68c8a1 | |||
0c634f6da0 | |||
ddac81a036 | |||
03b2315211 | |||
a97160f9a0 | |||
895cc03d31 | |||
10c91d5045 | |||
51de2628bf | |||
376fd71b07 | |||
0bfc39a5e9 | |||
be5496aa16 | |||
02befd1c17 | |||
9926e1564d | |||
18ec101d84 | |||
d7cc297a80 | |||
24e05065f1 |
13
.github/workflows/lint.yml
vendored
13
.github/workflows/lint.yml
vendored
|
@ -1,13 +0,0 @@
|
|||
name: Ruff
|
||||
on: [push, pull_request]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
#jobs:
|
||||
# ruff:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# - uses: chartboost/ruff-action@v1
|
23
.github/workflows/llm-code-review.yml
vendored
Normal file
23
.github/workflows/llm-code-review.yml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
name: AI Code Review
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
issues:
|
||||
types: [opened, reopened]
|
||||
|
||||
jobs:
|
||||
repofix:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Run RepoFixAI
|
||||
uses: Manav916/llm-code-review@main
|
||||
with:
|
||||
groq_api_key: ${{ secrets.GROQ_API_KEY }}
|
||||
groq_model: 'gemma-2-9b-it'
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# exclude_extensions: 'txt'
|
||||
repo_owner: ${{ github.repository_owner }}
|
||||
repo_name: ${{ github.event.repository.name }}
|
||||
event_number: ${{ github.event.number || github.event.issue.number }} # when listening for both pull requests and issues
|
||||
event_name: ${{ github.event_name }}
|
17
README.md
17
README.md
|
@ -1,11 +1,13 @@
|
|||
# Caterpillar Proxy
|
||||
# Caterpillar Proxy (Songchoongi Project)
|
||||
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fcaterpillar?ref=badge_shield)
|
||||
[](https://doi.org/10.5281/zenodo.13346533)
|
||||
[](#)
|
||||
[](https://www.slideshare.net/slideshow/2024-caterpillar-project-in-2024-korea-oss-contest/273031732)
|
||||
[](https://discord.gg/9VVTHpfsVW)
|
||||
[](https://github.com/gnh1201/welsonjs/discussions/167)
|
||||
|
||||
Caterpillar Proxy - The simple web debugging proxy (formerly, php-httpproxy)
|
||||
Caterpillar Proxy (Songchoongi Project) - The simple web debugging proxy (formerly, php-httpproxy)
|
||||
|
||||

|
||||
|
||||
|
@ -19,7 +21,7 @@ Imagine various means such as time machines, satellites, quantum technology, sou
|
|||
* [Build a network tunnel using Python and the LAMP(PHP) stack (qiita.com)](https://qiita.com/gnh1201/items/40f9350ca6d308def6d4)
|
||||
* [K-Anonymity for Spam Filtering: Case with Mastodon, and Misskey (qiita.com)](https://qiita.com/gnh1201/items/09f4081f84610db3a9d3)
|
||||
* [File Upload Vulnerability Attack Test (Caterpillar Proxy) (youtu.be) ](https://youtu.be/sPZOCgYtLRw)
|
||||
* Real-time processing of emergency disaster sensor data (e.g., fire detection).
|
||||
* [Real-time processing of emergency disaster sensor data (e.g., fire detection).](https://catswords.social/@catswords_oss/114016647285923011)
|
||||
|
||||
## How it works
|
||||
|
||||
|
@ -96,13 +98,18 @@ sudo update-ca-certificates
|
|||

|
||||
|
||||
## Report abuse
|
||||
- [GitHub Security Advisories](https://github.com/gnh1201/welsonjs/security)
|
||||
- abuse@catswords.net
|
||||
- [GitHub Security Advisories (gnh1201/caterpillar)](https://github.com/gnh1201/caterpillar/security)
|
||||
|
||||
## Join the community
|
||||
- ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
|
||||
- XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)
|
||||
- [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
|
||||
- [Join Catswords OSS #caterpillar on Discord (discord.gg)](https://discord.gg/9VVTHpfsVW)
|
||||
- [Join Catswords OSS on Gather (app.gather.town)](https://app.gather.town/invite?token=IE2AYZDpS-Ocu3SzpSc0)
|
||||
|
||||
## Special channels
|
||||
- [A paid consultation channel (m.expert.naver.com)](https://m.expert.naver.com/mobile/expert/product/detail?storeId=100051156&productId=100144540) is available for Korean (한국어) region.
|
||||
- [Join the private operations channel (forms.gle)](https://forms.gle/ZKAAaGTiGamksHoo8) is available for all regions.
|
||||
|
||||
## License
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fcaterpillar?ref=badge_large)
|
||||
|
|
61
assets/php/class.tfa.php
Normal file
61
assets/php/class.tfa.php
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
// https://github.com/dimamedia/PHP-Simple-TOTP-and-PubKey
|
||||
|
||||
class tfa {
|
||||
|
||||
// RFC4648 Base32 alphabet
|
||||
private $alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
|
||||
function getOtp($key) {
|
||||
|
||||
/* Base32 decoder */
|
||||
|
||||
// Remove spaces from the given public key and converting to an array
|
||||
$key = str_split(str_replace(" ","",$key));
|
||||
|
||||
$n = 0;
|
||||
$j = 0;
|
||||
$binary_key = "";
|
||||
|
||||
// Decode public key's each character to base32 and save into binary chunks
|
||||
foreach($key as $char) {
|
||||
$n = $n << 5;
|
||||
$n = $n + stripos($this->alphabet, $char);
|
||||
$j += 5;
|
||||
|
||||
if($j >= 8) {
|
||||
$j -= 8;
|
||||
$binary_key .= chr(($n & (0xFF << $j)) >> $j);
|
||||
}
|
||||
}
|
||||
/* End of Base32 decoder */
|
||||
|
||||
// current unix time 30sec period as binary
|
||||
$binary_timestamp = pack('N*', 0) . pack('N*', floor(microtime(true)/30));
|
||||
// generate keyed hash
|
||||
$hash = hash_hmac('sha1', $binary_timestamp, $binary_key, true);
|
||||
|
||||
// generate otp from hash
|
||||
$offset = ord($hash[19]) & 0xf;
|
||||
$otp = (
|
||||
((ord($hash[$offset+0]) & 0x7f) << 24 ) |
|
||||
((ord($hash[$offset+1]) & 0xff) << 16 ) |
|
||||
((ord($hash[$offset+2]) & 0xff) << 8 ) |
|
||||
(ord($hash[$offset+3]) & 0xff)
|
||||
) % pow(10, 6);
|
||||
|
||||
return $otp;
|
||||
}
|
||||
|
||||
function getPubKey() {
|
||||
$alphabet = str_split($this->alphabet);
|
||||
$key = '';
|
||||
// generate 16 chars public key from Base32 alphabet
|
||||
for ($i = 0; $i < 16; $i++) $key .= $alphabet[mt_rand(0,31)];
|
||||
// split into 4x4 chunks for easy reading
|
||||
return implode(" ", str_split($key, 4));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
70
assets/php/coupang.class.php
Normal file
70
assets/php/coupang.class.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
// coupang.class.php
|
||||
// Coupang Product Search API integration class
|
||||
// Namhyeon Go <gnh1201@gmail.com>
|
||||
// https://github.com/gnh1201/welsonjs
|
||||
//
|
||||
date_default_timezone_set("GMT+0");
|
||||
|
||||
class CoupangProductSearch {
|
||||
private $accessKey = "";
|
||||
private $secretKey = "";
|
||||
private $baseUrl = "https://api-gateway.coupang.com";
|
||||
|
||||
private function generateSignature($method, $path, $query = "") {
|
||||
$datetime = (new \DateTime("now", new \DateTimeZone("GMT")))->format("ymd\THis\Z");
|
||||
$message = $datetime . $method . $path . $query;
|
||||
|
||||
$signature = hash_hmac('sha256', $message, $this->secretKey);
|
||||
return [
|
||||
'authorization' => "CEA algorithm=HmacSHA256, access-key={$this->accessKey}, signed-date={$datetime}, signature={$signature}",
|
||||
'datetime' => $datetime
|
||||
];
|
||||
}
|
||||
|
||||
public function searchProducts($keyword, $limit = 10, $subId = null, $imageSize = null, $srpLinkOnly = false) {
|
||||
$path = "/v2/providers/affiliate_open_api/apis/openapi/products/search";
|
||||
$queryParams = http_build_query([
|
||||
'keyword' => $keyword,
|
||||
'limit' => $limit,
|
||||
'subId' => $subId,
|
||||
'imageSize' => $imageSize,
|
||||
'srpLinkOnly' => $srpLinkOnly
|
||||
]);
|
||||
$fullPath = $path . '?' . $queryParams;
|
||||
$url = $this->baseUrl . $fullPath;
|
||||
|
||||
$signatureData = $this->generateSignature("GET", $path, $queryParams);
|
||||
$authorization = $signatureData['authorization'];
|
||||
$datetime = $signatureData['datetime'];
|
||||
|
||||
$headers = [
|
||||
"Content-Type: application/json;charset=UTF-8",
|
||||
"Authorization: $authorization"
|
||||
];
|
||||
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
|
||||
curl_close($curl);
|
||||
|
||||
if ($httpCode === 200) {
|
||||
return json_decode($response, true);
|
||||
} else {
|
||||
try {
|
||||
return json_decode($response, true);
|
||||
} catch (Exception $e) {
|
||||
return [
|
||||
"status" => $httpCode,
|
||||
"message" => $e->getMessage()
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,19 +1,26 @@
|
|||
<?php
|
||||
/* index.php
|
||||
* Caterpillar Worker on PHP
|
||||
* Caterpillar Proxy Worker on PHP runtime
|
||||
*
|
||||
* Caterpillar Proxy - The simple web debugging proxy (formerly, php-httpproxy)
|
||||
* Namhyeon Go (Catswords Research) <abuse@catswords.net>
|
||||
* https://github.com/gnh1201/caterpillar
|
||||
* Created at: 2022-10-06
|
||||
* Updated at: 2024-11-26
|
||||
* Updated at: 2025-03-11
|
||||
*/
|
||||
|
||||
define("PHP_HTTPPROXY_VERSION", "0.1.6.4");
|
||||
define("PERF_START_TIME", microtime(true));
|
||||
define("PHP_HTTPPROXY_VERSION", "0.1.6.10");
|
||||
define("DEFAULT_SOCKET_TIMEOUT", 1);
|
||||
define("STATEFUL_SOCKET_TIMEOUT", 30);
|
||||
define("MAX_EXECUTION_TIME", 0);
|
||||
define("DEFAULT_USER_AGENT", 'php-httpproxy/' . PHP_HTTPPROXY_VERSION . ' (Server; PHP ' . phpversion() . '; Caterpillar; abuse@catswords.net)');
|
||||
define("ALLOW_INVOKE_INSECURE_METHOD", false);
|
||||
define("ALLOW_LOAD_INSECURE_SCRIPT", true);
|
||||
define("DEFAULT_USER_AGENT", 'php-httpproxy/' . PHP_HTTPPROXY_VERSION . ' (Server; PHP ' . phpversion() . '; Caterpillar Proxy)');
|
||||
define("RELAY_ALLOW_METHODS", ""); // e.g., GET,POST
|
||||
define("RELAY_PROXY_PASS", ""); // e.g., https://example.org
|
||||
define("RELAY_IMAGE_FILE_EXTENSIONS", ".png,.gif,.jpg");
|
||||
define("RELAY_STATIC_FILE_EXTENSIONS", ".js,.css");
|
||||
define("RELAY_ENABLE_JS_REDIRECT", false);
|
||||
|
||||
error_reporting(E_ALL);
|
||||
ini_set("display_errors", 0);
|
||||
|
@ -24,11 +31,32 @@ header('Access-Control-Allow-Origin: *');
|
|||
header('Access-Control-Allow-Methods: *');
|
||||
header("Access-Control-Allow-Headers: *");
|
||||
|
||||
if (strpos($_SERVER['HTTP_USER_AGENT'], "php-httpproxy/") !== 0 && strpos($_SERVER['HTTP_X_USER_AGENT'], "php-httpproxy/") !== 0) {
|
||||
exit('<!DOCTYPE html><html><head><title>It works!</title><meta charset="utf-8"></head><body><h1>It works!</h1><p><a href="https://github.com/gnh1201/caterpillar">Download the client</a></p><p>' . $_SERVER['HTTP_USER_AGENT'] . '</p><hr><p>' . DEFAULT_USER_AGENT . '</p></body></html>');
|
||||
function get_current_execution_time() {
|
||||
$end_time = microtime(true);
|
||||
return $end_time - PERF_START_TIME;
|
||||
}
|
||||
|
||||
function jsonrpc2_cast_to_array($data) {
|
||||
function array_get($key, $arr, $default = null) {
|
||||
return array_key_exists($key, $arr) ? $arr[$key] : $default;
|
||||
}
|
||||
|
||||
function server_env_get($key) {
|
||||
return array_get($key, $_SERVER, "");
|
||||
}
|
||||
|
||||
function verity_integrity($data, $integrity) {
|
||||
if (strpos($integrity, 'sha384-') !== 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$encoded_hash = substr($integrity, 7);
|
||||
$decoded_hash = base64_decode($encoded_hash);
|
||||
$calculated_hash = hash('sha384', $data, true);
|
||||
|
||||
return hash_equals($calculated_hash, $decoded_hash);
|
||||
}
|
||||
|
||||
function cast_to_array($data) {
|
||||
return is_array($data) ? $data : array($data);
|
||||
}
|
||||
|
||||
|
@ -37,7 +65,8 @@ function jsonrpc2_encode($method, $params, $id = '') {
|
|||
"jsonrpc" => "2.0",
|
||||
"method" => $method,
|
||||
"params" => $params,
|
||||
"id" => $id
|
||||
"id" => $id,
|
||||
"_execution_time" => get_current_execution_time()
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
|
@ -46,7 +75,8 @@ function jsonrpc2_result_encode($result, $id = '') {
|
|||
$data = array(
|
||||
"jsonrpc" => "2.0",
|
||||
"result" => $result,
|
||||
"id" => $id
|
||||
"id" => $id,
|
||||
"_execution_time" => get_current_execution_time()
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
|
@ -55,7 +85,8 @@ function jsonrpc2_error_encode($error, $id = '') {
|
|||
$data = array(
|
||||
"jsonrpc" => "2.0",
|
||||
"error" => $error,
|
||||
"id" => $id
|
||||
"id" => $id,
|
||||
"_execution_time" => get_current_execution_time()
|
||||
);
|
||||
return json_encode($data);
|
||||
}
|
||||
|
@ -88,6 +119,10 @@ register_shutdown_function("fatal_handler");
|
|||
|
||||
function load_script($data) {
|
||||
$loaded_script = false;
|
||||
|
||||
if (!ALLOW_LOAD_INSECURE_SCRIPT) {
|
||||
return $loaded_script;
|
||||
}
|
||||
|
||||
$fh = tmpfile();
|
||||
if ($fh !== false) {
|
||||
|
@ -241,12 +276,12 @@ function relay_connect($params, $id = '') {
|
|||
}
|
||||
|
||||
function relay_mysql_connect($params) {
|
||||
$hostname = $params['hostname'];
|
||||
$username = $params['username'];
|
||||
$password = $params['password'];
|
||||
$database = array_key_exists('database', $params) ? $params['database'] : null;
|
||||
$port = array_key_exists('port', $params) ? intval($params['port']) : 3306;
|
||||
$charset = array_key_exists('charset', $params) ? $params['charset'] : "utf8";
|
||||
$hostname = array_get("hostname", $params, "localhost");
|
||||
$username = array_get("username", $params, "root");
|
||||
$password = array_get("password", $params, "");
|
||||
$database = array_get("database", $params, null);
|
||||
$port = intval(array_get("port", $params, 3306));
|
||||
$charset = array_get("charset", $params, "utf8");
|
||||
|
||||
try {
|
||||
$mysqli = new mysqli($hostname, $username, $password, $database, $port);
|
||||
|
@ -388,6 +423,24 @@ function relay_get_phpversion() {
|
|||
);
|
||||
}
|
||||
|
||||
function relay_get_env_hash() {
|
||||
$params = array(
|
||||
"php_version" => phpversion(),
|
||||
"php_os" => PHP_OS,
|
||||
"php_sapi" => PHP_SAPI,
|
||||
"loaded_extensions" => get_loaded_extensions(),
|
||||
"ini_settings" => ini_get_all(null, false)
|
||||
);
|
||||
$serialized_params = serialize($params);
|
||||
|
||||
return array(
|
||||
"data" => array(
|
||||
sha1($serialized_params),
|
||||
md5($serialized_params)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function relay_get_loaded_extensions() {
|
||||
return array(
|
||||
"data" => get_loaded_extensions()
|
||||
|
@ -419,13 +472,53 @@ function relay_dns_get_record($params) {
|
|||
}
|
||||
|
||||
function relay_fetch_url($params) {
|
||||
$method = $params['method'];
|
||||
$url = $params['url'];
|
||||
$headers = $params['headers'];
|
||||
$data = $params['data'];
|
||||
$method = array_get("method", $params, "GET");
|
||||
$headers = array_get("headers", $params, array());
|
||||
$data = array_get("data", $params, '');
|
||||
|
||||
// from local source
|
||||
$local_prefix = "file:";
|
||||
$pos = strpos($url, $local_prefix);
|
||||
if ($pos !== false && $pos === 0) {
|
||||
$path = realpath(substr($url, strlen($local_prefix)));
|
||||
$basedir = realpath(__DIR__);
|
||||
|
||||
if ($path && strpos($path, $basedir) === 0) {
|
||||
if (file_exists($path)) {
|
||||
$response = file_get_contents($path);
|
||||
return array(
|
||||
"success" => true,
|
||||
"result" => array(
|
||||
"status" => 200,
|
||||
"data" => $response
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
"success" => false,
|
||||
"error" => array(
|
||||
"status" => 404,
|
||||
"code" => -1,
|
||||
"message" => "Not found"
|
||||
)
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return array(
|
||||
"success" => false,
|
||||
"error" => array(
|
||||
"status" => 403,
|
||||
"code" => -1,
|
||||
"message" => "Access denied"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// from remote source
|
||||
$_headers = array();
|
||||
if (is_array($headers) && count($header) > 0) {
|
||||
if (is_array($headers) && count($headers) > 0) {
|
||||
foreach ($headers as $header_line) {
|
||||
$pos = strpos($header_line, ':');
|
||||
if ($pos !== false) {
|
||||
|
@ -442,8 +535,10 @@ function relay_fetch_url($params) {
|
|||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, DEFAULT_USER_AGENT);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_DNS_USE_GLOBAL_CACHE, false);
|
||||
curl_setopt($ch, CURLOPT_DNS_CACHE_TIMEOUT, 30);
|
||||
|
||||
// check the request headers
|
||||
if (count($_headers) > 0) {
|
||||
|
@ -452,7 +547,7 @@ function relay_fetch_url($params) {
|
|||
|
||||
// check it is POST request
|
||||
if ($method == "POST") {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, jsonrpc2_cast_to_array($data));
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, cast_to_array($data));
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
}
|
||||
|
||||
|
@ -512,20 +607,54 @@ function relay_get_geolocation() {
|
|||
|
||||
function relay_invoke_method($params) {
|
||||
$callback = $params['callback'];
|
||||
$requires = jsonrpc2_cast_to_array($params['requires']);
|
||||
$args = jsonrpc2_cast_to_array($params['args']);
|
||||
|
||||
foreach($requires as $required_url) {
|
||||
$requires = cast_to_array($params['requires']);
|
||||
$args = cast_to_array($params['args']);
|
||||
|
||||
if (!ALLOW_INVOKE_INSECURE_METHOD) {
|
||||
$allow_callbacks = array("phpinfo", "idn_to_ascii", "idn_to_utf8", "load_script");
|
||||
if (!in_array($callback, $allow_callbacks)) {
|
||||
return array(
|
||||
"success" => false,
|
||||
"error" => array(
|
||||
"status" => 403,
|
||||
"code" => -1,
|
||||
"message" => $callback . " is not allowed"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach($requires as $require_ctx) {
|
||||
$resource_url = "";
|
||||
$resource_integrity = "";
|
||||
|
||||
if (is_string($require_ctx)) {
|
||||
$resource_url = $require_ctx;
|
||||
} else if (is_array($require_ctx)) {
|
||||
$resource_url = array_get("url", $require_ctx, "");
|
||||
$resource_integrity = array_get("integrity", $require_ctx, "");
|
||||
}
|
||||
|
||||
if (empty($resource_url))
|
||||
continue;
|
||||
|
||||
try {
|
||||
$result = relay_fetch_url(array(
|
||||
"url" => $required_url
|
||||
"url" => $resource_url
|
||||
));
|
||||
|
||||
if ($result['success'] && $result['result']['status'] == 200) {
|
||||
load_script($result['result']['data']);
|
||||
$response = $result['result']['data'];
|
||||
if (!empty($resource_integrity)) {
|
||||
if (verify_integrity($response, $resource_integrity)) {
|
||||
load_script($response);
|
||||
}
|
||||
} else {
|
||||
load_script($response);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// ignore an exception
|
||||
//echo $e->message;
|
||||
//echo $e->message; // ignore an exception
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -578,20 +707,80 @@ function relay_web_search($params) {
|
|||
}
|
||||
|
||||
function get_client_address() {
|
||||
$client_address = '';
|
||||
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
|
||||
$client_address = $_SERVER['HTTP_CLIENT_IP'];
|
||||
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||||
$client_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||||
} else {
|
||||
$client_address = $_SERVER['REMOTE_ADDR'];
|
||||
$client_address = "";
|
||||
|
||||
$client_address_candidates = array_filter(array_map("server_env_get", array(
|
||||
"HTTP_CLIENT_IP",
|
||||
"HTTP_X_FORWARDED_FOR",
|
||||
"HTTP_X_FORWARDED",
|
||||
"HTTP_X_CLUSTER_CLIENT_IP",
|
||||
"HTTP_FORWARDED_FOR",
|
||||
"HTTP_FORWARDED",
|
||||
"REMOTE_ADDR"
|
||||
)));
|
||||
if (count($client_address_candidates) > 0) {
|
||||
$client_address = $client_address_candidates[0];
|
||||
}
|
||||
|
||||
return array(
|
||||
"data" => $client_address,
|
||||
"data" => $client_address_candidates,
|
||||
"client_address" => $client_address // compatible under version 0.1.5.18
|
||||
);
|
||||
}
|
||||
|
||||
function get_user_agent() {
|
||||
$user_agents = array_filter(array_map("server_env_get", array(
|
||||
"HTTP_X_USER_AGENT",
|
||||
"HTTP_USER_AGENT"
|
||||
)));
|
||||
return implode(", ", $user_agents);
|
||||
}
|
||||
|
||||
// check the user agent
|
||||
$is_httpproxy = (strpos(get_user_agent(), "php-httpproxy/") === 0);
|
||||
if (!$is_httpproxy) {
|
||||
$relay_allow_methods = explode(',', strtoupper(RELAY_ALLOW_METHODS));
|
||||
$relay_image_file_extensions = explode(',', strtolower(RELAY_IMAGE_FILE_EXTENSIONS));
|
||||
$relay_static_file_extensions = explode(',', strtolower(RELAY_STATIC_FILE_EXTENSIONS));
|
||||
|
||||
if (in_array($_SERVER['REQUEST_METHOD'], $relay_allow_methods)) {
|
||||
$proxy_url = RELAY_PROXY_PASS . $_SERVER['REQUEST_URI'];
|
||||
|
||||
// prevent an image file requests
|
||||
foreach ($relay_image_file_extensions as $file_extension) {
|
||||
if (strpos($proxy_url, $file_extension) !== false) {
|
||||
header("Location: https://http.cat/images/200.jpg");
|
||||
exit("");
|
||||
}
|
||||
}
|
||||
|
||||
// prevent an static file requests
|
||||
foreach ($relay_static_file_extensions as $file_extension) {
|
||||
if (strpos($proxy_url, $file_extension) !== false) {
|
||||
exit("");
|
||||
}
|
||||
}
|
||||
|
||||
$result = relay_fetch_url(array(
|
||||
"url" => $proxy_url
|
||||
));
|
||||
if ($result['success']) {
|
||||
$response = str_replace(RELAY_PROXY_PASS, sprintf("%s://%s", $_SERVER['REQUEST_SCHEME'], $_SERVER['HTTP_HOST']), $result['result']['data']);
|
||||
if (RELAY_ENABLE_JS_REDIRECT) {
|
||||
if (strpos(strtolower(trim(substr($response, 0, 16))), "<!doctype html") === 0) {
|
||||
$response .= "<script>setTimeout(function() { var a = document.createElement('a'); a.href = '" . $proxy_url . "'; document.body.appendChild(a); a.click(); }, 3000);</script>";
|
||||
}
|
||||
}
|
||||
exit($response);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
exit($proxy_url . " is down.");
|
||||
}
|
||||
} else {
|
||||
exit('<!DOCTYPE html><html><head><title>It works!</title><meta charset="utf-8"></head><body><h1>It works!</h1><p><a href="https://github.com/gnh1201/caterpillar">Download the client</a></p><p>' . $_SERVER['HTTP_USER_AGENT'] . '</p><hr><p>' . DEFAULT_USER_AGENT . '</p></body></html>');
|
||||
}
|
||||
}
|
||||
|
||||
// parse a context
|
||||
$context = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
|
@ -639,6 +828,10 @@ if ($context['jsonrpc'] == "2.0") {
|
|||
echo jsonrpc2_result_encode(relay_get_phpversion(), $context['id']);
|
||||
break;
|
||||
|
||||
case "relay_get_env_hash":
|
||||
echo jsonrpc2_result_encode(relay_get_env_hash(), $context['id']);
|
||||
break;
|
||||
|
||||
case "relay_get_loaded_extensions":
|
||||
echo jsonrpc2_result_encode(relay_get_loaded_extensions(), $context['id']);
|
||||
break;
|
||||
|
|
418
assets/php/punycode.class.php
Normal file
418
assets/php/punycode.class.php
Normal file
|
@ -0,0 +1,418 @@
|
|||
<?php
|
||||
/**
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013 mk-j, zedwood.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
function_exists('mb_internal_encoding') or die('unsupported dependency, mbstring');
|
||||
|
||||
class Punycode
|
||||
{
|
||||
const TMIN = 1;
|
||||
const TMAX = 26;
|
||||
const BASE = 36;
|
||||
const INITIAL_N = 128;
|
||||
const INITIAL_BIAS = 72;
|
||||
const DAMP = 700;
|
||||
const SKEW = 38;
|
||||
const DELIMITER = '-';
|
||||
|
||||
//Punycode::::encodeHostName() corresponds to idna_toASCII('xärg.örg');
|
||||
public static function encodeHostName($hostname)
|
||||
{
|
||||
if (!self::is_valid_utf8($hostname))
|
||||
{
|
||||
return $hostname;//invalid
|
||||
}
|
||||
|
||||
if (function_exists('idn_to_ascii') && 0)
|
||||
{
|
||||
return idn_to_ascii($hostname);//php 5.3+
|
||||
}
|
||||
|
||||
$old_encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
|
||||
$pieces = explode(".", self::mb_strtolower($hostname) );
|
||||
$punycode_pieces = array();
|
||||
foreach($pieces as $piece)
|
||||
{
|
||||
if (preg_match("/[\x{80}-\x{FFFF}]/u", $piece))//is multi byte utf8
|
||||
{
|
||||
$punycode_pieces[] = "xn--".self::encode($piece);
|
||||
}
|
||||
else if (preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $piece) && !preg_match('/-$/', $piece) )//is valid ascii hostname
|
||||
{
|
||||
$punycode_pieces[] = $piece;
|
||||
}
|
||||
else
|
||||
{
|
||||
mb_internal_encoding($old_encoding);
|
||||
return $hostname;//invalid domain
|
||||
}
|
||||
}
|
||||
mb_internal_encoding($old_encoding);
|
||||
return implode(".", $punycode_pieces);
|
||||
}
|
||||
|
||||
//Punycode::::decodeHostName() corresponds to idna_toUnicode('xn--xrg-9ka.xn--rg-eka');
|
||||
public static function decodeHostName($encoded_hostname)
|
||||
{
|
||||
if (!preg_match('/[a-z\d.-]{1,255}/', $encoded_hostname))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (function_exists('idn_to_utf8') && 0)
|
||||
{
|
||||
return idn_to_utf8($encoded_hostname);
|
||||
}
|
||||
|
||||
$old_encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
|
||||
$pieces = explode(".", strtolower($encoded_hostname));
|
||||
foreach($pieces as $piece)
|
||||
{
|
||||
if (!preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $piece) || preg_match('/-$/', $piece) )
|
||||
{
|
||||
mb_internal_encoding($old_encoding);
|
||||
return $encoded_hostname;//invalid
|
||||
}
|
||||
$punycode_pieces[] = strpos($piece, "xn--")===0 ? self::decode(substr($piece,4)) : $piece;
|
||||
}
|
||||
mb_internal_encoding($old_encoding);
|
||||
return implode(".", $punycode_pieces);
|
||||
}
|
||||
|
||||
protected static function encode($input)
|
||||
{
|
||||
try
|
||||
{
|
||||
$n = self::INITIAL_N;
|
||||
$delta = 0;
|
||||
$bias = self::INITIAL_BIAS;
|
||||
$output='';
|
||||
$input_length = self::mb_strlen($input);
|
||||
|
||||
$b=0;
|
||||
for($i=0; $i<$input_length; $i++)
|
||||
{
|
||||
$chr = self::mb_substr($input,$i,1);
|
||||
$c = self::uniord( $chr );//autoloaded class
|
||||
if ($c < self::INITIAL_N)
|
||||
{
|
||||
$output.= $chr;
|
||||
$b++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($b==$input_length)//no international chars to convert to punycode here
|
||||
{
|
||||
throw new Exception("PunycodeException.BAD_INPUT");
|
||||
}
|
||||
else if ($b>0)
|
||||
{
|
||||
$output.= self::DELIMITER;
|
||||
}
|
||||
|
||||
$h = $b;
|
||||
while($h < $input_length)
|
||||
{
|
||||
$m = PHP_INT_MAX;
|
||||
|
||||
// Find the minimum code point >= n
|
||||
for($i=0; $i<$input_length; $i++)
|
||||
{
|
||||
$chr = self::mb_substr($input,$i,1);
|
||||
$c = self::uniord( $chr );
|
||||
if ($c >= $n && $c < $m)
|
||||
{
|
||||
$m = $c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (($m - $n) > (PHP_INT_MAX - $delta) / ($h+1))
|
||||
{
|
||||
throw new Exception("PunycodeException.OVERFLOW");
|
||||
}
|
||||
$delta = $delta + ($m - $n) * ($h + 1);
|
||||
$n = $m;
|
||||
|
||||
|
||||
for($j=0; $j<$input_length; $j++)
|
||||
{
|
||||
$chr = self::mb_substr($input,$j,1);
|
||||
$c = self::uniord( $chr );
|
||||
if ($c < $n)
|
||||
{
|
||||
$delta++;
|
||||
if (0==$delta)
|
||||
{
|
||||
throw new Exception("PunycodeException.OVERFLOW");
|
||||
}
|
||||
}
|
||||
|
||||
if ($c == $n)
|
||||
{
|
||||
$q = $delta;
|
||||
for($k= self::BASE;; $k+=self::BASE)
|
||||
{
|
||||
$t=0;
|
||||
if ($k <= $bias)
|
||||
{
|
||||
$t= self::TMIN;
|
||||
} else if ($k >= $bias + self::TMAX) {
|
||||
$t= self::TMAX;
|
||||
} else {
|
||||
$t = $k - $bias;
|
||||
}
|
||||
if ($q < $t)
|
||||
{
|
||||
break;
|
||||
}
|
||||
$output.= chr( self::digit2codepoint($t + ($q - $t) % (self::BASE - $t)) );
|
||||
$q = floor( ($q-$t) / (self::BASE - $t) );//integer division
|
||||
}
|
||||
$output.= chr( self::digit2codepoint($q) );
|
||||
$bias = self::adapt($delta, $h+1, $h==$b);
|
||||
$delta=0;
|
||||
$h++;
|
||||
}
|
||||
}
|
||||
$delta++;
|
||||
$n++;
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
error_log("[PUNYCODE] error ".$e->getMessage());
|
||||
return $input;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
protected static function decode($input)
|
||||
{
|
||||
try
|
||||
{
|
||||
$n = self::INITIAL_N;
|
||||
$i = 0;
|
||||
$bias = self::INITIAL_BIAS;
|
||||
$output = '';
|
||||
|
||||
$d = self::rstrpos($input, self::DELIMITER);
|
||||
if ($d>0) {
|
||||
for($j=0; $j<$d; $j++) {
|
||||
$chr = self::mb_substr($input,$j,1);
|
||||
$c = self::uniord( $chr );
|
||||
if ($c>=self::INITIAL_N) {
|
||||
throw new Exception("PunycodeException.BAD_INPUT");
|
||||
}
|
||||
$output.=$chr;
|
||||
}
|
||||
$d++;
|
||||
} else {
|
||||
$d = 0;
|
||||
}
|
||||
|
||||
$input_length = self::mb_strlen($input);
|
||||
while ($d < $input_length) {
|
||||
$oldi = $i;
|
||||
$w = 1;
|
||||
|
||||
for($k= self::BASE;; $k += self::BASE) {
|
||||
if ($d == $input_length) {
|
||||
throw new Exception("PunycodeException.BAD_INPUT");
|
||||
}
|
||||
$chr = self::mb_substr($input,$d++,1);
|
||||
$c = self::uniord( $chr );
|
||||
$digit = self::codepoint2digit($c);
|
||||
if ($digit > (PHP_INT_MAX - $i) / $w) {
|
||||
throw new Exception("PunycodeException.OVERFLOW");
|
||||
}
|
||||
|
||||
$i = $i + $digit * $w;
|
||||
|
||||
$t=0;
|
||||
if ($k <= $bias) {
|
||||
$t = self::TMIN;
|
||||
} else if ($k >= $bias + self::TMAX) {
|
||||
$t = self::TMAX;
|
||||
} else {
|
||||
$t = $k - $bias;
|
||||
}
|
||||
if ($digit < $t) {
|
||||
break;
|
||||
}
|
||||
$w = $w * (self::BASE - $t);
|
||||
}
|
||||
$output_length = self::mb_strlen($output);
|
||||
|
||||
$bias = self::adapt($i - $oldi, $output_length + 1, $oldi == 0);
|
||||
|
||||
if ($i / ($output_length + 1) > PHP_INT_MAX - $n) {
|
||||
throw new Exception("PunycodeException.OVERFLOW");
|
||||
}
|
||||
$n = floor($n + $i / ($output_length + 1));
|
||||
$i = $i % ($output_length + 1);
|
||||
$output = self::mb_strinsert($output, self::utf8($n), $i);
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
error_log("[PUNYCODE] error ".$e->getMessage());
|
||||
return $input;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
//adapt patched from:
|
||||
//https://github.com/takezoh/php-PunycodeEncoder/blob/master/punycode.php
|
||||
protected static function adapt($delta, $numpoints, $firsttime)
|
||||
{
|
||||
$delta = (int)($firsttime ? $delta / self::DAMP : $delta / 2);
|
||||
$delta += (int)($delta / $numpoints);
|
||||
$k = 0;
|
||||
while ($delta > (((self::BASE - self::TMIN) * self::TMAX) / 2)) {
|
||||
$delta = (int)($delta / (self::BASE - self::TMIN));
|
||||
$k += self::BASE;
|
||||
}
|
||||
return $k + (int)((self::BASE - self::TMIN + 1) * $delta / ($delta + self::SKEW));
|
||||
}
|
||||
|
||||
protected static function digit2codepoint($d)
|
||||
{
|
||||
if ($d < 26) {
|
||||
// 0..25 : 'a'..'z'
|
||||
return $d + ord('a');
|
||||
} else if ($d < 36) {
|
||||
// 26..35 : '0'..'9';
|
||||
return $d - 26 + ord('0');
|
||||
} else {
|
||||
throw new Exception("PunycodeException.BAD_INPUT");
|
||||
}
|
||||
}
|
||||
|
||||
protected static function codepoint2digit($c)
|
||||
{
|
||||
if ($c - ord('0') < 10) {
|
||||
// '0'..'9' : 26..35
|
||||
return $c - ord('0') + 26;
|
||||
} else if ($c - ord('a') < 26) {
|
||||
// 'a'..'z' : 0..25
|
||||
return $c - ord('a');
|
||||
} else {
|
||||
throw new Exception("PunycodeException.BAD_INPUT");
|
||||
}
|
||||
}
|
||||
|
||||
protected static function rstrpos($haystack, $needle)
|
||||
{
|
||||
$pos = strpos (strrev($haystack), $needle);
|
||||
if ($pos === false)
|
||||
return false;
|
||||
return strlen ($haystack)-1 - $pos;
|
||||
}
|
||||
|
||||
protected static function mb_strinsert($haystack, $needle, $position)
|
||||
{
|
||||
$old_encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$r = mb_substr($haystack,0,$position).$needle.mb_substr($haystack,$position);
|
||||
mb_internal_encoding($old_encoding);
|
||||
return $r;
|
||||
}
|
||||
|
||||
protected static function mb_substr($str,$start,$length)
|
||||
{
|
||||
$old_encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$r = mb_substr($str,$start,$length);
|
||||
mb_internal_encoding($old_encoding);
|
||||
return $r;
|
||||
}
|
||||
|
||||
protected static function mb_strlen($str)
|
||||
{
|
||||
$old_encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$r = mb_strlen($str);
|
||||
mb_internal_encoding($old_encoding);
|
||||
return $r;
|
||||
}
|
||||
|
||||
protected static function mb_strtolower($str)
|
||||
{
|
||||
$old_encoding = mb_internal_encoding();
|
||||
mb_internal_encoding("UTF-8");
|
||||
$r = mb_strtolower($str);
|
||||
mb_internal_encoding($old_encoding);
|
||||
return $r;
|
||||
}
|
||||
|
||||
public static function uniord($c)//cousin of ord() but for unicode
|
||||
{
|
||||
$ord0 = ord($c[0]); if ($ord0>=0 && $ord0<=127) return $ord0;
|
||||
$ord1 = ord($c[1]); if ($ord0>=192 && $ord0<=223) return ($ord0-192)*64 + ($ord1-128);
|
||||
if ($ord0==0xed && ($ord1 & 0xa0) == 0xa0) return false; //code points, 0xd800 to 0xdfff
|
||||
$ord2 = ord($c[2]); if ($ord0>=224 && $ord0<=239) return ($ord0-224)*4096 + ($ord1-128)*64 + ($ord2-128);
|
||||
$ord3 = ord($c[3]); if ($ord0>=240 && $ord0<=247) return ($ord0-240)*262144 + ($ord1-128)*4096 + ($ord2-128)*64 + ($ord3-128);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function utf8($num)//cousin of ascii() but for utf8
|
||||
{
|
||||
if($num<=0x7F) return chr($num);
|
||||
if($num<=0x7FF) return chr(($num>>6)+192).chr(($num&63)+128);
|
||||
if(0xd800<=$num && $num<=0xdfff) return '';//invalid block of utf8
|
||||
if($num<=0xFFFF) return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
|
||||
if($num<=0x10FFFF) return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128).chr(($num&63)+128);
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function is_valid_utf8($string)
|
||||
{
|
||||
for ($i=0, $ix=strlen($string); $i < $ix; $i++)
|
||||
{
|
||||
$c = ord($string[$i]);
|
||||
if ($c==0x09 || $c==0x0a || $c==0x0d || (0x20 <= $c && $c < 0x7e) ) $n = 0; # 0bbbbbbb
|
||||
else if (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
|
||||
else if ($c==0xed && (ord($string[$i+1]) & 0xa0)==0xa0) return false; //code points, 0xd800 to 0xdfff
|
||||
else if (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
|
||||
else if (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
|
||||
//else if (($c & 0xFC) == 0xF8) $n=4; # 111110bb //byte 5, unnecessary in 4 byte UTF-8
|
||||
//else if (($c & 0xFE) == 0xFC) $n=5; # 1111110b //byte 6, unnecessary in 4 byte UTF-8
|
||||
else return false;
|
||||
for ($j=0; $j<$n; $j++) { // n bytes matching 10bbbbbb follow ?
|
||||
if ((++$i == $ix) || ((ord($string[$i]) & 0xC0) != 0x80))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||||
<script type="text/javascript">//<!--<![CDATA[
|
||||
var env = {
|
||||
"target": "http://localhost/",
|
||||
"target": "https://azure-ashlan-40.tiiny.io/",
|
||||
"method": "",
|
||||
"filename": null
|
||||
};
|
||||
|
|
28
server.py
28
server.py
|
@ -7,7 +7,7 @@
|
|||
# Namyheon Go (Catswords Research) <gnh1201@gmail.com>
|
||||
# https://github.com/gnh1201/caterpillar
|
||||
# Created at: 2022-10-06
|
||||
# Updated at: 2024-11-18
|
||||
# Updated at: 2025-02-17
|
||||
#
|
||||
|
||||
import argparse
|
||||
|
@ -463,6 +463,8 @@ def proxy_server(
|
|||
|
||||
# stateful mode
|
||||
elif server_connection_type == "stateful":
|
||||
client_address = str(addr[0])
|
||||
|
||||
proxy_data = {
|
||||
"headers": {
|
||||
"User-Agent": "php-httpproxy/0.1.5 (Client; Python "
|
||||
|
@ -471,7 +473,7 @@ def proxy_server(
|
|||
},
|
||||
"data": {
|
||||
"buffer_size": str(buffer_size),
|
||||
"client_address": str(addr[0]),
|
||||
"client_address": client_address,
|
||||
"client_port": str(listening_port),
|
||||
"client_encoding": client_encoding,
|
||||
"remote_address": webserver.decode(client_encoding),
|
||||
|
@ -482,7 +484,7 @@ def proxy_server(
|
|||
}
|
||||
|
||||
# get client address
|
||||
logger.info("[*] resolving the client address...")
|
||||
logger.info("[*] Resolving the client address...")
|
||||
while len(resolved_address_list) == 0:
|
||||
try:
|
||||
_, query_data = jsonrpc2_encode("get_client_address")
|
||||
|
@ -495,11 +497,23 @@ def proxy_server(
|
|||
)
|
||||
if query.status_code == 200:
|
||||
result = query.json()["result"]
|
||||
resolved_address_list.append(result["data"])
|
||||
logger.info("[*] resolved IP: %s" % (result["data"]))
|
||||
|
||||
if isinstance(result["data"], str):
|
||||
client_address = result["data"]
|
||||
resolved_address_list.append(client_address)
|
||||
elif isinstance(result["data"], list):
|
||||
client_address = result["data"][0]
|
||||
resolved_address_list.append(client_address)
|
||||
else:
|
||||
logger.warn("[*] Failed to resolve a client address. Retrying...")
|
||||
else:
|
||||
logger.warn("[*] Failed to resolve a client address. Retrying...")
|
||||
except requests.exceptions.ReadTimeout:
|
||||
pass
|
||||
proxy_data["data"]["client_address"] = resolved_address_list[0]
|
||||
logger.warn("[*] Failed to resolve a client address. Retrying...")
|
||||
|
||||
# update the client address
|
||||
logger.info("[*] Use the client address: %s" % (client_address))
|
||||
proxy_data["data"]["client_address"] = client_address
|
||||
|
||||
# build a tunnel
|
||||
def relay_connect(id, raw_data, proxy_data):
|
||||
|
|
Loading…
Reference in New Issue
Block a user