resolveDocumentPath($docsetId, $relativePath); if(!$doc) { http_response_code(404); header('Content-Type: text/plain; charset=utf-8'); echo "Docset asset not found."; exit; } $file = $doc['file']; $mime = detect_docset_mime($file); header('Content-Type: '.$mime); header('X-Content-Type-Options: nosniff'); if(str_starts_with($mime, 'text/html')) { header("Content-Security-Policy: default-src 'self' data:; script-src 'none'; object-src 'none'; frame-ancestors 'self'; img-src 'self' data:; font-src 'self' data:; style-src 'self' 'unsafe-inline'"); echo DocsetRenderer::rewriteAssetHtml((string)file_get_contents($file), $repo, $docsetId, dirname($doc['relative'])); exit; } readfile($file); exit; function detect_docset_mime(string $file): string { $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); $map = array( 'html' => 'text/html; charset=utf-8', 'htm' => 'text/html; charset=utf-8', 'css' => 'text/css; charset=utf-8', 'js' => 'application/javascript; charset=utf-8', 'json' => 'application/json; charset=utf-8', 'png' => 'image/png', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'gif' => 'image/gif', 'svg' => 'image/svg+xml', 'webp' => 'image/webp', 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'ttf' => 'font/ttf', 'ico' => 'image/x-icon', ); return $map[$extension] ?? 'application/octet-stream'; }