path correction
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* Forward /citpl_website/api/* → Node (Express) without requiring Apache mod_proxy.
|
||||
* Start the API on the server: cd /path/to/app && npm run server
|
||||
* Or: pm2 start server/index.js --name citpl-api
|
||||
*/
|
||||
declare(strict_types=1);
|
||||
|
||||
$apiOrigin = getenv('CITPL_API_ORIGIN') ?: 'http://127.0.0.1:3001';
|
||||
|
||||
$requestUri = $_SERVER['REQUEST_URI'] ?? '/api';
|
||||
$path = parse_url($requestUri, PHP_URL_PATH) ?: '/api';
|
||||
|
||||
// Keep everything from "/api" onward (works under /citpl_website/api/...)
|
||||
if (preg_match('#(/api(?:/.*)?)$#', $path, $m)) {
|
||||
$forwardPath = $m[1];
|
||||
} else {
|
||||
$forwardPath = '/api';
|
||||
}
|
||||
|
||||
$query = $_SERVER['QUERY_STRING'] ?? '';
|
||||
$url = rtrim($apiOrigin, '/') . $forwardPath . ($query !== '' ? '?' . $query : '');
|
||||
|
||||
$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
|
||||
$body = file_get_contents('php://input');
|
||||
if ($body === false) {
|
||||
$body = '';
|
||||
}
|
||||
|
||||
$headers = [];
|
||||
if (function_exists('getallheaders')) {
|
||||
foreach (getallheaders() as $name => $value) {
|
||||
$lower = strtolower((string) $name);
|
||||
if ($lower === 'host' || $lower === 'content-length') {
|
||||
continue;
|
||||
}
|
||||
$headers[] = $name . ': ' . $value;
|
||||
}
|
||||
} else {
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
if (strpos($key, 'HTTP_') !== 0) {
|
||||
continue;
|
||||
}
|
||||
$name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
|
||||
if (strtolower($name) === 'host') {
|
||||
continue;
|
||||
}
|
||||
$headers[] = $name . ': ' . $value;
|
||||
}
|
||||
if (!empty($_SERVER['CONTENT_TYPE'])) {
|
||||
$headers[] = 'Content-Type: ' . $_SERVER['CONTENT_TYPE'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('curl_init')) {
|
||||
http_response_code(500);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'error' => 'PHP curl extension is required for the API proxy',
|
||||
'code' => 'PROXY_MISCONFIGURED',
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_CUSTOMREQUEST => $method,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_FOLLOWLOCATION => false,
|
||||
CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_TIMEOUT => 60,
|
||||
CURLOPT_HTTPHEADER => $headers,
|
||||
]);
|
||||
|
||||
if ($method !== 'GET' && $method !== 'HEAD') {
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
}
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if ($response === false) {
|
||||
$err = curl_error($ch);
|
||||
curl_close($ch);
|
||||
http_response_code(502);
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode([
|
||||
'error' => 'API server unreachable. On the host run: npm run server (port 3001)',
|
||||
'detail' => $err,
|
||||
'code' => 'BAD_GATEWAY',
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$headerSize = (int) curl_getinfo($ch, CURLINFO_HEADER_SIZE);
|
||||
curl_close($ch);
|
||||
|
||||
$rawHeaders = substr($response, 0, $headerSize);
|
||||
$responseBody = substr($response, $headerSize);
|
||||
|
||||
http_response_code($status > 0 ? $status : 502);
|
||||
|
||||
$skip = ['transfer-encoding', 'connection', 'keep-alive', 'content-length'];
|
||||
foreach (explode("\r\n", $rawHeaders) as $line) {
|
||||
if ($line === '' || stripos($line, 'HTTP/') === 0) {
|
||||
continue;
|
||||
}
|
||||
$parts = explode(':', $line, 2);
|
||||
if (count($parts) < 2) {
|
||||
continue;
|
||||
}
|
||||
$name = trim($parts[0]);
|
||||
if (in_array(strtolower($name), $skip, true)) {
|
||||
continue;
|
||||
}
|
||||
header($name . ':' . $parts[1], false);
|
||||
}
|
||||
|
||||
echo $responseBody;
|
||||
Reference in New Issue
Block a user