I have this PHP script:
<?PHP
// 0. Start The Session, If Not Already Started:
if(session_status() == PHP_SESSION_NONE)
{
session_start([
"lifetime" => 3600,
"path" => "/",
"domain" => $_SERVER["HTTP_HOST"],
"secure" => isset($_SERVER["HTTPS"]),
"httponly" => true,
"samesite" => "Strict",
]);
session_regenerate_id(true);
}
// 1. Configuration Settings:
define("ENABLE_REDIRECTION", 1);
define("ERROR_LOG_PATH", __DIR__ . "/Error_Log.txt");
define("DEFAULT_CHARSET", "UTF-8");
define("KAPIJA", "/");
// 2. Enable G. N. U. Zip Compression, If Supported by The Client:
if(isset($_SERVER["HTTP_ACCEPT_ENCODING"]))
{
if(strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "br") !== false)
{
ob_start("ob_start_brotli");
}
elseif(strpos($_SERVER["HTTP_ACCEPT_ENCODING"], "gzip") !== false)
{
ob_start("ob_gzhandler");
}
else
{
ob_start();
}
}
// 3. Check for Session Hijacking:
if(!isset($_SESSION["IPaddress"]) || !isset($_SESSION["userAgent"]))
{
$_SESSION["IPaddress"] = $_SERVER["REMOTE_ADDR"];
$_SESSION["userAgent"] = $_SERVER["HTTP_USER_AGENT"];
}
elseif($_SESSION["IPaddress"] !== $_SERVER["REMOTE_ADDR"] || $_SESSION["userAgent"] !== $_SERVER["HTTP_USER_AGENT"])
{
session_unset(); // Clear session data
session_destroy(); // Destroy the session
session_start(); // Start a new session
session_regenerate_id(true); // Regenerate session ID
$_SESSION["IPaddress"] = $_SERVER["REMOTE_ADDR"];
$_SESSION["userAgent"] = $_SERVER["HTTP_USER_AGENT"];
}
// 4. Set A Session Timeout and Periodically Regenerate Session ID:
if(!isset($_SESSION["CREATED"]))
{
$_SESSION["CREATED"] = time();
}
elseif(time() - $_SESSION["CREATED"] > 1860)
{
session_regenerate_id(true);
$_SESSION["CREATED"] = time();
}
// 5. Security Headers:
header("Content-Type: text/css; charset=UTF-8");
header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://trusted.cdn.com https://www.googletagmanager.com https://cdnjs.cloudflare.com; style-src 'self' 'unsafe-inline' https://trusted.cdn.com; img-src 'self' data:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none';");
header("X-Content-Type-Options: nosniff");
header("X-Frame-Options: DENY");
header("X-XSS-Protection: 1; mode=block");
header("Strict-Transport-Security: max-age=86400; includeSubDomains; preload");
// 6. Enable Error Logging for Debugging (Disable Display Errors for Production):
ini_set("display_errors", 0);
ini_set("display_startup_errors", 0);
ini_set("log_errors", 1);
ini_set("error_log", ERROR_LOG_PATH);
error_reporting(E_ALL);
// 7. Redirect to Home Page If Accessing Izvor.PHP:
if($_SERVER["REQUEST_URI"] === "/Izvor.PHP")
{
header("Location: " . KAPIJA, true, 301); exit();
}
// 8. Ensure UTF-8 encoding
mb_internal_encoding("UTF-8");
ini_set("default_charset", DEFAULT_CHARSET);
header("Content-Type: text/html; charset=" . DEFAULT_CHARSET);
// 9. Set Locale for Serbian (Both Latin and Cyrillic):
setlocale(LC_ALL, "sr_RS.UTF-8"); // Serbian Cyrillic
setlocale(LC_ALL, "[email protected]"); // Serbian Latin
setlocale(LC_ALL, "en_GB.UTF-8"); // British English
// 10. Comprehensive Function to Process URLs:
function process_comprehensive_url($url)
{
// 10. 1. Decode the URL to Get The Actual Characters:
$decoded_url = rawurldecode($url);
// 10. 2. Sanitize The URL:
$sanitized_url = htmlspecialchars($decoded_url, ENT_QUOTES, "UTF-8");
// 10. 3. Specific Handling for Ampersands:
$final_url = str_replace("&", "&", $sanitized_url);
return $final_url; // Return The Processed URL
}
// 13. Secure Input Validation Function:
function secure_input($data)
{
return htmlspecialchars($data, ENT_QUOTES, "UTF-8");
}
// 14. Function to Internally Handle and Map Keys to Unique Identifiers:
function get_hashed_key($key)
{
static $key_map = [];
if($key === "")
{
$unique_key = md5(uniqid("", true));
$key_map[$unique_key] = $key;
return $unique_key;
}
return $key;
}
// 15. Function to Retrieve The Original Key:
function get_original_key($unique_key)
{
global $key_map;
return $key_map[$unique_key] ?? $unique_key;
}
// 16. URL-to-File-Path Mapping With and Without Leading Slashes and With Potential Empty Keys, Handled Internally, Including UTF-8 Names:
$url_map = [
get_hashed_key(process_comprehensive_url("")) => process_comprehensive_url(""),
];
// 17. Downloading Map:
// Adding downloads on click:
$download_map = [
get_hashed_key(process_comprehensive_url("")) => "",
];
/* <?PHP
If(Session_Status() == PHP_SESSION_NONE)
{
Session_Start();
}
Echo(IsSet($_SESSION["metaTags"])? $_SESSION["metaTags"]: "");
?> */
// Functions to add META tags:
function addCommonMetaTags()
{
echo("<META HTTP-Equiv="Content-Type" Content="Text/HTML; CharSet=UTF-8">n");
}
function addSpecificMetaTags($page)
{
switch($page)
{
case("/"):
default:
echo("<META Name="Page-Name" Content="">n");
break;
}
}
function addMetaTags($page)
{
addCommonMetaTags();
// addSpecificMetaTags($page);
}
// Determine the page type based on the request URI
$request_uri = process_comprehensive_url($_SERVER['REQUEST_URI']);
// Normalize the request URI
$pageType = $request_uri;
// Start output buffering to capture and insert META tags
ob_start();
addCommonMetaTags();
addSpecificMetaTags($pageType);
$metaTags = ob_get_clean();
// Store the META tags in a session or a global variable for later use
$_SESSION["metaTags"] = $metaTags;
// 18. URLs and Their Pages:
$routes = [
get_hashed_key(process_comprehensive_url("/")) => __DIR__ . "/",
];
// 19. Redirections:
$urls_to_be_redirected = [
get_hashed_key(process_comprehensive_url("/")) => process_comprehensive_url("/2025"),
];
// 20. Define Error Pages:
$error_pages = [
"404" => __DIR__ . "/Errors/404.html",
// Add more error pages if needed
];
// 21. Process The Request URI and Clean Path:
$request_uri = process_comprehensive_url($_SERVER["REQUEST_URI"]);
$clean_path = process_comprehensive_url(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH));
$clean_path = ltrim($clean_path, "/");
// 22. Normalize Clean Path to Ensure It Matches Our Internally Handled Keys:
$normalized_clean_path = get_hashed_key($clean_path);
// 23. Debugging: Log The Processed Paths:
error_log("Processed request_uri: " . $request_uri);
error_log("Processed clean_path: " . $clean_path);
// 24. Handle FavIcon Requests:
if($clean_path === "Trougao" || $clean_path === "favicon.ico")
{
$favicon_path = __DIR__ . "/" . $url_map["Trougao"];
error_log("Serving favicon from path: " . $favicon_path);
if(file_exists($favicon_path))
{
serve_document($favicon_path, "image/png");
}
else
{
error_log("File not found: " . $favicon_path);
echo("File not found.");
}
exit();
}
// 25. Handle Download Requests:
if(array_key_exists($normalized_clean_path, $download_map))
{
$file_path = __DIR__ . "/" . $download_map[$normalized_clean_path];
error_log("Serving file for download: " . $file_path);
if(file_exists($file_path))
{
serve_document($file_path, "application/octet-stream", true);
}
else
{
error_log("File not found: " . $file_path);
echo("File not found.");
}
exit();
}
// 26. Handling The Root Path Case:
if($clean_path === "")
{
$clean_path = "/";
}
// 28. Function to Get The MIME Type of A File:
function get_mime_type($file)
{
$mime_types = [
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"css" => "text/css",
"csv" => "text/csv",
"woff" => "font/woff",
"woff2" => "font/woff2",
"ttf" => "font/ttf",
"otf" => "font/otf",
"js" => "application/javascript",
"json" => "application/json",
"pdf" => "application/pdf",
"xml" => "application/xml",
"zip" => "application/zip",
"rar" => "application/x-rar-compressed",
"jpg" => "image/jpeg",
"jpeg" => "image/jpeg",
"png" => "image/png",
"gif" => "image/gif",
"ico" => "image/x-icon",
"svg" => "image/svg+xml",
"webp" => "image/webp",
"mp4" => "video/mp4",
"mp3" => "audio/mpeg",
];
$extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
return $mime_types[$extension] ?? "application/octet-stream";
}
// 29. Serve The Document with Proper MIME Type:
function serve_document($document, $mime_type, $is_download = false)
{
if(file_exists($document))
{
header("Content-Type: " . $mime_type);
header("Content-Length: " . filesize($document));
header("Last-Modified: " . gmdate("D, d M Y H:i:s", filemtime($document)) . " GMT");
if($is_download)
{
header("Content-Disposition: attachment; filename='" . basename($document) . "'");
}
readfile($document); exit();
}
else
{
error_log("File not found: " . $document);
echo("File not found."); exit();
}
}
// 29. Rate Limiting to Prevent Abuse:
$rate_limit_key = $_SERVER["REMOTE_ADDR"] . ":" . $clean_path;
if(!rate_limit_check($rate_limit_key, 3010, 3600))
{
header("HTTP/1.1 429 Too Many Requests");
echo("Too many requests. Please try again later."); exit;
}
function rate_limit_check($key, $limit = 3010, $window = 3600)
{
$current_time = time();
if(!isset($_SESSION["rate_limit"][$key]))
{
$_SESSION["rate_limit"][$key] = ["count" => 0, "start" => $current_time];
}
$data = &$_SESSION["rate_limit"][$key];
if($current_time - $data["start"] > $window)
{
$data = ["count" => 0, "start" => $current_time];
}
$data["count"]++;
return $data["count"] <= $limit;
}
// 30. Check If Redirection Is Enabled and Handle Accordingly:
if(ENABLE_REDIRECTION && array_key_exists($request_uri, $urls_to_be_redirected))
{
$redirect_to = $urls_to_be_redirected[$request_uri];
if(array_key_exists($redirect_to, $routes))
{
$file_path = get_full_path($routes[$redirect_to]);
if(file_exists($file_path))
{
header("Location: $redirect_to"); exit();
}
else
{
log_error("File does not exist: $file_path");
handle_error(404, $error_pages);
}
}
else
{
log_error("Route does not exist: $redirect_to");
handle_error(404, $error_pages);
}
}
elseif(array_key_exists($request_uri, $routes))
{
$file_path = get_full_path($routes[$request_uri]);
if(file_exists($file_path))
{
require $file_path;
}
else
{
log_error("File does not exist: $file_path");
handle_error(404, $error_pages);
}
}
elseif(array_key_exists($clean_path, $url_map))
{
serve_document(__DIR__ . "/" . $url_map[$clean_path], get_mime_type($url_map[$clean_path]));
}
else
{
log_error("Route does not exist: $request_uri");
handle_error(404, $error_pages);
}
// 31. Error-Handling Function:
function handle_error($error_code, $error_pages)
{
http_response_code($error_code);
$error_message = "$error_code Error - Page not found";
log_error($error_message);
if(is_array($error_pages) && array_key_exists((string)$error_code, $error_pages) && file_exists($error_pages[(string)$error_code]))
{
include $error_pages[(string)$error_code];
}
else
{
echo("$error_message");
}
exit();
}
// 32. Function to Get The Full Path:
function get_full_path($path)
{
return (strpos($path, "/") === 0 || strpos($path, ":") === 1)? $path: __DIR__ . "/" . $path;
}
// 33. Logging Function:
function log_error($message)
{
error_log($message, 3, ERROR_LOG_PATH);
}
?>
Which has all the functions I currently need. It loads files as expected.
But when I enter responsive mode in Firefox, with this script, it stops loading some SubCSS (@import URL) files. When I entered console, it tells me that
header("X-Content-Type-Options: nosniff");
prevents CSS from being properly loaded in Firefox’s responsive mode.
I tried to fix it with the help of Copilot (Artificial Intelligence), but it keeps getting bad things far more worse. Can you please check it and improve it?
Copilot “changed” some code in it and, after that, the PHP script downloaded files without extension in stead of loading and displaying it properly in browser…
Can you please help me to improve my script to work fully well, both with responsive and non-responsive modes?