//导入nginx 基础文件
#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
// 注册你的module到commands数组中,这样nginx.conf就能识别 hello_world命令了
// 识别命令,调用函数
static ngx_command_t ngx_http_hello_world_commands[] = {
{
ngx_string("hello_world"), // The command name
NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1, hello_world 命令所在conf文件中的位置,参数数量
ngx_http_hello_world, // The command handler,解析nginx.conf,遇到hello_world时要调用的处理函数
NGX_HTTP_LOC_CONF_OFFSET,//location 配置参数的存储的位置,
offsetof(ngx_http_hello_world_loc_conf_t, output_words),//从上面位置开始,获取我们需要的配置参数
NULL//配置项读取后的处理方法
},
ngx_null_command //commands结束标志
};
// Structure for the HelloWorld context
// 模块上下问初始时,需要调用函数
// 配置项处理,对应配置在不同的框架位置
static ngx_http_module_t ngx_http_hello_world_module_ctx = {
NULL,/* preconfiguration */
NULL,/* postconfiguration */
NULL,/* create main configuration */
NULL,
NULL,/* create server configuration */
NULL,/* merge server configuration */
ngx_http_hello_world_create_loc_conf,
ngx_http_hello_world_merge_loc_conf /* merge location configuration */
};
// Structure for the HelloWorld module, the most important thing
// 定义一个模块组变量,编译后加入模块组
ngx_module_t ngx_http_hello_world_module = {
NGX_MODULE_V1,//定义了7个默认值,给ctx_index,index,spare0-3,version
&ngx_http_hello_world_module_ctx,//指向特定模块的处理接口
ngx_http_hello_world_commands,//根据commands,识别配置项
NGX_HTTP_MODULE,//模块类型
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//spare_hook0-7 8个保留的填充
};
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));
//将临时缓冲区的数据,负值ngx数据输出链结构
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;
}