从apache模块读取POST参数

时间:2015-07-06 11:50:01

标签: c apache http-post apache-modules

我正在尝试从apache c模块中读取POST参数。

这是我正在使用的代码:

/* Include the required headers from httpd */
#include "httpd.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_request.h"
#include "http_config.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"



/* Define prototypes of our functions in this module */
typedef struct {
    const char *key;
    const char *value;
} keyValuePair;

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!
 */

static int example_handler(request_rec *r)
{
    /* First off, we need to check if this is a call for the "example" handler.
     * If it is, we accept it and do our things, it not, we simply return DECLINED,
     * and Apache will try somewhere else.
     */
    if (!r->handler || strcmp(r->handler, "example-handler")) return (DECLINED);

    // The first thing we will do is write a simple "Hello, world!" back to the client.
    ap_rputs("Hello, world!<br/>", r);
    return OK;
}

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;
        ap_rputs(kvp[i].key,r);
        ap_rputs(kvp[i].value,r);
        i++;
    }
    return kvp;
}

我已经从apache网站复制了阅读帖子功能: https://httpd.apache.org/docs/2.4/developer/modguide.html#snippets

尝试编译模块时出现以下错误:

  

mod_example.c:82:9:错误:使用未声明的标识符   'ap_form_pair_t'           ap_form_pair_t * pair =(ap_form_pair_t *)apr_array_pop(pairs);

apxs无法识别ap_form_pair_t。我错过了任何头文件吗?

你能帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

ap_form_pair_t附带apache版本2.4,所以我认为你使用较低版本。

此函数将所有发布数据写入缓冲区,它可以帮助您:

int util_read(request_rec *r, char **rbuf, size_t &length){

int rc;
length = 0;
if((rc = ap_setup_client_block(r, REQUEST_CHUNKED_ERROR)) != OK){

    return rc;

}

if(ap_should_client_block(r)){
    char argsbuffer[HUGE_STRING_LEN];
    int rsize, len_read, rpos=0;
    length = r->remaining;
    *rbuf = (char*)apr_pcalloc(r->pool, length + 1);


    while((len_read = ap_get_client_block(r, argsbuffer, sizeof(argsbuffer))) > 0){
        if((rpos + len_read) > length){
            rsize = length - rpos;
        } else {
            rsize = len_read;
        }
        memcpy((char*)*rbuf + rpos, argsbuffer, rsize);
        rpos += rsize;
    }

}
return rc;
}