nginx模块开发流程

来源:互联网 发布:淘宝开店咨询电话 编辑:程序博客网 时间:2024/06/05 17:49

* 编写模块基本结构:模块配置结构/模块配置指令/模块上下文结构/模块的定义

** 模块配置结构定义
typedef struct
{
ngx_str_t hello_string;
ngx_int_t hello_counter;
}ngx_http_hello_loc_conf_t;

** 模块配置指令定义
static ngx_command_t ngx_http_hello_commands[] = {
{
ngx_string("hello_string"),
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
ngx_http_hello_string,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_hello_loc_conf_t, hello_string),
NULL },

{
ngx_string("hello_counter"),
NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_http_hello_counter,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_hello_loc_conf_t, hello_counter),
NULL },

ngx_null_command
};

** 模块上下文结构定义
typedef struct {
ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);

void       *(*create_main_conf)(ngx_conf_t *cf);
char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);

void       *(*create_srv_conf)(ngx_conf_t *cf);
char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);

void       *(*create_loc_conf)(ngx_conf_t *cf);
char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;


** 模块的定义
ngx_module_t ngx_http_hello_module = {
    NGX_MODULE_V1,
    &ngx_http_hello_module_ctx,    /* module context */
    ngx_http_hello_commands,       /* module directives */
    NGX_HTTP_MODULE,               /* module type */
    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
};

* 实现handler的挂载函数。(按处理阶段挂载/按需挂载)
** handler模块挂载
static ngx_int_t
ngx_http_hello_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);

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

        *h = ngx_http_hello_handler;

        return NGX_OK;
}

* 编写handler处理函数。模块的功能主要通过这个函数完成。

static ngx_int_tngx_http_hello_handler(ngx_http_request_t *r){        ngx_int_t    rc;        ngx_buf_t   *b;        ngx_chain_t  out;        ngx_http_hello_loc_conf_t* my_conf;        u_char ngx_hello_string[1024] = {0};        ngx_uint_t content_length = 0;        ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, "ngx_http_hello_handler is called!");        my_conf = ngx_http_get_module_loc_conf(r, ngx_http_hello_module);        if (my_conf->hello_string.len == 0 )        {                ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, "hello_string is empty!");                return NGX_DECLINED;        }        if (my_conf->hello_counter == NGX_CONF_UNSET                || my_conf->hello_counter == 0)        {                ngx_sprintf(ngx_hello_string, "%s", my_conf->hello_string.data);        }        else        {                ngx_sprintf(ngx_hello_string, "%s Visited Times:%d", my_conf->hello_string.data,                        ++ngx_hello_visited_times);        }        ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, "hello_string:%s", ngx_hello_string);        content_length = ngx_strlen(ngx_hello_string);        /* we response to 'GET' and 'HEAD' requests only */        if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {                return NGX_HTTP_NOT_ALLOWED;        }        /* discard request body, since we don't need it here */        rc = ngx_http_discard_request_body(r);        if (rc != NGX_OK) {                return rc;        }        /* set the 'Content-type' header */        /*         *r->headers_out.content_type.len = sizeof("text/html") - 1;         *r->headers_out.content_type.data = (u_char *)"text/html";         */        ngx_str_set(&r->headers_out.content_type, "text/html");        /* send the header only, if the request type is http 'HEAD' */        if (r->method == NGX_HTTP_HEAD) {                r->headers_out.status = NGX_HTTP_OK;                r->headers_out.content_length_n = content_length;                return ngx_http_send_header(r);        }        /* allocate a buffer for your response body */        b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));        if (b == NULL) {                return NGX_HTTP_INTERNAL_SERVER_ERROR;        }        /* attach this buffer to the buffer chain */        out.buf = b;        out.next = NULL;        /* adjust the pointers of the buffer */        b->pos = ngx_hello_string;        b->last = ngx_hello_string + content_length;        b->memory = 1;    /* this buffer is in memory */        b->last_buf = 1;  /* this is the last buffer in the buffer chain */        /* set the status line */        r->headers_out.status = NGX_HTTP_OK;        r->headers_out.content_length_n = content_length;        /* send the headers of your response */        rc = ngx_http_send_header(r);        if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {                return rc;        }        /* send the buffer chain of your response */        return ngx_http_output_filter(r, &out);}

参考: http://tengine.taobao.org/book/chapter_03.html

0 0
原创粉丝点击