nginx 모듈 1, hello 모듈 작성

9368 단어 nginx
최근 에 nginx 소스 코드 를 읽 고 있 습 니 다. nginx 에 대한 이 해 를 강화 하기 위해 문자 의 상황 을 통 해 이 과정 에서 배 운 것 을 기록 하고 이 를 통 해 여러분 들 이
nginx 모듈 개발 은 이 를 입구 로 하여 나중에 자신의 모듈 을 개발 할 수 있 도록 감성 적 인 인식 을 가지 고 있다.
여 기 는 기본적으로 여러분 들 이 nginx 의 사용 에 대해 어느 정도 인식 을 가지 고 있 기 때문에 저 는 nginx 가 어떻게 사용 하 는 지 에 대한 쓸데없는 말 을 하지 않 고 hello 모듈 을 쓰기 시 작 했 습 니 다.
우선 우 리 는 우리 의 hello 모듈 이 무엇 을 해 야 하 는 지 를 명 확 히 해 야 한다. 우 리 는 이러한 모듈 을 쓸 계획 이다. 이 모듈 은 location 구역 에 있 는 명령 을 제공 하고 이 명령 을 통 해 우 리 는 할 수 있다.
명령 뒤의 문 자 를 그대로 출력 합 니 다. 예 를 들 어:
location /say {
		say  hello;
	}

우 리 는 / say 를 방문 하면 hello 를 출력 하 는 글 자 를 출력 합 니 다.
nginx 모듈 의 명명 규범 에 따라 우 리 는 모듈 의 이름 을 ngx 로 지 었 다.http_say_module, 다음은 이 모듈 을 실현 합 니 다.
파일 생 성 ngxhttp_say_module. c, 이 파일 에 nginx 모듈 을 작성 하 는 데 필요 한 헤더 파일 을 도입 합 니 다.
   #include <ngx_config.h>
   #incldue <ngx_core.h>
   #inclued <ngx_http.h>

사용자 정의 구조 체
그 후에 우 리 는 설정 파일 에서 분 석 된 명령 정 보 를 저장 하기 위해 구조 체 를 만들어 야 한다. 그러면 필요 할 때 구조 체 에서 우리 가 설정 한 명령 값 을 받 을 수 있다.
 typedef struct {
	ngx_str_t		say;  //       say   
  } ngx_http_loc_conf_t;

모듈 의 명령 정보
명령 값 을 저장 하 는 구조 가 생 겼 습 니 다. 명령 을 설명 하 는 구조 가 필요 합 니 다. nginx 에서 모든 모듈 에 여러 개의 명령 이 있 고 모든 명령 은 하나의 ngx 를 사용 할 수 있 습 니 다.command_t
전체 모듈 명령 이 ngx 에 놓 여 있 음 을 나타 낸다.command_t 배열 중

  static  ngx_command_t ngx_http_say_commands[] = {
  	{
		//    
  		ngx_string("say");  

		//          location           
  		NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 

		//ngxin    ,           ngx_http_say_loc_conf_t    
                //                  
  		ngx_conf_set_str_slot, 

		//                ,        main_conf、srv_conf、loc_conf
                //    http    、  server   、  location   
                //          location  ,         loc_conf
  		NGX_HTTP_LOC_CONF_OFFSET, 
		
		//                     
  		offsetof(ngx_http_say_loc_conf_t,say),

		//        ,       ,     null
  		NULL
  	},
  	
  	ngx_null_command
  }

모듈 의 상하 문 정보
모듈 의 컨 텍스트 는 nginx 가 설정 파일 을 분석 할 때 호출 할 수 있 는 함 수 를 제공 합 니 다. 이 함수 들 은 설정 파일 을 분석 할 때 순서대로 호출 됩 니 다.
간단하게 보기 위해 서 저희 가 여기 함수 두 개 만 등 록 했 어 요.
static ngx_http_module_t ngx_http_say_module_ctx={
    NULL,               						  /*preconfiguration*/
    ngx_http_say_init, 					  /*postconfiguration*/

    NULL,              						  /*create main configuration*/
    NULL,                						  /*init main configuration*/

    NULL,                						  /*create server configuration*/
    NULL,               						  /*merge server configuration*/

                        						 
    ngx_http_say_create_loc_conf, 		  	  /*create location configuration*/
    NULL               						  /*merge location configuration*/
 };

ngx_http_say_create_loc_conf 함수 의 역할 은 사용자 정의 데이터 구 조 를 만 드 는 것 입 니 다.
nginx 는 요청 을 더욱 정확하게 처리 하기 위해 요청 처리 과정 을 11 단계 로 나 누 었 고 모든 명령 은 보통 특정한 단계 에서 실 행 됩 니 다.
모든 nginx 모듈 은 몇 단계 에 등 록 된 다음 에 각 단계 마다 모듈 의 서로 다른 명령 을 수행 합 니 다. 이 11 단계 중 하나 가 있 습 니 다.
NGX_HTTP_CONTENT_PHASE 단계, 이 단 계 는 일반적으로 콘 텐 츠 출력 을 담당 하기 때문에 ngxhttp_say_init 방법 에서 모듈 을
이 단계 까지 등록
모듈 정의
위의 정보 가 있 으 면 우 리 는 nginx 에 우리 의 모듈 을 설명 하고 nginx 에서 ngx 를 사용 해 야 합 니 다.module_t 구조 체 는 모듈 을 설명 하고 우리 의 모듈 에 대해 다음 과 같이 구체 적 으로 설명 한다.
 
ngx_module_t ngx_http_say_module = { 
    NGX_MODULE_V1,                             
    &ngx_http_say_module_ctx, 		  /*       ,          */
    ngx_http_say_commands,   		  /*       */
    NGX_HTTP_MODULE,        		  /*module type*/   //      HTTP  
    NULL,               					 /*init master*/ 
    NULL,               					 /*init module*/ 
    NULL,               					 /*init process*/
    NULL,               					 /*init thread*/ 
    NULL,               					 /*exit thread*/ 
    NULL,               					 /*exit process*/
    NULL,               					 /*exit master*/
    NGX_MODULE_V1_PADDING
 };

이 구 조 는 비교적 간단 하 다. 단지 두 곳 만 우리 자신의 것 이 고, 다른 것 은 기본적으로 모두 고정 되 어 있다.
관련 함수 작성 시작
  nginx 의 상하 문 구조 에서 우 리 는 두 개의 반전 함 수 를 등 록 했 습 니 다. 우 리 는 먼저 create 를 봅 니 다.loc 함수
  
static void *ngx_http_say_create_loc_conf(ngx_conf_t *cf){
   	 ngx_http_say_loc_conf_t *conf;
       
   	 conf  = ngx_pcalloc(cf->pool,sizeof(ngx_http_say_loc_conf_t));
    	 if (conf == NULL){
       	    return NULL;
   	 }

         return conf;
   }

 
   앞에서 말 했 듯 이 이 함 수 는 사용자 정의 구조 체 를 만 들 고 돌아 갑 니 다.
   nginx 메모리 관 리 는 ngx 를 통 해pool_t 구조 체 가 실 현 된 것 입 니 다. 만약 에 우리 가 메모 리 를 분배 해 야 한다 면 모두 이 구조 체 에서 분 배 된 것 입 니 다.
   최종 적 으로 어느 순간 에 이 구조 체 를 없 애 면 그 안에서 분 배 된 모든 메모리 가 방출 될 것 이다. 그러면 우 리 는 걱정 할 필요 가 없다.
   그 메모리 가 풀 리 지 않 았 다 고 신 청 했 습 니 다.이 구조 체 를 어떻게 조작 하 는 지 에 대해 nginx 는 일련의 방법 을 제 공 했 는데 그 중에서 ngxpcalloc
   메모 리 를 신청 합 니 다. 그래서 우 리 는 그 가 ngx 를 신청 하 는 데 사용 합 니 다.http_say_loc_conf_t 구조 에 필요 한 메모리.
  
   초기 화 방법 ngxhttp_say_init, 이 방법 에서 단 계 를 등록 하고 이 단계 에서 실행 할 함 수 를 연결 합 니 다.
 
 
 static ngx_int_t ngx_http_say_init(ngx_conf_t *cf){
   	 ngx_http_handler_pt     *h;  			//         
   	 ngx_http_core_main_conf_t   *cmcf;

   	 cmcf = ngx_http_conf_get_module_main_conf(cf,ngx_http_core_module);

   	 //     CONTENT  
   	 h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
   	 if(h == NULL){
      	  return NGX_ERROR;
   	 }

   	 *h = ngx_http_say_handler;  //         

   	 return NGX_OK;
  }

  우리 가 이 함수 에서 ngx 를http_say_handler 방법 이 NGX 에 등록 되 었 습 니 다.HTTP_CONTENT_PHASE 단계
  이 단계 까지 실행 을 요청 하면 nginx 는 제 가 등록 한 방법 을 호출 합 니 다. 그리고 우 리 는 이 방법 에서 명령 의 값 에 따라 여러 가지 일 을 할 수 있 습 니 다.
  요청 을 제대로 처리 하 는 함수 ngxhttp_say_handler
  
static ngx_int_t ngx_http_say_handler(ngx_http_request_t *r){
  	  ngx_int_t  rc;
  	  ngx_buf_t *b;       //nginx     buffer    
   	  ngx_chain_t out;   //nginx               ,  chain    buf,         chain   
	  ngx_http_say_loc_conf_t *my_conf;  //           ,       ,           

    	//   my_conf      ,    buf 
    	u_char* tmp_buf = ngx_pcalloc(r->pool, my_conf->say.len+1);
    	//           
    	my_conf = ngx_http_get_module_loc_conf(r,ngx_http_say_module);
    	//       ,        ,  nginx       index、autoindex、static   nginx             
    	if(my_conf->say.len == 0){
       		return NGX_DECLINED;
    	}

    	//        buf ,                 
    	ngx_sprintf(tmp_buf,"%s
",my_conf->say.data); ngx_uint_t content_length = ngx_strlen(tmp_buf); // , rc = ngx_http_discard_request_body(r); if(rc != NGX_OK){ return rc; } // buf b = ngx_pcalloc(r->pool,sizeof(ngx_buf_t)); if (b == NULL){ return NGX_HTTP_INTERNAL_SERVER_ERROR; } // buf b->pos = tmp_buf; b->last = tmp_buf + content_length; b->memory = 1; // buf , b->file b->last_buf = 1; // buffer buffer // buf chain out.buf = b; out.next = NULL; // r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = content_length; // , , header filter rc = ngx_http_send_header(r); if(rc == NGX_ERROR || rc > NGX_OK || r->header_only){ return rc; } // , body filter return ngx_http_output_filter(r,&out); }

nginx 에 모듈 을 등록 하고 실행 합 니 다.
  우선 우 리 는 모듈 정 보 를 설명 하기 위해 config 파일 이 필요 합 니 다. 내용 은 다음 과 같 습 니 다.
    
       //nginx 저희 모듈 이름 알려 주세요.
       ngx_addon_name=ngx_http_say_module
       //nginx 에 게 HTTP 모듈 을 추가 하 라 고 알려 주세요.
       HTTP_MODULES="$HTTP_MODULES ngx_http_say_module"
       //nginx 에 어떤 파일 을 컴 파일 하 는 지 알려 줍 니 다.
       NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_say_module.c"
  우리 의 모듈 파일 을 이러한 디 렉 터 리 구조 로 구성 합 니 다.
     
     ngx_http_say_module
|
|--------config
|
|-------ngx_http_say_module.c
  모듈 을 nginx 에 컴 파일 합 니 다.
    
       /configure   --add-module=/ngx_http_say_module
  
  설치 하고 다시 시작 한 후 설정 파일 에 다음 명령 을 설정 합 니 다.
location ~    ^/say {
say hello;
}
  
  curl 실행http://127.0.0.1/say 출력 결과 hello

좋은 웹페이지 즐겨찾기