为什么在Apache 2.2模块中调用ap_hook_type_checker函数时,request_rec::file

Why is request_rec::filename NULL when the ap_hook_type_checker function is called in my Apache 2.2 module?

本文关键字:函数 rec file checker request hook 模块 Apache 调用 为什么 ap      更新时间:2023-10-16

我有一个Apache模块在CentOS上正常工作,但在Ubuntu上失败。我已经将问题跟踪到这样一个事实,即请求记录包含request_rec结构中文件名的NULL值,Apache将其作为参数传递给我在模块中定义的钩子函数,以检查正在处理的文件的文件类型。

extern "C" module AP_MODULE_DECLARE_DATA  MyModule = {
STANDARD20_MODULE_STUFF,     // initializer
NULL,                        // create per-dir config
NULL,                        // merge per-dir config
NULL,                        // server config
NULL,                        // merge server config
MyCommandTable,              // command table
MyRegisterHooks              // register hooks
};

static void MyRegisterHooks(apr_pool_t *p)
{
ap_hook_child_init(MyPluginInit, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_type_checker(MyCheckAppFileType, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(MyFileHandler,NULL,NULL,APR_HOOK_MIDDLE);
}

…最后,罪魁祸首函数:

static int MyCheckAppFileType(request_rec *ap_req)
{
if(ap_req == NULL)
{
    return DECLINED; // Not reached
}
if(ap_req->filename == NULL)
{
    return DECLINED; // HERE is the problem ... Why is ap_req->filename NULL?
                     // On CentOS it is not NULL, only on Ubuntu.
}
    // ...
}

我在Ubuntu和CentOS上都使用Apache 2.2,并且我已经在两个系统上独立地从头开始构建了这个模块。

进一步信息~3个月后:我发现在CentOS上构建模块,然后将二进制文件复制到Ubuntu上,它可以工作。采用相同的代码并在Ubuntu上构建它会在运行时导致上述失败。因此,代码似乎不一定是问题所在——或者至少在两个系统上编译器处理的某些东西不同,导致CentOS构建成功,而Ubuntu构建却没有。

刚才我遇到了一个几乎相同的问题。我用的是别人写的模块。在一台测试机器上,模块正确地执行了authN和authZ。在另一台机器上,r->filename是位于验证检查钩内的NULL。你的问题在我的谷歌搜索中最先出现。

在我的情况下,我追踪到ap_set_module_config的错误使用。代码如下:

ap_set_module_config(r, &auth_my_module, attrs);

ap_set_module_config的源代码是这样说的:

/**
 * Generic accessors for other modules to set at their own module-specific
 * data
 * @param conf_vector The vector in which the modules configuration is stored.
 *        usually r->per_dir_config or s->module_config
 * @param m The module to set the data for.
 * @param val The module-specific data to set
 */
AP_DECLARE(void) ap_set_module_config(ap_conf_vector_t *cv, const module *m,
                                      void *val);

我将对ap_set_module_config的调用更改为:

ap_set_module_config(r->per_dir_config, &auth_my_module, attrs);

就像魔法一样,r->filename在验证检查钩子中不再是NULL。我是编写apache模块的新手,所以我需要找出这到底是什么意思,但我很高兴我找到了问题所在。您可以检查代码,看看如何调用ap_set_module_config

Edit:我应该补充说,我通过添加调试语句来跟踪这一点,这些语句准确地显示了request_rec结构体的filename字段何时成为NULL。对于我来说,在我定义的钩子中,它从valid变为NULL

祝你好运!