Nginx · 모듈 개발 편 해부 (1) 당신 의 Hello World 모듈 을 달 려 라!

10709 단어 nginx
Nginx · 모듈 개발 편 해부 (1) 당신 의 Hello World 모듈 을 달 려 라!
저자: 유 대 · Poechant (종 초) 메 일 박스: zhongchao. ustc \ # gmail. com (\ # - > @) 블 로그: Blog.CSDN.net/Poechant 날짜: June 2nd, 2012 1. Nginx 모듈 개발 을 배 우려 면 어떤 준비 가 필요 합 니까?
필요 한 예비 지식 이 많 지 않 습 니 다. 다음 과 같은 몇 가지 가 있 습 니 다.
C 언어의 프로 그래 밍 경험 이 있 습 니 다.
Nginx 가 무엇 을 하 는 지 알 고 Nginx 의 프로필 을 작성 하거나 고 친 경험 이 있 습 니 다.
OK, 이 두 가지 면 충분 합 니 다.)
자, 그럼 시작 합 시다 ~
2 우리 Hello World 의 목 표 는 무엇 입 니까?
우리 의 목 표 는 브 라 우 저 에 입력 http://localhost/hello_world 할 때 표시 하 는 것 입 니 다.
hello world

물론 좀 더 사용자 정의 할 수 있 도록 hello world 뒤에 문자열 을 표시 하려 고 합 니 다. 예 를 들 어:
hello world, Poechant

그럼 우리 프로필 은 어떻게 보 입 니까?
http {
    include mime.types;
    default_type application/octet-stream;
    server {
        listen 80;
        server_name localhost;
        location / {
            root html;
            index index.php index.html index.htm;
        }
        location /hello_world {
            hello_world Poechant;
        }
    }
}

네, 간단 하 죠? 유일한 특별한 부분 은:
location /hello_world {
    hello_world Poechant;
}

착공
3.1 디 렉 터 리 구조
우선 우리 의 파일 과 디 렉 터 리 구 조 를 명 확 히 해 야 합 니 다.
ngx_http_hello_world_module
|_____________ngx_http_hello_world_module.c
|_____________config

이 중 ngx_http_hello_world_module.c 은 모듈 의 C 소스 파일 이 고 config 은 모듈 의 설정 파일 이다.
3.2 ngx_http_hello_world_module.c
구조 체 정의:
typedef struct {
    ngx_str_t output_words;
} ngx_http_hello_world_loc_conf_t;

세 개의 변 수 를 정의 합 니 다:
// Structure for the HelloWorld command
static ngx_command_t ngx_http_hello_world_commands[] = {
    {
        ngx_string("hello_world"), // The command name
        NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
        ngx_http_hello_world, // The command handler
        NGX_HTTP_LOC_CONF_OFFSET,
        offsetof(ngx_http_hello_world_loc_conf_t, output_words),
        NULL
    },
    ngx_null_command
};

// Structure for the HelloWorld context
static ngx_http_module_t ngx_http_hello_world_module_ctx = {
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    ngx_http_hello_world_create_loc_conf,
    ngx_http_hello_world_merge_loc_conf
};

// Structure for the HelloWorld module, the most important thing
ngx_module_t ngx_http_hello_world_module = {
    NGX_MODULE_V1,
    &ngx_http_hello_world_module_ctx,
    ngx_http_hello_world_commands,
    NGX_HTTP_MODULE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NGX_MODULE_V1_PADDING
};

세 함수 정의:
static char* ngx_http_hello_world(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);
static void* ngx_http_hello_world_create_loc_conf(ngx_conf_t* cf)
static char* ngx_http_hello_world_merge_loc_conf(ngx_conf_t* cf, void* parent, void* child)

전체 프로그램 은 다음 과 같 습 니 다.
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

typedef struct {
    ngx_str_t output_words;
} ngx_http_hello_world_loc_conf_t;

// To process HelloWorld command arguments
static char* ngx_http_hello_world(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);

// Allocate memory for HelloWorld command
static void* ngx_http_hello_world_create_loc_conf(ngx_conf_t* cf);

// Copy HelloWorld argument to another place
static char* ngx_http_hello_world_merge_loc_conf(ngx_conf_t* cf, void* parent, void* child);

// Structure for the HelloWorld command
static ngx_command_t ngx_http_hello_world_commands[] = {
    {
        ngx_string("hello_world"), // The command name
        NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
        ngx_http_hello_world, // The command handler
        NGX_HTTP_LOC_CONF_OFFSET,
        offsetof(ngx_http_hello_world_loc_conf_t, output_words),
        NULL
    },
    ngx_null_command
};

// Structure for the HelloWorld context
static ngx_http_module_t ngx_http_hello_world_module_ctx = {
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    ngx_http_hello_world_create_loc_conf,
    ngx_http_hello_world_merge_loc_conf
};

// Structure for the HelloWorld module, the most important thing
ngx_module_t ngx_http_hello_world_module = {
    NGX_MODULE_V1,
    &ngx_http_hello_world_module_ctx,
    ngx_http_hello_world_commands,
    NGX_HTTP_MODULE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NGX_MODULE_V1_PADDING
};

static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t* r) {
    ngx_int_t rc;
    ngx_buf_t* b;
    ngx_chain_t out[2];

    ngx_http_hello_world_loc_conf_t* hlcf;
    hlcf = ngx_http_get_module_loc_conf(r, ngx_http_hello_world_module);

    r->headers_out.content_type.len = sizeof("text/plain") - 1;
    r->headers_out.content_type.data = (u_char*)"text/plain";

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));

    out[0].buf = b;
    out[0].next = &out[1];

    b->pos = (u_char*)"hello_world, ";
    b->last = b->pos + sizeof("hello_world, ") - 1;
    b->memory = 1;

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));

    out[1].buf = b;
    out[1].next = NULL;

    b->pos = hlcf->output_words.data;
    b->last = hlcf->output_words.data + (hlcf->output_words.len);
    b->memory = 1;
    b->last_buf = 1;

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = hlcf->output_words.len + sizeof("hello_world, ") - 1;
    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    return ngx_http_output_filter(r, &out[0]);
}

static void* ngx_http_hello_world_create_loc_conf(ngx_conf_t* cf) {
    ngx_http_hello_world_loc_conf_t* conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_hello_world_loc_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }
    conf->output_words.len = 0;
    conf->output_words.data = NULL;

    return conf;
}

static char* ngx_http_hello_world_merge_loc_conf(ngx_conf_t* cf, void* parent, void* child) {
    ngx_http_hello_world_loc_conf_t* prev = parent;
    ngx_http_hello_world_loc_conf_t* conf = child;
    ngx_conf_merge_str_value(conf->output_words, prev->output_words, "Nginx");
    return NGX_CONF_OK;
}

static char* ngx_http_hello_world(ngx_conf_t* cf, ngx_command_t* cmd, void* conf) {
    ngx_http_core_loc_conf_t* clcf;
    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    clcf->handler = ngx_http_hello_world_handler;
    ngx_conf_set_str_slot(cf, cmd, conf);
    return NGX_CONF_OK;
}

3.3 config
ngx_addon_name=ngx_http_hello_world_module
HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c"

3.4 프로필 작성
처음에는 이미 보 여 줬 는데, 바로 그것 이 었 다.
3.5 당신 의 모듈 을 컴 파일 합 니 다.
$ ./configure --add-module=/your/module/path/ngx_http_hello_world_module
make

잘못된 힌트 가 없다 면 축하합니다. 모듈 컴 파일 이 통과 되 었 습 니 다!
그리고 Nginx 를 실행 합 니 다.잘못된 알림 이 없 으 면 다시 한 번 축하합니다. 모듈 이 정상적으로 불 러 와 서 실행 되 었 습 니 다!
3.6 당신 의 모듈 테스트
http://localhost/hello_world

보 실 수 있 을 겁 니 다.
hello_world, Poechant

이 간단 한 모듈 의 상세 한 설명 은 이 시리즈 박문 의 두 번 째, 세 번 째, 네 편 에 있다.
4. 아마 나 는 '비 코드' 라 고 말 해 야 할 것 같다.
일반적으로 입문 해서 어떤 일 을 할 때 우 리 는 쓸데없는 말 을 듣 고 싶 지 않 으 니 빨리 일 을 시작 하 기 를 바란다. 그렇지 않 으 면 매우 공허 하 다 고 느 낄 것 이다.이것 도 내 가 처음부터 예 를 들 어 코드 를 제시 한 이유 이다.하지만 '빈말' 을 알 아야 이해 에 도움 이 된다.
Nginx 가 요청 을 처리 하 는 과정 은 요청 을 받 은 후 설정 파일 에 기 술 된 해당 location 으로 위치 한 다음 handler 에서 response 를 생 성하 고 filter 에서 처리 합 니 다.그래서 모듈 개발 은 handler 모듈 개발 일 수도 있 고 filter 모듈 개발 일 수도 있 습 니 다 (물론 다른 유형의 모듈 도 있 습 니 다).
5 참고 사항 추천
Emiller’s Guide to Nginx Module Development
Emiller’s Advanced Topics in Nginx Module Development
블 로그 가든 - T2 서 균 체 - Nginx 모듈 개발 입문
crk_월 드 블 로그
Ngx Deve Kit
Emiller 's Guide To Nginx Module 중국어 버 전 개발
Nginx & OpenResty
CodingLabs - Nginx 모듈 개발 입문
-
유 대 에서 온 CSDN 블 로그: Blog.CSDN.net/Poechant
-

좋은 웹페이지 즐겨찾기