読者です 読者をやめる 読者になる 読者になる

QUERY_STRING をパースするApacheモジュール

Apache C

CentOS5.1 上の Apache2.2のサンプル。

  • mod_mygetparse の作成
# apxs -g -n mygetparse
# cd mygetparse
# make
# make install

/etc/httpd/conf.d/mod_mygetparse.conf を以下のように作成

LoadModule mygetparse_module modules/mod_mygetparse.so

<Location /mygetparse>
    SetHandler mygetparse
</Location>
  • mod_mygetparse.c
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "apr_tables.h"
#include "ap_config.h"

static apr_table_t *get_param_by_urlencoded(apr_pool_t *p, char *query_string){
	apr_table_t *param=NULL;
	char *token;
	char *args = query_string;

	param = apr_table_make(p, 16);
	while(*args && (token = ap_getword(p, &args, '&'))){
		char *key, *val;
		key = ap_getword(p, &token, '=');
		val = ap_getword(p, &token, '=');
		ap_unescape_url(key);
		ap_unescape_url(val);
		apr_table_set(param, key, val);
	}
	return param;
}

/* The sample content handler */
static int mygetparse_handler(request_rec *r)
{
	if (strcmp(r->handler, "mygetparse")) {
		return DECLINED;
	}
	r->content_type = "text/html";
	
	ap_rputs("<html><body>\n", r);

	apr_table_t *param = get_param_by_urlencoded(r->pool, r->args);
	if(param==NULL){
		ap_rputs("NO QUERY_STRING", r);
	}
	else {
		ap_rprintf(r, "Name: %s<br/>", apr_table_get(param, "name"));
		ap_rprintf(r, "Age: %s<br/>", apr_table_get(param, "age"));
	}

	ap_rputs("</body></html>", r);
	return OK;
}

static void mygetparse_register_hooks(apr_pool_t *p)
{
	ap_hook_handler(mygetparse_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA mygetparse_module = {
	STANDARD20_MODULE_STUFF, 
	NULL,                  /* create per-dir    config structures */
	NULL,                  /* merge  per-dir    config structures */
	NULL,                  /* create per-server config structures */
	NULL,                  /* merge  per-server config structures */
	NULL,                  /* table of config file commands       */
	mygetparse_register_hooks  /* register hooks                  */
};
  • libapreq2 を使ったバージョン
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include <apreq2/apreq_param.h>
#include "apr_tables.h"
#include "ap_config.h"

//static int mygetparse_handler(request_rec *r)
int mygetparse_handler(request_rec *r)
{
    if (strcmp(r->handler, "myupload")) {
        return DECLINED;
    }
    r->content_type = "text/html";      
    
    apr_table_t *param=apr_table_make(r->pool, 16);
    
    apreq_parse_query_string(r->pool, param, (r->args)?r->args:"");

    ap_rputs(apreq_params_as_string(r->pool, param, "key", APREQ_JOIN_AS_IS), r);
    ap_rputs(apreq_params_as_string(r->pool, param, "key", APREQ_JOIN_ENCODE), r);
    ap_rputs(apreq_params_as_string(r->pool, param, "key", APREQ_JOIN_DECODE), r);
    ap_rputs(apreq_params_as_string(r->pool, param, "key", APREQ_JOIN_QUOTE), r);

    //(apr_array_header_t *) apreq_params_as_array(apr_pool_t *p,const apr_table_t *t,const char *key);

    if (!r->header_only)
        ap_rputs("mygetparse", r);
    return OK;
}

static void mygetparse_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(mygetparse_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

module AP_MODULE_DECLARE_DATA mygetparse_module = {
    STANDARD20_MODULE_STUFF, 
    NULL,                  /* create per-dir    config structures */
    NULL,                  /* merge  per-dir    config structures */
    NULL,                  /* create per-server config structures */
    NULL,                  /* merge  per-server config structures */
    NULL,                  /* table of config file commands       */
    mygetparse_register_hooks  /* register hooks                      */
};