You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

登录后提供受限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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:40:58