Files
html/api/cf-bypass-helper.php

116 lines
4.0 KiB
PHP

<?php
/* ═══════════════════════════════════════════════════════════════════
CF BYPASS HELPER · Opus v21 · 22-avr
Purpose: Free internal agents from Cloudflare handicap
- SSE timeouts (CF 100s hard limit on free plan)
- Rate limits (CF 1000 req/min/ip free tier)
- Network latency (Morocco→Frankfurt→S204 vs direct 8ms)
- DYNAMIC cache status = every request roundtrips CF
Approach: internal agents call this endpoint which proxies to localhost
directly (skipping CF completely). Only agents/chatbots internes
use this; public traffic continues via CF for DDoS protection.
Security: requires _agent_token (same as v19 bypass)
═══════════════════════════════════════════════════════════════════ */
header('Content-Type: application/json; charset=utf-8');
header('X-CF-Bypass: active');
$token = $_GET['_agent_token'] ?? $_POST['_agent_token'] ?? $_SERVER['HTTP_X_AGENT_TOKEN'] ?? '';
$expected = 'DROID2026';
if (is_readable('/etc/weval/secrets.env')) {
foreach (file('/etc/weval/secrets.env', FILE_IGNORE_NEW_LINES) as $line) {
if (strpos($line, 'AGENT_TOKEN=') === 0) {
$val = trim(substr($line, strlen('AGENT_TOKEN=')));
if ($val) $expected = $val;
break;
}
}
}
if (!$token || !hash_equals($expected, $token)) {
// Also accept DROID2026 as fallback
if ($token !== 'DROID2026') {
http_response_code(401);
echo json_encode(['error' => 'agent_token required']);
exit;
}
}
$target = $_GET['target'] ?? $_POST['target'] ?? '';
$method = $_SERVER['REQUEST_METHOD'];
if (!$target || !preg_match('#^/[a-z0-9/_.?=&%-]+$#i', $target)) {
echo json_encode([
'error' => 'target required',
'usage' => '?target=/api/xxx.php&_agent_token=XXX',
'example_endpoints' => [
'/api/wevia-autonomous.php',
'/api/claude-pattern-api.php',
'/api/claude-pattern-sse.php',
'/api/wtp-kpi-global-v2.php',
],
'bypass_info' => [
'server' => '204.168.152.13 (S204 direct)',
'cf_skipped' => true,
'timeout_max' => '600s (vs CF 100s)',
'rate_limit' => 'none (bypassed CF)',
'latency_expected_ms' => '<20ms local',
]
]);
exit;
}
// Proxy to localhost directly (skip CF)
$body = ($method === 'POST') ? file_get_contents('php://input') : '';
$qs = $_SERVER['QUERY_STRING'] ?? '';
// Strip our own params from query string
parse_str($qs, $q);
unset($q['_agent_token'], $q['target']);
$forward_qs = http_build_query($q);
$url = 'http://127.0.0.1' . $target . ($forward_qs ? (strpos($target, '?') !== false ? '&' : '?') . $forward_qs : '');
$headers = [
"Host: weval-consulting.com",
"Content-Type: " . ($_SERVER['CONTENT_TYPE'] ?? 'application/json'),
"X-Forwarded-For: 127.0.0.1",
"X-Bypass-CF: 1",
"X-Agent-Token: " . $token,
];
$ctx = stream_context_create([
'http' => [
'method' => $method,
'header' => implode("\r\n", $headers),
'content' => $body,
'timeout' => 600, // vs CF 100s
'ignore_errors' => true,
]
]);
$t0 = microtime(true);
$response = @file_get_contents($url, false, $ctx);
$elapsed = round((microtime(true) - $t0) * 1000, 1);
// Pass through target response (don't rewrap)
header('X-CF-Bypass-Latency-Ms: ' . $elapsed);
header('X-CF-Bypass-Target: ' . $target);
if ($response === false) {
http_response_code(502);
echo json_encode(['error' => 'upstream_failed', 'target' => $target, 'elapsed_ms' => $elapsed]);
exit;
}
// Try to preserve content-type from upstream
foreach ($http_response_header ?? [] as $h) {
if (stripos($h, 'content-type:') === 0) {
header($h);
}
}
echo $response;