아파치 모듈 프로그래밍
시작
apxs -n gc_suggest -g
위 명령을 실행하면 아파치 모듈 프로그램을 개발하기 위한 skeleton이 생성된다.
-rw-r--r-- 1 hanadmin hanmail 1022 2015-02-01 00:16 Makefile
-rw-r--r-- 1 hanadmin hanmail 2156 2015-02-01 00:16 mod_gc_suggest.c
-rw-r--r-- 1 hanadmin hanmail 172 2015-02-01 00:16 modules.mk
참고 : http://httpd.apache.org/docs/2.4/programs/apxs.html
skeleton code
/*
** mod_gc_suggest.c -- Apache sample gc_suggest module
** [Autogenerated via ``apxs -n gc_suggest -g'']
**
** To play with this sample module first compile it into a
** DSO file and install it into Apache's modules directory
** by running:
**
** $ apxs -c -i mod_gc_suggest.c
**
** Then activate it in Apache's httpd.conf file for instance
** for the URL /gc_suggest in as follows:
**
** # httpd.conf
** LoadModule gc_suggest_module modules/mod_gc_suggest.so
** <Location /gc_suggest>
** SetHandler gc_suggest
** </Location>
**
** Then after restarting Apache via
**
** $ apachectl restart
**
** you immediately can request the URL /gc_suggest and watch for the
** output of this module. This can be achieved for instance via:
**
** $ lynx -mime_header http://localhost/gc_suggest
**
** The output should be similar to the following one:
**
** HTTP/1.1 200 OK
** Date: Tue, 31 Mar 1998 14:42:22 GMT
** Server: Apache/1.3.4 (Unix)
** Connection: close
** Content-Type: text/html
**
** The sample page from mod_gc_suggest.c
*/
#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "ap_config.h"
/* The sample content handler */
static int gc_suggest_handler(request_rec *r)
{
if (strcmp(r->handler, "gc_suggest")) {
return DECLINED;
}
r->content_type = "text/html";
if (!r->header_only)
ap_rputs("The sample page from mod_gc_suggest.c\n", r);
return OK;
}
static void gc_suggest_register_hooks(apr_pool_t *p)
{
ap_hook_handler(gc_suggest_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA gc_suggest_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 */
gc_suggest_register_hooks /* register hooks */
};
httpd.conf 설정
LoadModule gc_suggest_module modules/mod_gc_suggest.so
<Location /gc_suggest>
SetHandler gc_suggest
</Location>
실행파라미터 설정
<IfModule mod_gc_suggest.c>
DB_PATH gc_suggest "/data1/jchern/suggest/suggest.tri"
</IfModule>
외부프로그램 링킹
*.c 로 돼 있는 코드를 *.slo로 mod_gc_suggest.la라인에 추가하고 아랫줄에는 *.lo로 추가
module.mk
mod_gc_suggest.la: mod_gc_suggest.slo keystroke.slo codeConvert.slo
$(SH_LINK) -rpath $(libexecdir) -module -avoid-version mod_gc_suggest.lo keystroke.lo codeConvert.lo -ldtrie -L/data1/jchern/dtrie/trunk/install/lib
DISTCLEAN_TARGETS = modules.mk
shared = mod_gc_suggest.la
외부 라이브러리 링킹이 필요한 경우
modules.mk : -lcouchbase 와 같이 추가
mod_couchbase.la: mod_couchbase.slo
$(SH_LINK) -rpath $(libexecdir) -module -avoid-version -lcouchbase mod_couchbase.lo
DISTCLEAN_TARGETS = modules.mk
shared = mod_couchbase.la
apache logging
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "message - %s ", "cannot find function");
사전초기화
static void init(apr_pool_t *p, server_rec *s)
{
gc_suggest_conf_t *conf = (gc_suggest_conf_t *) ap_get_module_config(s->module_config, &gc_suggest_module);
if(( trie = dtrie_open( trie, conf->db[0] )) == NULL )
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "cannot load successfully - %s\n", conf->db[0] );
}
static void gc_suggest_register_hooks(apr_pool_t *p)
{
ap_hook_child_init(init, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(gc_suggest_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
파라미터설정
#define MAX_URIS 8
typedef struct gc_suggest_conf{
int n_uri;
char *uri[MAX_URIS];
char *db [MAX_URIS];
} gc_suggest_conf_t;
...
static const char *set_db_path (cmd_parms * cmd, void *dummy, const char *arg1, const char *arg2 )
{
struct stat ss;
gc_suggest_conf_t *conf = (gc_suggest_conf_t *) ap_get_module_config(cmd->server->module_config, &gc_suggest_module);
if(conf->n_uri > MAX_URIS)
{
return apr_psprintf(cmd->pool, "Maximum URI is %s, and exceed", conf->n_uri);
}
if(stat(arg2, &ss))
{
return apr_psprintf(cmd->pool, "grammar suggest db [%s] is not exist.", arg2);
}
if(!S_ISREG(ss.st_mode))
{
return apr_psprintf(cmd->pool, "Path [%s] is not regular file.", arg2);
}
conf->uri[conf->n_uri] = apr_pstrdup(cmd->pool, arg1);
conf->db [conf->n_uri] = apr_pstrdup(cmd->pool, arg2);
conf->n_uri ++;
return NULL;
}
static const command_rec gc_suggest_cmds[] =
{
AP_INIT_TAKE2 ("DB_PATH", set_db_path, NULL, RSRC_CONF, "gc_suggest DB path (uri, DB)"),
{NULL},
};
static void *create_gc_suggest_config (apr_pool_t * p, server_rec *s)
{
gc_suggest_conf_t *conf = apr_pcalloc (p, sizeof (gc_suggest_conf_t));
conf->n_uri = 0;
return conf;
}
/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA gc_suggest_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
create_gc_suggest_config, /* create per-server config structures */
NULL, /* merge per-server config structures */
gc_suggest_cmds, /* table of config file commands */
gc_suggest_register_hooks /* register hooks */
};
참고 페이지
http://httpd.apache.org/docs/2.4/programs/apxs.html
http://httpd.apache.org/docs/2.4/developer/modguide.html
https://apr.apache.org/
http://blog.ilovelinux.org/2013/10/apache-http-server-24-module-guide_6.html