【问题标题】:Error while using ap_parse_form_data to retrieve POST data from apache module in C使用 ap_parse_form_data 从 C 中的 apache 模块检索 POST 数据时出错
【发布时间】:2013-01-08 12:21:56
【问题描述】:

我想使用“C”在 Apache 模块中解析来自浏览器的 POST 数据。根据 Apache API 文档,函数 ap_parse_form_data 可用于此目的。该函数在 httpd.h 中声明,我已将其包含在我的模块中:

...
#include <httpd.h>
#include <apr_tables.h>
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
...
keyValuePair* readPost(request_rec* r) {
    ...
    apr_array_header_t *pairs=NULL;
    int res;
    ...
    res = ap_parse_form_data(r, NULL, &pairs, -1, 8192);

使用 apxs2 命令成功编译程序,并且模块安装在正确的路径中。但是,当我启动 Apache 服务器时,它会抛出如下错误:

apache2:/etc/apache2/apache2.conf 的第 204 行语法错误:
/etc/apache2/mods-enabled/apache_post.load 第 1 行的语法错误:
无法将 /usr/lib/apache2/modules/mod_apache_post.so 加载到服务器中:
/usr/lib/apache2/modules/mod_apache_post.so:未定义符号:
ap_parse_form_data

undefined symbol:ap_parse_form_data

有什么技巧可以解决这个问题吗?

【问题讨论】:

  • 看起来像一个链接器错误,但我无法真正解决它。
  • 您确定您启动的 HTTPd 服务器版本与您针对 ?ap_parse_form_data() 编译模块的版本相同,已在 Apache HTTPd 2.4.x 中添加,所以看起来您可能是将模块加载到以前版本的 HTTPd、2.0.x 或 2.2.x。
  • @RemiGacogne:你能建议一些方法来解析版本 2.2.x 中的 POST 请求

标签: c apache2


【解决方案1】:

我更新了这个帖子,因为有人想要回答这个问题,它会有所帮助。

    #include "httpd.h"
    #include "http_core.h"
    #include "http_protocol.h"
    #include "http_request.h"

    #include "apr_strings.h"
    #include "apr_network_io.h"
    #include "apr_dbd.h"
    #include <apr_file_info.h>
    #include <apr_file_io.h>
    #include <apr_tables.h>
    #include "util_script.h"

    typedef struct {
    const char* key;
    const char* value;
    } keyValuePair;

    /* Define prototypes of our functions in this module */
    static void register_hooks(apr_pool_t *pool);
    static int example_handler(request_rec *r);
    keyValuePair* readPost(request_rec* r);
    /* Define our module as an entity and assign a function for registering hooks  */


    module AP_MODULE_DECLARE_DATA   example_module =
    {
    STANDARD20_MODULE_STUFF,
            NULL,            // Per-directory configuration handler
            NULL,            // Merge handler for per-directory configurations
            NULL,            // Per-server configuration handler
            NULL,            // Merge handler for per-server configurations
            NULL,            // Any directives we may have for httpd
    register_hooks   // Our hook registering function
    };


    /* register_hooks: Adds a hook to the httpd process */
    static void register_hooks(apr_pool_t *pool) 
    {

            /* Hook the request handler */
            ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
    }

    /* The handler function for our module.
            * This is where all the fun happens!
    */



    keyValuePair* readPost(request_rec* r) {
            apr_array_header_t *pairs = NULL;
            apr_off_t len;
            apr_size_t size;
            int res;
            int i = 0;
            char *buffer;
            keyValuePair* kvp;

    res = ap_parse_form_data(r, NULL, &pairs, -1, HUGE_STRING_LEN);
    if (res != OK || !pairs) return NULL; /* Return NULL if we failed or if there are is no POST data */
    kvp = apr_pcalloc(r->pool, sizeof(keyValuePair) * (pairs->nelts + 1));
    while (pairs && !apr_is_empty_array(pairs)) {
    ap_form_pair_t *pair = (ap_form_pair_t *) apr_array_pop(pairs);
    apr_brigade_length(pair->value, 1, &len);
    size = (apr_size_t) len;
    buffer = apr_palloc(r->pool, size + 1);
    apr_brigade_flatten(pair->value, buffer, &size);
    buffer[len] = 0;
    kvp[i].key = apr_pstrdup(r->pool, pair->name);
    kvp[i].value = buffer;
    i++;
    }
    return kvp;
    }

    static int example_handler(request_rec *r)
    {
    /*~~~~~~~~~~~~~~~~~~~~~~*/
    keyValuePair* formData;
    /*~~~~~~~~~~~~~~~~~~~~~~*/

            formData = readPost(r);
            if (formData) {
             int i;
            for (i = 0; &formData[i]; i++) {
            if (formData[i].key && formData[i].value) {
                    ap_rprintf(r, "%s = %s\n", formData[i].key, formData[i].value);
            } else if (formData[i].key) {
                    ap_rprintf(r, "%s\n", formData[i].key);
            } else if (formData[i].value) {
                    ap_rprintf(r, "= %s\n", formData[i].value);
            } else {
                    break;
            }
            }
    }
    return OK;
    }

所以在用一些名称(mod_example.c)保存上面的代码之后,你可以像这样使用 apxs 编译它

             apxs -i -a -c mod_example.c

然后在 apache2.conf(etc/apache2/) 文件中添加这个。

             <Location "/exampleDir">
                   SetHandler example-handler
             </Location>   

然后尝试将 post 请求发送到目录 /exampleDir。请按照本教程http://httpd.apache.org/docs/2.4/developer/modguide.html 了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多