登录后提供受限PDF时出现404错误,寻求技术排查帮助
WordPress插件PDF访问限制问题排查求助
我正在开发一款WordPress插件,用于限制站点特定区域的PDF文件访问——仅允许已登录用户查看。这些PDF存储在wp-content/custom-files/pdfs/目录下,文件名均以s开头。
问题现象
插件逻辑看似正常,已登录用户访问受限PDF时,WordPress调试日志显示插件触发、识别用户已登录、成功找到PDF文件,且日志显示已通过readfile()(或fpassthru())发送文件,还记录了正确的文件大小并提示字节全部发送完成。但浏览器并未加载PDF,而是返回404 Not Found错误。奇怪的是,访问同目录下不以s开头的PDF(插件不触发)则完全正常,推测问题出在插件执行后、浏览器接收文件前的环节。
代码片段
插件代码
<?php /** Plugin Name: ... */ defined('ABSPATH') || exit; add_action( 'template_redirect', 'restrict_s_pdfs' ); function restrict_s_pdfs() { error_log('restrict_s_pdfs function called'); // Check if the user is trying to access a restricted PDF if ( strpos( $_SERVER['REQUEST_URI'], '/wp-content/custom-files/pdfs/s' ) !== false && strtolower( pathinfo( $_SERVER['REQUEST_URI'], PATHINFO_EXTENSION ) ) === 'pdf' ) { error_log('Potential restricted PDF access detected: ' . $_SERVER['REQUEST_URI']); if ( is_user_logged_in() ) { error_log('User is logged in.'); // Define the full path to the PDF file (remove the leading slash from REQUEST_URI) $filepath = ABSPATH . ltrim(urldecode( $_SERVER['REQUEST_URI'] ), '/'); error_log('Filepath constructed: ' . $filepath); // Security check: Ensure the file exists and is within the allowed directory $file_exists = file_exists( $filepath ); error_log('file_exists: ' . ($file_exists ? 'true' : 'false')); $is_within_allowed_dir = strpos( $filepath, ABSPATH . 'wp-content/custom-files/pdfs/' ) === 0; error_log('is_within_allowed_dir: ' . ($is_within_allowed_dir ? 'true' : 'false')); if ( $file_exists && $is_within_allowed_dir ) { error_log('File exists and is within allowed directory. Serving PDF inline.'); ob_end_clean(); // Try clearing output buffer // Set the appropriate headers for a PDF header('Content-Type: application/pdf'); error_log('Content-Type header sent.'); header('Content-Disposition: inline; filename="' . basename( $_SERVER['REQUEST_URI'] ) . '"'); error_log('Content-Disposition header sent.'); $filesize = filesize($filepath); header('Content-Length: ' . $filesize); error_log('Content-Length header sent: ' . $filesize); error_log('About to readfile for inline display: ' . $filepath); $bytes_sent = readfile($filepath); error_log('readfile completed for inline display. Bytes sent: ' . $bytes_sent); if ($bytes_sent !== $filesize) { error_log('ERROR: Incomplete file transfer for inline display!'); } else { error_log('File transfer for inline display appears complete.'); } exit; } else { error_log('File not found or not within allowed directory. Returning 403.'); wp_die( 'File not found or access denied.', 'Access Denied', array( 'response' => 403 ) ); } } else { error_log('User is not logged in. Redirecting to login with redirect URL.'); // Get the current URL to redirect back to after login $redirect_url = $_SERVER['REQUEST_URI']; $login_url = wp_login_url( $redirect_url ); // Redirect to the login page with the redirect URL wp_redirect( $login_url, 302 ); exit; } } else { error_log('Not a restricted PDF request: ' . $_SERVER['REQUEST_URI']); } }
.htaccess 文件内容
<IfModule mod_rewrite.c> RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] RewriteBase / RewriteRule ^index\.php$ - [L] RewriteRule ^en/wp-login.php /wp-login.php [QSA,L] RewriteRule ^de/wp-login.php /wp-login.php [QSA,L] # **Add your PDF restriction rules here, before the last RewriteRule** RewriteCond %{REQUEST_URI} ^/wp-content/custom-files/pdfs/s.*\.pdf$ [NC] RewriteCond %{REQUEST_FILENAME} -f RewriteRule . /index.php [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>
已尝试的排查步骤
- 反复检查插件逻辑,日志无错误;
- 确认文件路径和权限,禁用.htaccess规则可正常访问但失去登录校验;
- 尝试
ob_end_clean()清理输出缓冲区; - 切换至
fpassthru()替代readfile(),问题依旧; - 调整Nginx配置(服务器为Nginx反向代理Apache);
- 咨询AI工具未获有效帮助。
恳请帮忙排查问题原因,谢谢!
内容的提问来源于stack exchange,提问作者Salim
相关产品推荐
相关产品推荐

