add parameter forwarding in URL
This commit is contained in:
BIN
backend/app/.DS_Store
vendored
Normal file
BIN
backend/app/.DS_Store
vendored
Normal file
Binary file not shown.
@ -86,7 +86,7 @@ NGINX config example:
|
|||||||
|
|
||||||
4. **Map domain in /etc/hosts**
|
4. **Map domain in /etc/hosts**
|
||||||
```bash
|
```bash
|
||||||
127.0.0.1 mitul.lxdapp.local
|
127.0.0.1 test.lxdapp.local
|
||||||
|
|
||||||
5. **Make sure LXD is working**
|
5. **Make sure LXD is working**
|
||||||
```bash
|
```bash
|
||||||
@ -112,7 +112,7 @@ NGINX config example:
|
|||||||
|
|
||||||
**Headers:**
|
**Headers:**
|
||||||
|
|
||||||
Origin: http://mitul.lxdapp.local
|
Origin: http://customer.lxdapp.local
|
||||||
|
|
||||||
**Response:**
|
**Response:**
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@ -1,2 +1,3 @@
|
|||||||
{
|
{
|
||||||
|
"test.lxdapp.local": "container-test"
|
||||||
}
|
}
|
||||||
Binary file not shown.
@ -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
|
|
||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
|
|
||||||
use App\Managers\LXDProxyManager;
|
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
@ -20,7 +19,7 @@ class ProxyController
|
|||||||
$mainDomain = $_ENV['MAIN_DOMAIN'] ?? 'lxdapp.local';
|
$mainDomain = $_ENV['MAIN_DOMAIN'] ?? 'lxdapp.local';
|
||||||
|
|
||||||
$origin = $request->getHeaderLine('Origin');
|
$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();
|
$params = (array)$request->getParsedBody();
|
||||||
|
|
||||||
$configPath = __DIR__ . '/../../config.json';
|
$configPath = __DIR__ . '/../../config.json';
|
||||||
@ -145,6 +144,74 @@ class ProxyController
|
|||||||
* Proxies the request to the container.
|
* Proxies the request to the container.
|
||||||
*/
|
*/
|
||||||
private function proxyToContainer(Request $request, Response $response, string $ip, string $name): Response
|
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";
|
$target = $ip ? "http://$ip:80" : "http://127.0.0.1:3000";
|
||||||
|
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -6,6 +6,6 @@ use App\Controllers\ProxyController;
|
|||||||
return function (App $app) {
|
return function (App $app) {
|
||||||
// Proxy route
|
// Proxy route
|
||||||
$app->group('/api/v1', function ($group) {
|
$app->group('/api/v1', function ($group) {
|
||||||
$group->any('/proxy', [ProxyController::class, 'forward']);
|
$group->any('/{routes:.*}', [ProxyController::class, 'forward']);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user