$value) { $lowerName = strtolower($name); // Skip headers that shouldn't be forwarded if (!in_array($lowerName, ['host', 'connection', 'authorization', 'cookie', 'referer', 'origin'])) { $headersToForward[] = "$name: $value"; } } // Add Accept header if not present if (!isset($headersToForward['Accept'])) { $headersToForward[] = 'Accept: */*'; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headersToForward); // Get response headers $responseHeaders = []; curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$responseHeaders) { $len = strlen($header); $header = explode(':', $header, 2); if (count($header) < 2) { return $len; } $name = strtolower(trim($header[0])); $value = trim($header[1]); // Skip headers that shouldn't be forwarded to client if (!in_array($name, ['transfer-encoding', 'connection'])) { $responseHeaders[$name] = $value; } return $len; }); // Execute request $response = curl_exec($ch); // Check for errors if (curl_errno($ch)) { http_response_code(500); header('Content-Type: application/json'); echo json_encode([ 'error' => 'Proxy error: ' . curl_error($ch), 'url' => $geoserverUrl ]); curl_close($ch); exit; } // Get response info $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); curl_close($ch); // Set response code http_response_code($httpCode); // Forward response headers foreach ($responseHeaders as $name => $value) { header("$name: $value"); } // Ensure Content-Type is set if (!isset($responseHeaders['content-type']) && $contentType) { header("Content-Type: $contentType"); } // Add CORS headers for same-origin requests (optional but helpful) header("Access-Control-Allow-Origin: " . ($_SERVER['HTTP_ORIGIN'] ?? '*')); header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type"); header("Access-Control-Allow-Credentials: true"); // Output response echo $response;