'module'에 해당되는 글 1건

  1. 2007/06/11 apache 모듈 만들기 2탄 (1)

apache 모듈 만들기 2탄

정리하자.. 2007/06/11 17:22
이제 mod_irdealtest.c 파일을 작성해보자.
먼저 적당한 헤더들을 인클루드 시킨다 기본적으로 중요한 것들만 일단 넣은다음 에러가 발생하면 하나씩 추가 해보도록 하자. 기본적으로 있어야 할 것들은 다음과 같다.
#include "httpd.h"
#include "http_config.h"
#include "http_log.h"


물론 이것들중 없어도 되는 것이 있을지도 모른다...하지만 일단 넘어가자..흠흠
...
제일먼저 모듈에 대해 선언을 해주어야 한다. 다음과 같이 선언을 해주자.

module AP_MODULE_DECLARE_DATA irdealtest_module;

그리고 아래와 같이 할당 해준다 할당 해줄때 각각의 인자를 보면 첫번째 인자는 모듈의 버전,마이너 버전, 모듈의 인덱스, 모듈의 이름, 핸들, 등등의 값을 정해준다.

module AP_MODULE_DECLARE_DATA irdealtest_module =
{  
        // Only one callback function is provided.  Real
        // modules will need to declare callback functions for
        // server/directory configuration, configuration merging
        // and other tasks.
        STANDARD20_MODULE_STUFF,
        NULL,
        NULL,
        create_irdealtest_config,               /*create irdealtest config*/
        NULL,
        irdeattest_cmds,                        /*for config*/
        mod_irdealtest_register_hooks,          /* callback for registering hooks */
};


첫번째 인자인 STANDAR20_MODULE_STUFF는 다음과 같다.

/** Use this in all standard modules */
#define STANDARD20_MODULE_STUFF MODULE_MAGIC_NUMBER_MAJOR, \
        MODULE_MAGIC_NUMBER_MINOR, \
-1, \
__FILE__, \
NULL, \
NULL, \
MODULE_MAGIC_COOKIE, \
NULL      /* rewrite args spot */


 원래 module struct가 매우 여러개의 인자로 되어있는데 그중 일부를 처리해주었다고 보면 되겠다. 더 자세히 보고 싶으면 module struct 정의부분을 살펴보아라. 여튼 첫번째 인자는 그렇고
2,3,4,5 번 인자를 잘살펴봐야 하는데 2,3번째 인자는 Directory/Location 컨테이너 안에서 설정되는 지시어들을 설정해주는 것이고 3,4는 서버에서 설정되는 지시어들을 설정해주는 함수를 등록해주는 것이다. 각각 살펴보면

   2
번째      /* create per-directory config structure */
   3
번째
      /* merge per-directory config structures */
   4
번째
      /* create per-server config structure */
   5
번째
      /* merge per-server config structures */

설명에 create라고 되어있는것은 아파치의 첫번째 프로세스가 실행될때 설정하는 것이라고 보면 되고 merge라고 되어있는 것은 두번째 프로세스부터 프로세스가 생성될 때 실행된다고 보면된다. create merge의 두종류의 설정방법을 사용하는 이유는 프로세스들간에 설정값을 동기화하거나 같은 값을 가지게 하려고 사용한다고 보면된다
.

6
번째 인자는 httpd.conf파일로 부터 읽어드릴는 컨피그 값을 저장 하도록 하는 구조체 이다. irdealtest_cmds를 살펴보면

static const command_rec irdealtest_cmds[] =
{
    AP_INIT_TAKE1 ("IrdealMessage", add_irdealmessage, NULL, RSRC_CONF, "irdeal's message"),

    AP_INIT_TAKE1 ("IrdealDebug", set_debug, NULL, RSRC_CONF, "Set IRDEAL Debug rutine"),
    {NULL}
};

commane_rec라는 배열로 모듈의 지시어를 저장한다. 여기서 AP_INIT_TAKE1 는 인자를 하나만 받는 지시어를 등록(?)하는 것이다. AP_INIT_TAKE1이외에도 여러종류의 지시어를 받아들이는 define되어 있다. (http_config.h 참조)
 AP_INIT_TAKE1
을 살펴보면

첫번째 인자는 지시어 이름을 나타낸다.
두번째 인자는 지시어가 있을때 호출되는 함수를 나타낸다. 보통 지시어로 부터 받은 값을 인자로 가지고 모듈에 필요한 설정을 하는데 사용된다
.
3
번째 인자는 두번째 인자에서 등록된 함수로 필요에 의해 넘겨줄 수 있는 값이다. 보통 사용하지 않는듯
..
5
번째 인자값은 사용법에 관한 메시지, 혹은 디스크립션정도로 생각하자
.
4
번재 인자값의 의미는 아래와 같은데. 이 지시어가 어디에서 설정될지를 나타낸다. RSRC_CONF 값은 <Directory> <Location> 밖에서 사용되는 것을 알 수 있다
.

/**    
 * @defgroup ConfigDirectives Allowed locations for configuration directives.    
 * 
 * The allowed locations for a configuration directive are the union of          
 * those indicated by each set bit in the req_override mask.                     
 *
 * @{
 */                                                                              
#define OR_NONE 0             /**< *.conf is not available anywhere in this override */
#define OR_LIMIT 1       /**< *.conf inside <Directory> or <Location>            
                and .htaccess when AllowOverride Limit */                        
#define OR_OPTIONS 2         /**< *.conf anywhere
                                and .htaccess when AllowOverride Options */      
#define OR_FILEINFO 4        /**< *.conf anywhere                                
                and .htaccess when AllowOverride FileInfo */                      
#define OR_AUTHCFG 8         /**< *.conf inside <Directory> or <Location>        
                and .htaccess when AllowOverride AuthConfig */                   
#define OR_INDEXES 16        /**< *.conf anywhere
                and .htaccess when AllowOverride Indexes */                      
#define OR_UNSET 32          /**< unset a directive (in Allow) */                
#define ACCESS_CONF 64       /**< *.conf inside <Directory> or <Location> */     
#define RSRC_CONF 128        /**< *.conf outside <Directory> or <Location> */    
#define EXEC_ON_READ 256     /**< force directive to execute a command           
                which would modify the configuration (like including another     
                file, or IFModule */                                             
/** this directive can be placed anywhere */                                     
#define OR_ALL (OR_LIMIT|OR_OPTIONS|OR_FILEINFO|OR_AUTHCFG|OR_INDEXES)           
                                                                                  
/** @} */

실제 command_struct는 다음과 같다.

struct command_struct {
    /** Name of this command */
    const char *name;
    /** The function to be called when this directive is parsed */
    cmd_func func;
    /** Extra data, for functions which implement multiple commands... */
    void *cmd_data;
    /** What overrides need to be allowed to enable this command. */
    int req_override;
    /** What the command expects as arguments
     *  @defvar cmd_how args_how*/
    enum cmd_how args_how;
   
    /** 'usage' message, in case of syntax errors */
    const char *errmsg;
}; 


module AP_MODULE_DECLARE_DATA irdealtest_module 에서 마지막 인자는 mod_irdealtest가 후킹할 함수를 동록하는 함수이다. mod_irdealtest에서는 다음과 같다
.

static ap_filter_rec_t *irdealtest_out_filter_handle;
static void mod_irdealtest_register_hooks (apr_pool_t *p)
{   
   
irdealtest
_out_filter_handle = ap_register_output_filter("IRDEALFILTER", irdesltest_out_filter, NULL, AP_FTYPE_PROTOCOL + 1);
   

ap_hook_insert_filter(irdealtest_filter_insert, NULL, NULL, APR_HOOK_MIDDLE);

}


함수에서 첫번째는 irdealtest_out_filter를 등록하는 부분이고, 두번째 부분은 insert_filter를 후킹해서 irdealtest_filter_insert로 넘겨주는 것이다. ap_hook_insert_filter에 대해서는 다음에 설명하자
.

여튼 이렇게 irdealtest_out_filter라는 것을 아웃풋 필터로 등록했고, inser_filter를 후킹하는 함수에서 irdealtest_filter_insert를 등록했다
.
irdealtest_out_filter
는 다음과 같다
.

static int irdealtest_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{                          
    request_rec * r = f->r;
                           
    ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "It's in irdealtest_out_filter irdeal's message =====  %s", sconf->irdealmessage);
                         
    return ap_pass_brigade(f->next, bb);
}         



현재는 단순히 메시지만 출력한다. irdealtest_filter_insert함수에서는 irdealtest_out_filter_handle runtime에 집어넣는다
.

static void irdealtest_filter_insert(request_rec *r)
{
    ap_add_output_filter_handle(irdealtest_out_filter_handle, NULL, r, r->connection);
}
 
 
모듈의 설정을 해주어야 하는데 다음과 같은 구조체를 하나 만들자.

static struct {

    char irdealtestmessage[100];
} irdealtest_conf;

그리고 그것의 초기화는 다음과 같이 create_irdealtest_config 함수에서 해준다.

static irdealtest_conf * sconf;

static void *create_irdealtest_config(apr_pool_t *p, server_rec *s)

{

    sconf = (flvseek_conf *) apr_pcalloc(p, sizeof(flvseek_conf));

    sconf->irdealtestmessage[0] = '\0';

    return sconf;

}

컨피그 파일을 읽어서 집어넣는것은 다음과 같이.

static const char * add_irdealmessage (cmd_parms * cmd, void* cfg, const char * arg)

{

    strcpy(sconf->flvident, arg);

    return NULL;

}

위의 코드들을 잘조합하면 에러파일에 메세지를 출력하는 모듈을 만들수 있다. 내용이 좀 정리가 잘안된듯하지만 차근 차근 따라하고...다른 모듈들은 어떻게 구현했는가 하고 비교해보면서 보다보면 알수 있을 것이다. 좀 더 세부적인 내용은 다음기회에 적기로 하겠다. 그때는 생각나는데로 조금씩 조금씩 적어볼까 한다. 한번에 넘 많은 것을 적으려니까 숨이찬다..ㅡㅡ;
크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 1 : Comment 1

Trackback Address :: http://irdeal.tistory.com/trackback/33 관련글 쓰기

  1. Tracked from 엘레노아의 작업로그 2007/07/18 17:09 DELETE

    Subject: apache 모듈 만들기

    참고 사이트 : apache 모듈 만들기 1탄. 예전에 Apache로 작업할때 이 내용을 알았더라면 1/2는 덜 헤딩을 했으리라. 덧붙여서 공식 사이트의 apxs 관련 문서와 mod_so 관련 문서를 첨부한다. apxs는 Apache Extension 도구로써, Apache 서버의 확장 모듈을 컴파일하고 설치하기 위해 공식적으로 만들어진 도구이다. 이것을 이용하여 소스를 아파치의 소스트리에 집어넣어서 모듈로 만들지 않고, 독립적으로 컴파일 하여 모듈..
  1. 학주니 2007/08/06 09:48 Modify/Delete Reply

    오~ 제가 찾고자 하는 내용이에요.. ^^;
    제 블로그에 스크랩해도 되나요?

Write a comment