也来学习写一下nginx的自定义模块

| 2012年2月19日

这几天在家里,学习了一下nginx的一些东西,首先当然就是用编译安装来配置简单的服务了。上一篇也算是学习配置的一点心得,在网上看了nginx的可扩展性后,我也简单研究了一下nginx的自定义模块。并且在晚上代码的参考下,也编译了两个模块来玩了一下,这里先展示一下一个最简单的模块。

这个模块主要是这样一个目的,在输入一个指定的url后,会返回自定义的内容:

url:http://127.0.0.1/hello

输出内容为我自定义的字符串,比如:“I try to fuck Nginx!!!”

这里介绍以下步骤:

第一步:

建立任意一个目录,比如:ngx_hello

第二步:

在这个文件夹中建立一个config文件,内容如下:

ngx_addon_name=ngx_xtest  #这里指定模块名称 HTTP_MODULES="$HTTP_MODULES ngx_xtest" #指定编译后文件名称 NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_xtest.c"  #指定源文件,这里我只有一个文件多个文件就要全部写上去

CORE_LIBS="$CORE_LIBS " #这里指定编译的nginx库,这变量是由编译nginx的时候Makefile传递过来的,上面的几个变量也是一样

第三步:

建立ngx_xtest.c文件,内容如下,也写了简单的注释 //引用nginx头文件,我们这个测试文件就一个没有其它的测试文件,所以也没有引用其它的头文件。

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>

char* ngx_xtest_setup(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

u_char ngx_xtest_string[] = "I try to FUCK Nginx !!!";
//这个事命令组,这里我们可以写多个命令,以数组的形式存在
static ngx_command_t ngx_xtest_commands[] =
{
{   ngx_string("hello"),//这是命令字段,其实也就是我们在url中访问时写的目标文件
NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
ngx_xtest_setup,      //这个函数来响应hello这个命令,hello命令触发这个函数
0,
0,
NULL
},
ngx_null_command
};//这个数组必须以ngx_null_command结尾

//这个是用来处理配置文件的,这里我们使用系统的默认配置文件处理
static ngx_http_module_t ngx_xtest_ctx = {
NULL,                          /* preconfiguration */
NULL,                          /* postconfiguration */
NULL,                          /* create main configuration */
NULL,                          /* init main configuration */
NULL,                          /* create server configuration */
NULL,                          /* merge server configuration */
NULL,                          /* create location configuration */
NULL                           /* merge location configuration */
};

//这个才是真正的模块。
ngx_module_t ngx_xtest = {
NGX_MODULE_V1,
&amp;ngx_xtest_ctx,       /* module context */
ngx_xtest_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
};//实例化模块对象

//hello命令的真正处理函数,参数是ngx_http_request_t即一个请求
//此函数实现的也是基本处理流程
static ngx_int_t ngx_xtest_handler(ngx_http_request_t *r){
ngx_int_t    rc;
ngx_buf_t   *b;
ngx_chain_t  out;

//填充HTTP头
/* 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";

//分配输出内存空间
/* allocate a buffer */
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
if (b == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
//输出缓存附加到输出链表上
/* attach buffer to the buffer chain */
out.buf = b;
out.next = NULL;

//填写输出缓存内容
/* adjust the pointers of the buffer */
b->pos = ngx_xtest_string;  /* the begin offset of the buffer */
b->last = ngx_xtest_string + sizeof(ngx_xtest_string) - 1; /* the end offset of the buffer */
b->memory = 1;    /* this buffer is in memory */
b->last_buf = 1/* this is the last buffer in the buffer chain */

/* 设置http返回码 */
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.content_length_n = sizeof(ngx_xtest_string) - 1;

//发送HTTP报头
/* 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, &amp;out);
}

//实现hello命令的初始化函数,此函数指定命令的真正处理函数为ngx_xtest_handler
char* ngx_xtest_setup(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_xtest_handler; /* handler to process the 'hello' directive */

return NGX_CONF_OK;
}

第四步:编译安转

在编译时需要加入–add-module=/path

$./configure --prefix=/usr/local/nginx --add-module=/data/babycode/nginx/ngx_xmodule/ --with-debug

$make

#make install

第五步:修改配置 配置文件—nginx.conf

location /hello{

hello;

}

第六步:运行测试

#/usr/local/nginx/sbin/nginx

测试

在浏览器中输入:http://127.0.0.1/hello

浏览器中会出现"I try to FUCK Nginx !!!",则表示运行成功拉。。。

OK! 今天就先学习到这里,打完收工,睡觉拉。。。

看完本文有收获?请分享给更多人

关注「黑光技术」,关注大数据+微服务