Chinaunix首页 | 论坛 | 博客
  • 博客访问: 493488
  • 博文数量: 25
  • 博客积分: 111
  • 博客等级: 民兵
  • 技术积分: 1279
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-26 20:51
文章分类

全部博文(25)

文章存档

2014年(17)

2013年(8)

分类: C/C++

2014-04-07 10:43:23

最近在看Nginx源码,这篇blog中会给出一个简单的实例。在编写Nginx module时主要编写的是两个结构:一个是上下文结构表明编写的是什么模块(例如:ngx_http_module_t),另一个是命令模块(ngx_command_t)。

下面细致的说下这两个module,加深记忆吧:

点击(此处)折叠或打开

  1. typedef struct{
  2.   /*着两个函数分别于解析配置文件前和解析之后各自调用*/
  3.   ngx_int_t (*preconfiguration)(ngx_conf_t *cf);
  4.   Ngx_int_t (*postconfiguration)(ngx_conf_t *cf);
  5.   
  6.   /*一个函数用于存储main_srv_conf配置选项,另一个用于初始化main_srv_conf*/
  7.   void *(*create_main_conf)(ngx_conf_t *cf);
  8.   char *(*init_main_conf)(ngx_conf_t *cf, void *conf);
  9.   
  10.   /*一个函数用于存储loc_srv_conf配置选项,另一个用于合并main_srv_conf和loc_srv_conf里面的同名配置*/
  11.   void *(*create_srv_conf)(ngx_conf_t *cf);
  12.   char *(*merge_srv_conf)(ngx_conf_t* cf, void* prev, void* conf);
  13.   
  14.   /*作用同上*/
  15.   void *(*create_loc_conf)(ngx_conf_t *cf);
  16.   char *(*merge_loc_conf)(ngx_conf_t* cf, void* prev, void* conf);
  17. }ngx_http_module_t;
  18. /*
  19.     下面以最后了两项为例进行简要说明:
  20.     create_loc_conf为location{...}配置项分配内存
  21.     merge_loc_conf用于合并loc_conf和srv_conf同名配置,具体的合并方式系统给出来了一些宏,例如ngx_conf_merge_value、ngx_conf_ptr_value等
  22. */
  23. typedef struct{
  24.   ngx_str_t name;                                                  
  25.   Ngx_uint_t type;                                                 
  26.   char *(*set)(ngx_cong_t* cf, ngx_command_t* cmd, void *conf);    
  27.   ngx_uint_t conf;                                                 
  28.   ngx_uint_t offset;                                               
  29.   void *post;                                                      //一个补充字段,一般不用的,填入NULL
  30. }ngx_command_t;
  31. /*
  32.     type:表示在读到哪些模配置项{main_conf,serv_conf,loc_conf}的name配置,以及参数类型和个数。例如:NGX_HTTP_LOC_CONG|NGX_CONF_TAKE1,表示配置只能出现在 location{...},且只能携带一个参数。
  33.     conf:表示配置项是由ngx_http_module_t结构中的哪个函数(create_loc、srv、main_conf)创建的。例如下面的例子中定义了 location配置,此时就应该由ngx_http_module_t中的create_loc_conf分配结构内存。
  34.     offset:表示要读取的配置项(name),在结构中的位置。以便调用系统默认的set函数时,必须设置这个值,但自定义set函数则不必要。
  35.     set:读取到name配置项的时候,进行处理配置项的回调函数,这些回调函数一共有14个,下面给出一些并作简要说明:
  36.         ngx_conf_set_flag_slot:将“on”或者“off”转换成1或0;
  37.         ngx_conf_set_str_slot:将字符串保存为ngx_str_t;
  38.         ngx_conf_set_num_slot:解析一个数字并保存为ngx_int_t;
  39.    见下面的具体实例
  40. */
  41. //下面给出一个简单的实例,并进行注释说明。

  42. typedef struct{
  43.     ngx_str_t test;
  44. }ngx_http_hello_loc_conf_t;

  45. /*用于读取loc_src_conf中的配置信息,并存储在ngx_http_hello_loc_conf_t中*/
  46. static char *ngx_http_hello(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

  47. static ngx_command_t ngx_http_hello_commands[] = {
  48.     { ngx_string("hello"),                                          
  49.       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
  50.       ngx_http_hello,                                                
  51.       0,
  52.       0,
  53.       NULL },
  54.       ngx_string("test"),
  55.       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
  56.       ngx_conf_set_str_slot,
  57.       NGX_HTTP_LOC_CONF_OFFSET,
  58.       offsetof(ngx_http_hello_loc_conf_t, test),
  59.       NULL},
  60.     ngx_null_command                                                 //表示数组结束
  61. };
  62. /*此函数用于读取到配置问时,执行的回调函数*/
  63. static void *ngx_http_hello_create_loc_conf(ngx_conf_t *cf);
  64.  static ngx_http_module_t ngx_http_hello_module_ctx = {
  65.     NULL,                                                             
  66.     NULL,                                                            
  67.     NULL,                                                             
  68.     NULL,                                                             
  69.     NULL,                                                            
  70.     NULL,                                                            
  71.     ngx_http_hello_create_loc_conf,                                   // 用于为ngx_http_hello_loc_conf_t结构分配内存
  72.     NULL                                                              
  73. };
  74. ngx_module_t ngx_http_hello_module = {
  75.     NGX_MODULE_V1,
  76.     &ngx_http_hello_module_ctx,                                       // 模块上下文
  77.     ngx_http_hello_commands,                                          // 模块指令集
  78.     NGX_HTTP_MODULE,                                                   
  79.     NULL,                                                             
  80.     NULL,                                                            
  81.     NULL,                                                             
  82.     NULL,                                                             
  83.     NULL,                                                            
  84.     NULL,                                                           
  85.     NULL,                                                             
  86.     NGX_MODULE_V1_PADDING
  87. };
  88. static u_char ngx_hello_string[] = "hello world";
  89. /*
  90.     处理函数,主要是当处理到NGX_HTTP_CONTENT_PHASE阶段时,进行的回调处理,比如返回用户的请求信息时。
  91. */
  92. static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r){
  93.     ngx_int_t rc;
  94.     ngx_buf_t *b;
  95.     ngx_chain_t out;
  96.     ngx_http_hello_loc_conf_t *hrcf;
  97.     /* 设置响应内容格式,这里为text/html */
  98.     r->headers_out.content_type_len = sizeof("text/html") - 1;
  99.     r->headers_out.content_type.len = sizeof("text/html") - 1;
  100.     r->headers_out.content_type.data = (u_char *) "text/html";
  101.     b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
  102.     if (b == NULL) {
  103.         return NGX_HTTP_INTERNAL_SERVER_ERROR;
  104. }
  105.     out.buf = b;
  106.     out.next = NULL;
  107.     b->pos = ngx_hello_string;
  108.     b->last = ngx_hello_string + sizeof(ngx_hello_string) - 1;
  109.     b->memory = 1;
  110.     b->last_buf = 1;
  111.     r->headers_out.status = NGX_HTTP_OK;
  112.   r->headers_out.content_length_n = sizeof(ngx_hello_string) - 1;
  113.   //应答HTTP的header信息
  114.     rc = ngx_http_send_header(r);
  115.     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
  116.    return rc;
  117.   }
  118.     /* 演示如何获取配置选项的值 */
  119.     hrcf = ngx_http_get_module_loc_conf(r, ngx_http_hello_module);
  120.     printf("test: %s\n", hrcf->test.data);
  121.     return ngx_http_output_filter(r, &out);//应答HTTP CONTENT信息
  122. }
  123. /* 读取局部配置信息 */
  124. static void *ngx_http_hello_create_loc_conf(ngx_conf_t *cf){
  125.     ngx_http_hello_loc_conf_t *hlcf;
  126.     hlcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_hello_loc_conf_t));
  127.     if (hlcf == NULL) {
  128.         return NULL;
  129.     }
  130.     return hlcf;
  131. }
  132. static char *ngx_http_hello(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){
  133.     ngx_http_core_loc_conf_t *clcf;
  134.     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  135.     clcf->handler = ngx_http_hello_handler; /* 设置读取到NGX_HTTP_CONTENT_PHASE    的回调函数 */
  136.     return NGX_CONF_OK;
  137. }
本文出处:http://blog.chinaunix.net/uid-28311809-id-4198428.html


阅读(2977) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~