add parameter forwarding in URL

This commit is contained in:
2025-07-09 14:39:49 +02:00
parent 4aa3a766c6
commit ed6443347a
8 changed files with 73 additions and 158 deletions

BIN
backend/app/.DS_Store vendored Normal file

Binary file not shown.

View File

@ -86,7 +86,7 @@ NGINX config example:
4. **Map domain in /etc/hosts**
```bash
127.0.0.1 mitul.lxdapp.local
127.0.0.1 test.lxdapp.local
5. **Make sure LXD is working**
```bash
@ -112,7 +112,7 @@ NGINX config example:
**Headers:**
Origin: http://mitul.lxdapp.local
Origin: http://customer.lxdapp.local
**Response:**
```bash

View File

@ -1,2 +1,3 @@
{
"test.lxdapp.local": "container-test"
}

Binary file not shown.

View File

@ -1,10 +0,0 @@
2025-07-08 13:07:05 : http://10.110.90.30:80
2025-07-08 13:29:10 : http://10.110.90.30:80
2025-07-08 14:43:45 : http://10.110.90.144:80
2025-07-08 14:50:28 : http://10.110.90.89:80
2025-07-08 14:53:41 : http://10.110.90.89:80
2025-07-08 15:07:07 : http://10.110.90.95:80
2025-07-08 15:12:49 : http://10.110.90.95:80
2025-07-08 15:23:59 : http://10.110.90.147:80
2025-07-08 15:24:26 : http://10.110.90.147:80
2025-07-09 06:15:42 : http://10.110.90.248:80

View File

@ -2,7 +2,6 @@
namespace App\Controllers;
use App\Managers\LXDProxyManager;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use GuzzleHttp\Client;
@ -20,7 +19,7 @@ class ProxyController
$mainDomain = $_ENV['MAIN_DOMAIN'] ?? 'lxdapp.local';
$origin = $request->getHeaderLine('Origin');
$domain = parse_url($origin, PHP_URL_HOST); // e.g. mitul.lxdapp.local
$domain = parse_url($origin, PHP_URL_HOST); // e.g. customer.lxdapp.local
$params = (array)$request->getParsedBody();
$configPath = __DIR__ . '/../../config.json';
@ -145,6 +144,74 @@ class ProxyController
* Proxies the request to the container.
*/
private function proxyToContainer(Request $request, Response $response, string $ip, string $name): Response
{
$client = new Client([
'http_errors' => false,
'timeout' => 10,
]);
$method = $request->getMethod();
$baseUrl = $ip ? "http://$ip" : "http://127.0.0.1:3000";
$uri = $request->getUri();
$path = $uri->getPath();
// Remove /api/v1 prefix from path
$prefix = '/api/v1';
if (strpos($path, $prefix) === 0) {
$path = substr($path, strlen($prefix));
if ($path === '') {
$path = '/';
}
}
// Add .php extension if not present
if (!str_ends_with($path, '.php')) {
$path .= '.php';
}
$query = $uri->getQuery();
$targetUrl = $baseUrl . $path . ($query ? '?' . $query : '');
$options = [
'headers' => [],
'http_errors' => false,
'debug' => false,
];
foreach ($request->getHeaders() as $headerName => $values) {
if (strtolower($headerName) !== 'host') {
$options['headers'][$headerName] = implode(', ', $values);
}
}
$options['headers'] = [
'Host' => (string) $ip,
'Accept-Encoding' => 'gzip, deflate',
'Accept' => '*/*',
'User-Agent' => 'SlimProxy/1.0',
];
if (in_array($method, ['POST', 'PUT', 'PATCH', 'DELETE'])) {
$body = (string) $request->getBody();
if ($body) {
$options['body'] = $body;
}
}
$forwarded = $client->request($method, $targetUrl, $options);
$this->writeLastAccessLog($name, $targetUrl);
foreach ($forwarded->getHeaders() as $headerName => $headerValues) {
$response = $response->withHeader($headerName, implode(', ', $headerValues));
}
$response->getBody()->write((string) $forwarded->getBody());
return $response->withStatus($forwarded->getStatusCode());
}
private function proxyToContainerOLD(Request $request, Response $response, string $ip, string $name): Response
{
$target = $ip ? "http://$ip:80" : "http://127.0.0.1:3000";

View File

@ -1,143 +0,0 @@
<?php
namespace App\Managers;
use App\Services\LxdService;
class LXDProxyManager
{
protected LxdService $lxdService;
protected string $mapFile = '/etc/nginx/lxd_map.conf';
public function __construct(LxdService $lxdService)
{
$this->lxdService = $lxdService;
}
/**
* Handle request to container: return IP or null if fallback needed.
*/
public function handleRequest(string $name, $domain)
{
try {
$container = $this->lxdService->containerExists($name);
if (!$container) {
$this->lxdService->createContainer($name);
sleep(10);
$this->lxdService->startContainer($name);
$maxRetries = 20;
$delay = 2;
for ($i = 0; $i < $maxRetries; $i++) {
$status = $this->lxdService->getStatus($name);
if ($status['metadata']['status'] === 'Running') {
break;
}
sleep($delay);
}
$this->lxdService->installPackages($name);
sleep(5);
$ipv4 = $this->lxdService->getContainerIP($name);
$maxRetries = 20;
$waitSeconds = 3;
$ready = false;
for ($i = 0; $i < $maxRetries; $i++) {
// Try to connect to port 80 on container IP (you can use fsockopen, curl, or similar)
$connection = @fsockopen($ipv4, 80, $errno, $errstr, 2);
if ($connection) {
fclose($connection);
$ready = true;
break;
}
sleep($waitSeconds);
}
$hostConfigPath = __DIR__ . '/../../config.json';
if (file_exists($hostConfigPath)) {
$hostConfigData = json_decode(file_get_contents($hostConfigPath), true);
} else {
// If the file doesn't exist, initialize an empty array
$hostConfigData = [];
}
// Step 3: Append the new container entry to the JSON data
$hostConfigData[$domain] = $name;
// Step 4: Write the updated data back to the host-config.json file
file_put_contents($hostConfigPath, json_encode($hostConfigData, JSON_PRETTY_PRINT));
@mkdir('/var/www/last-access', 0777, true);
@touch("/var/www/last-access/$name.txt");
return [
'status' => 'success',
'ip' => $ipv4,
];
}
if ($container['metadata']['status'] === 'Running') {
$ipv4 = $this->getIPv4FromMetadata($container['metadata']);
return [
'status' => 'success',
'ip' => $ipv4,
];
}
// Start the container and wait for IP
$this->lxdService->startContainer($name);
$maxRetries = 30;
$delay = 2;
$ipv4 = null;
for ($i = 0; $i < $maxRetries; $i++) {
$status = $this->lxdService->getStatus($name);
$ipv4 = $this->getIPv4FromMetadata($status['metadata']);
if (!empty($ipv4)) {
break;
}
sleep($delay);
}
if ($ipv4) {
return [
'status' => 'success',
'ip' => $ipv4,
];
}
return [
'status' => 'failed',
'message' => 'Container did not acquire an IP in time.',
];
} catch (\Exception $e) {
return [
'status' => 'failed',
'error' => $e->getMessage(),
];
}
}
public function getIPv4FromMetadata(array $metadata): ?string
{
if (
isset($metadata['network']['eth0']['addresses']) &&
is_array($metadata['network']['eth0']['addresses'])
) {
foreach ($metadata['network']['eth0']['addresses'] as $addr) {
if (isset($addr['family']) && $addr['family'] === 'inet' && isset($addr['address'])) {
return $addr['address'];
}
}
}
return null;
}
}

View File

@ -6,6 +6,6 @@ use App\Controllers\ProxyController;
return function (App $app) {
// Proxy route
$app->group('/api/v1', function ($group) {
$group->any('/proxy', [ProxyController::class, 'forward']);
$group->any('/{routes:.*}', [ProxyController::class, 'forward']);
});
};