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

apacheモジュール作成のまとめ

Apache

かなり自分用。

# apxs -g -n hello   <- これで雛形ができる。
# cd hello
# make
# make install

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

LoadModule hello_module modules/mod_hello.so

<Location /hello>
    SetHandler hello
</Location>

apache 再起動&確認

# apachectl restart
# curl http://localhost/hello
The sample page from mod_hello.c   <-こんな感じで表示されればOK

通常のプログラムと異なりApacheがリソースの管理をしてくれる。

リソースプールの種類
Serverプール それぞれのApacheプロセス起動時に生成され、終了時に破棄される
Connectionプール クライアントがApacheに接続したときに生成され、切断したときに破棄される
Requestプール クライアントからのリクエスト毎に生成され、レスポンス後に破棄される
Subプール 任意のプールから作成し、破棄できる

ファイルハンドルはプログラマが明示的にクローズできるが、メモリの開放はApacheが行うのでプログラマが行うことはできない。

  • Apache1.3用 の関数と、Apache2.0用の関数の対応表

MODULE.JP - Apacheモジュールプログラミングガイド から自分用に転載。

AP13                       AP20
=====================================================
ap_array_pstrcat           apr_array_pstrcat
ap_construct_url           ap_construct_url
ap_copy_array              apr_array_copy
ap_document_root           ap_document_root
ap_escape_html             ap_escape_html
ap_escape_shell_cmd        ap_escape_shell_cmd
ap_escape_uri              ap_escape_uri
ap_get_basic_auth_pw       ap_get_basic_auth_pw
ap_get_client_block        ap_get_client_block
ap_get_module_config       ap_get_module_config
ap_get_server_name         ap_get_server_name
ap_get_server_port         ap_get_server_port
ap_get_server_version      ap_get_server_version
ap_getword                 ap_getword
ap_getword_conf            ap_getword_conf
ap_getword_conf_nc         ap_getword_nc
ap_getword_white           ap_getword_white
ap_getword_white_nc        ap_getword_nc
ap_gm_timestr_822          apr_rfc822_date
ap_hard_timeout             
ap_http_method             ap_http_method
ap_internal_redirect       ap_internal_redirect
ap_kill_timeout            
ap_log_error               ap_log_error
ap_log_printf              
ap_log_rerror              ap_log_rerror
ap_make_array              apr_array_make
ap_make_full_path          ap_make_full_path
ap_make_table              apr_table_make
ap_md5                     ap_md5
ap_meets_conditions        ap_meets_conditions
ap_note_basic_auth_failure ap_note_basic_auth_failure
ap_note_cleanups_for_fd     
ap_note_cleanups_for_file  
ap_note_cleanups_for_h     
ap_os_dso_error            apr_dso_error
ap_os_dso_load             apr_dso_load
ap_os_dso_sym              apr_dso_sym
ap_os_dso_unload           apr_dso_unload
ap_palloc                  apr_palloc
ap_parseHTTPdate           apr_date_parse_http
ap_pbase64decode           ap_pbase64decode
ap_pbase64encode           ap_pbase64encode
ap_pcalloc                 apr_pcalloc
ap_pclosedir               apr_dir_close
ap_pclosef                 apr_file_close
ap_pfclose                 apr_file_close
ap_pfdopen                 
ap_pfopen                  apr_file_open
ap_popendir                apr_dir_open
ap_popenf                  apr_file_open
ap_pregcomp                ap_pregcomp
ap_pregsub                 ap_pregsub
ap_psignature              ap_psignature
ap_psprintf                apr_psprintf
ap_pstrcat                 apr_pstrcat
ap_pstrdup                 apr_pstrdup
ap_pstrndup                apr_pstrndup
ap_push_array              apr_array_push
ap_pvsprintf               
ap_regerror                ap_regerror
ap_regexec                 ap_regexec
ap_regfree                 ap_regfree
ap_requires                ap_requires
ap_reset_timeout           
ap_rprintf                 ap_rprintf
ap_rputc                   ap_rputc
ap_rputs                   ap_rputs
ap_send_fd                 ap_send_fd
ap_send_http_header        
ap_server_root_relative    ap_server_root_relative
ap_set_content_length      ap_set_content_length
ap_set_etag                ap_set_etag
ap_set_file_slot           ap_set_file_slot
ap_set_last_modified       ap_set_last_modified
ap_set_string_slot         ap_set_string_slot
ap_set_string_slot_lower   ap_set_string_slot_lower
ap_setup_client_block      
ap_should_client_block     
ap_table_add               apr_table_add
ap_table_do                apr_table_do
ap_table_elts              apr_table_elts
ap_table_get               apr_table_get
ap_table_merge             apr_table_merge
ap_table_set               apr_table_set
ap_table_unset             apr_table_unset
ap_unescape_url            ap_unescape_url
ap_update_mtime            ap_update_mtime
-----------------------------------------------------
array_header               apr_array_header_t
cmd_parms                  cmd_parms
command_rec                command_rec
module                     module
regex_t                    regex_t
regmatch_t                 regmatch_t
request_rec                request_rec
server_rec                 server_rec
table                      apr_table_t
table_entry                apr_table_entry_t
uri_components             apr_uri_t
pool                       apr_pool_t
  • プログラム例: /etc/services を送信する mod_sendfile Apache2.2版

小山浩之さんのApacheモジュール プログラミングガイドに載っているApache1.3のサンプルプログラムをApache2.2に移植してみた。

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include "httpd.h"
#include "http_config.h"
#include "http_protocol.h"
#include "http_log.h"
#include "ap_config.h"
#include "apr_file_info.h"

const char ETC_SERVICES[] = "/etc/services";

/* The sample content handler */
static int sendfile_handler(request_rec *r)
{
    if (strcmp(r->handler, "sendfile")) {
        return DECLINED;
    }
    
    //APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **newf, /* file pointer */
    //                                    const char *fname, /* file name */
    //                                    apr_int32_t flag, /* see apr_file_io.h  ex. APR_FOPEN_READ */
    //                                    apr_fileperms_t perm, /* see apr_file_info.h  ex. APR_FPROT_UREAD */
    //                                    apr_pool_t *pool /*   */ );
    apr_file_t *fp;
    apr_file_open(&fp, ETC_SERVICES, APR_FOPEN_READ, APR_FPROT_UREAD|APR_FPROT_UWRITE, r->pool);
    
    if(fp == NULL){
        ap_log_rerror(APLOG_MARK, APLOG_ERR, r->status, r, "This is a test: %s.\n", ETC_SERVICES);
        return HTTP_FORBIDDEN;
    }

    r->content_type = "text/html";
    apr_off_t off = 0;
    struct stat buf;
    stat(ETC_SERVICES, &buf);
    apr_size_t sent;
    ap_send_fd(fp, r, off, (apr_size_t)buf.st_size, &sent );
    
    return OK;
}

static void sendfile_register_hooks(apr_pool_t *p)
{
    ap_hook_handler(sendfile_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA sendfile_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       */
    sendfile_register_hooks  /* register hooks                      */
};