Nginx模块开发之hello world


此文的目的:只是为了让代码飞起来,不涉及原理


测试的nginx版本: nginx-1.10.2


先上nginx配置

events {
    worker_connections 1024;
}

http {
    server {
        listen 80;

        location / {
            mytest;
        }
    }
}

我们要实现的模块就是" mytest",请求到来时,交由此模块处理。


步骤一:

我们下载nginx源码,解压后,在源码目录创建目录ngx_http_mytest_module,

并需要在此目录中创建两个文件configngx_http_mytest_module.c,如下图



步骤二:

编辑config文件,内容如下

ngx_addon_name=ngx_http_mytest_module
HTTP_MODULES="$HTTP_MODULES ngx_http_mytest_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest_module.c"

步骤三:

编辑ngx_http_mytest_module.c文件,代码如下

#include 
#include 
#include 

//声明mytest模块的配置处理方法
static char* ngx_http_mytest(ngx_conf_t* cf, ngx_command_t* cmd, void* conf);

//
static ngx_http_module_t ngx_http_mytest_module_ctx = {
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

//定义mytest模块配置处理
static ngx_command_t ngx_http_mytest_commands[] = {
    {
        //配置项名称
        ngx_string("mytest"),

        //配置项类型,指令在location配置部分出现是合法的,且无参数
        NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,

        //出现了该配置项时,调用此方法处理配置项的参数
        ngx_http_mytest,

        //
        NGX_HTTP_LOC_CONF_OFFSET,

        //
        0,

        //
        NULL
    },

    //ngx_null_command是一个空的ngx_command宏
    ngx_null_command
};


//定义mytest模块
ngx_module_t ngx_http_mytest_module = {
    NGX_MODULE_V1,
    &ngx_http_mytest_module_ctx,
    ngx_http_mytest_commands,
    NGX_HTTP_MODULE,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NGX_MODULE_V1_PADDING
};


//请求处理方法
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t* r)
{
    if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }
    
    //丢弃请求中的包体
    ngx_int_t rc = ngx_http_discard_request_body(r);
    if (rc != NGX_OK) {
        return rc;
    }

    //设置返回的返回的Content-Type
    ngx_str_t type = ngx_string("text/plain");

    //返回的包体内容
    ngx_str_t response = ngx_string("hello world!\n");
    
    //设置返回状态码
    r->headers_out.status = NGX_HTTP_OK;

    //设置Content-Length的长度
    r->headers_out.content_length_n = response.len;

    //设置Content-Type
    r->headers_out.content_type = type;

    //发送HTTP头
    rc = ngx_http_send_header(r);
    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    //构造ngx_buf_t结构体准备发送包体
    ngx_buf_t* b;
    b = ngx_create_temp_buf(r->pool, response.len);
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    //将hello world复制到ngx_buf_t指向的内存中
    ngx_memcpy(b->pos, response.data, response.len);
    //注意,一定要设置好last指针
    b->last = b->pos + response.len;
    //声明这是最后一块缓冲区
    b->last_buf = 1;
    
    //构造发送时的ngx_chain_t结构体
    ngx_chain_t out;
    //赋值ngx_buf_t
    out.buf = b;
    //设置next为NULL
    out.next = NULL;

    /*最后一步为发送包体,发送结束后HTTP框架会调用ngx_http_finalize_request方法结束请求*/
    return ngx_http_output_filter(r, &out);

}


//定义mytest模块的配置处理方法
static char* ngx_http_mytest(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_mytest_handler;
    return NGX_CONF_OK;
}


步骤四:

编译nginx,指定安装目录和增加的模块,如果全程没报错,意味着编译成功

./configure --prefix=/usr/local/nginx-1.10.2 --add-module=./ngx_http_mytest_module
make
make install

步骤五:

测试配置,并运行,通过curl测试模块的可用性,curl -i "127.0.0.1/"

也可以通过浏览器访问。

如下图

Nginx模块开发之hello world_第1张图片


最后:此文没有讲解原理,没有讲模块是怎么添加进去的,也没有讲模块是怎么运行的,只是为了跑起来。

推荐文章:http://www.evanmiller.org/nginx-modules-guide.html

推荐书籍:《深入理解Nginx:模块开发与架构解析》


原文出自:http://blog.csdn.net/daiyudong2020/article/details/53502829



end;

你可能感兴趣的:(nginx)