'정리하자..'에 해당되는 글 3건

  1. 2007/06/11 apache 모듈 만들기 2탄 (1)
  2. 2007/05/19 apache 모듈 만들기 1탄. (1)
  3. 2007/04/05 아파치 config directive 종류

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


apache 모듈 만들기 1탄.

정리하자.. 2007/05/19 17:47

아파치 모듈을 자주 만드는 편이 아니어서 인지...가끔 만들때마다...어떻게 만들었었는지를 까먹게 된다..나는 내가 까먹기의 화신이 아닐까라는 생각을 가끔 할 때가 있다..ㅡㅡ; 여튼 다음에 또 까먹어도 쉽게 따라 할 수 있게 내용을 남겨보려한다.

아파치에서 모듈을 설치하는 방법은 apxs를 사용하는 것과 직접 소스트리에 집어넣는 방법이 있는데..여기서는 직접 소스트리에 집어넣는 방법에 대해서만 일단 기록하겠다.

기준이 되는 아파치 버전은 현재 최신버전인 2.2.4버전 이다. 먼저 컴파일을 하기위해서 여러 설정을 해야 하는데 그러기 위해 autoconf를 이용한다. 아파치에는 autoconf를위해 여러 함수들이 들어가있는데...그것까지 모두 다 알필요는 없다...물론 필요에 의해서 알고 싶다면..acinclude.m4 파일을 열어보거 어떤 펑션들이 정의 되어있는지 확인해볼 수 있다. 여기서는 그것에 대해 일일이 남기지 않고 간단하게 따라 할 수 있는정도만 남기겠다.

먼저 새로운 모듈을 만들려면 아파치디렉토리/modules/모듈명  디렉토리를 만든다. 쉽게 설명하기위해서 irdealtest라는 모듈을 만든다는 가정하에 설명을 하겠다. modules/irdealtest를 만들고 그안에 Makefile.in파일을 만든다. 이것은 Make파일을 만들때 사용하려는 것인데...간단하게 다음과 같이 작성해준다.

# a modules Makefile has no explicit targets -- they will be defined by
# whatever modules are enabled. just grab special.mk to deal with this.

include $(top_srcdir)/build/special.m

그리고 config.m4파일을 만들고 다음과 같은 내용을 집어 넣는다.

APACHE_MODPATH_INIT(irdealtest)
APACHE_MODULE(irdealtest, irdealtest module, , , no)
APACHE_MODPATH_FINISH

APACHE_MODPATH_INIT(irdealtest) 부분은 모듈의 패스를 설정하는 부분이고 APACHE_MODULE함수에서 첫번째 인자는 모듈의 이름 두번째 인자는 모듈에 대한 설명이고, 마지막 인자는 디폴트로 컴파일 되는 것이 아니라는 뜻이다. 마지막 인자는 다음과 같은 의미의 변수들이 올수 있다.

yes 는 디폴트로 컴파일이 된다는 것이고 사용안하려면 명시적으로 disable을 해주어야 한다.
no 는 디폴트로 컴파일 안한다는 것이고, 사용하려면 명시적으로 enable을 해주어야 한다.
most 는 디폴트로는 컴파일을 안하는데, 사용하려면 명시적으로 enable해주거나 most와 all을 했을 때도 사용하게된다.
static 은 기본적으로 static한 모듈이 된다.
"" 는 기본적으로 컴파일을 안하는데, 명시적으로 enable해주거나 all을 했을 때 사용하게된다.

이렇게 두개의 파일을 만든뒤 configure 파일을 백업해둔다. 그리고 새롭게 내가 만들 모듈을 포함하는 configure를 만들면되는데, 이때는 아파치 소스에서 제공되는 buildconf를 실행시키면 된다.

buildconf를 실행시키면 새로운 configure가 만들어지는데 이 파일을 읽고 irdealtest라는 문자열을 검색해 봐라. 그러면 새로운 configure에 내가 만든 모듈을 설정하는 부분이 들어갔는지를 알 수 있다.

오늘은 여기까지.....내용이 약간 부실해서...앞으로 조금씩 고쳐나가겠다...

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 1 : Comment 1

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

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

    Subject: apache 모듈 만들기

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

    좋은글 잘 읽었습니다. 간단한 모듈 작성과 컴파일 방법에 대한 강좌도 있었으면 좋겠습니다
    기대하겠습니다.

Write a comment


아파치 config directive 종류

정리하자.. 2007/04/05 11:23

아파치에서 사용되는 directive는 4가지 정도로 구분 할 수 있다.

첫번째는 Main Config에 속하는 Directive들이다.. 이 지시어들은 어떠한 container에도 속하지 않고 overriden된 곳을 제외 하고는 글로벌 하게 적용된다. 이 곳에 속하는 지시어는 서버 전반에 걸쳐사용되는 기본값등을 설정해주는데 좋다.

두번째는 Virtual Host에속한 것이다. <VirtualHost> container 안에서 설정한다. 각 버츄얼 호스트들이 여기에 설정한 값으로 자신의 고유 서버의 설정을 가지게 된다. main config에서 valid한 지시어는 버츄얼 호스트 설정에서도 valid하다.

세번째는 <Directory>, <Files>, <Location> 디렉토리 안에서 사용되는 설정값이다. 이곳에서 설정되는 값은 버츄얼 호스트에서 설정하는 값과 orthogonal하다. 이 값은 디렉토리별로 상속이 된다.

네번째는 htaccess에서 사용되는 지시어들이다..이것은 세번째에서 사용된 지시어들의 확장된 개념이라고 보면 된다. 이것은 유저들에게 그들만의 지시어를 설정할 수 있게 해준다.

위에 언급한 것과 같은 container안에서만 지시어가 있는것은 아니다. 모듈들이 자신이 만든 container들도 있기 때문이다. <Limit> <perl>등...하지만 이것에 대해서는 여기서 언급하지 않는다.

위에서 보면 설정은 크게 두가지 종류가 있다. Host와 관련된 것이 있고 Directory와 관련된 것이 있다. 이것이 하나는 per-server config 이고 다른하나는 per-directory config이다. 서버와 관련된 컨피그는 server_rec와 관련이 있고 directory config는 request_rec와 관련있다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Trackback 0 : Comment 0

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

Write a comment