Nginx学习之二-配置项解析及编程实现

在开发功能灵活的Nginx模块时,需要从配置文件中获取特定的信息。不过,我们并不需要再编写一套读取配置的系统,Nginx已经为用户提供了强大的配置项解析机制,同时还支持“-s reload”命令,可以在不重启服务的情况下可使配置生效。

一、Nginx配置文件简介

如果编译安装Nginx时使用默认路径,那么Nginx运行目录是/usr/local/nginx,其配置文件存放目录是/usr/local/nginx/conf/nginx.conf。其内容默认如下:

[cpp] view plaincopyprint?

  1. #user  nobody;
  2. worker_processes  1;
  3. #error_log  logs/error.log;
  4. #error_log  logs/error.log  notice;
  5. #error_log  logs/error.log  info;
  6. #pid        logs/nginx.pid;
  7. events {
  8. worker_connections  1024;
  9. }
  10. http {
  11. include       mime.types;
  12. default_type  application/octet-stream;
  13. #log_format  main  ‘$remote_addr - $remote_user [$time_local] "$request" ‘
  14. #                  ‘$status $body_bytes_sent "$http_referer" ‘
  15. #                  ‘"$http_user_agent" "$http_x_forwarded_for"‘;
  16. #access_log  logs/access.log  main;
  17. sendfile        on;
  18. #tcp_nopush     on;
  19. #keepalive_timeout  0;
  20. keepalive_timeout  65;
  21. #gzip  on;
  22. server {
  23. listen       80;
  24. server_name  localhost;
  25. #charset koi8-r;
  26. #access_log  logs/host.access.log  main;
  27. location / {
  28. root   html;
  29. index  index.html index.htm;
  30. }
  31. #error_page  404              /404.html;
  32. # redirect server error pages to the static page /50x.html
  33. #
  34. error_page   500 502 503 504  /50x.html;
  35. location = /50x.html {
  36. root   html;
  37. }
  38. # proxy the PHP scripts to Apache listening on 127.0.0.1:80
  39. #
  40. #location ~ \.php$ {
  41. #    proxy_pass   http://127.0.0.1;
  42. #}
  43. # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  44. #
  45. #location ~ \.php$ {
  46. #    root           html;
  47. #    fastcgi_pass   127.0.0.1:9000;
  48. #    fastcgi_index  index.php;
  49. #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
  50. #    include        fastcgi_params;
  51. #}
  52. # deny access to .htaccess files, if Apache‘s document root
  53. # concurs with nginx‘s one
  54. #
  55. #location ~ /\.ht {
  56. #    deny  all;
  57. #}
  58. }
  59. # another virtual host using mix of IP-, name-, and port-based configuration
  60. #
  61. #server {
  62. #    listen       8000;
  63. #    listen       somename:8080;
  64. #    server_name  somename  alias  another.alias;
  65. #    location / {
  66. #        root   html;
  67. #        index  index.html index.htm;
  68. #    }
  69. #}
  70. # HTTPS server
  71. #
  72. #server {
  73. #    listen       443;
  74. #    server_name  localhost;
  75. #    ssl                  on;
  76. #    ssl_certificate      cert.pem;
  77. #    ssl_certificate_key  cert.key;
  78. #    ssl_session_timeout  5m;
  79. #    ssl_protocols  SSLv2 SSLv3 TLSv1;
  80. #    ssl_ciphers  HIGH:!aNULL:!MD5;
  81. #    ssl_prefer_server_ciphers   on;
  82. #    location / {
  83. #        root   html;
  84. #        index  index.html index.htm;
  85. #    }
  86. #}
  87. }

块配置项

配置文件中有很多块配置项。块配置项是由一个块配置项名和一对大括号组成。例如上面代码段中的http、server、event等等。也可以在块配置项名之后后大括号之前加上参数。

块配置项可以嵌套。内层块直接继承外层块。例如上例中server块里的任意配置都是基于http块里的已有配置的。当内外层中的配置发生冲突时,究竟是以内层块还是外层块的配置为准取决于解析这个配置项的模块。

配置项的语法

最基本的配置项语法格式:

配置项名 配置项值1 配置项值2 配置项值3 ... ;

行首是配置项名,这些配置项名必须是Nginx的某一个模块想要处理的,否则Nginx会认为配置文件出现了非法的配置项名。配置项名输入结束后以空格作为分隔符。

其次是配置项值,可以是数字或字符串。可以由一个或多个配置项值。中间以空格分隔。

最后,行尾是分号。

以“#”开始的是注释行。

二、怎样使用http配置

处理http配置项可以分为以下四个步骤:

(1)创建数据结构用于存储配置项对应的参数。

(2)设定配置项在nginx.conf中出现时的限制条件与回调方法。

(3)实现第二步中的回调方法,或者使用Nginx框架预设的14个回调方法。

(4)合并不同级别的配置块中出现的同名配置项。

在这里不得不提到的是两个非常重要的数据结构:ngx_http_module_t以及ngx_command_t,是HTTP模块时不可或缺的部分,它们把这四个步骤与Nginx有机地结合起来。

在本例中我们通过在配置文件中添加如下项来自己编写模块进行解析(添加到默认server块内):

[cpp] view plaincopyprint?

  1. #测试配置项2
  2. location /test2 {
  3. test_str "hello my dear HUST!";
  4. test_flag on;
  5. test_num 10;
  6. test_size 1000;
  7. mytest;
  8. }

要实现的效果是,当在浏览器中输入http://localhost/test2时,将所有包含参数的配置项名及其对应的参数输出。

分配用于保存配置参数的数据结构

这个数据结构依据需要保存的参数自定义即可。

一般情况下这个结构是(包含了各种类型的配置项,但是在本例中只实现了部分类型的配置项的解析):

[cpp] view plaincopyprint?

  1. //存储配置项参数的结构体
  2. typedef struct{
  3. ngx_str_t arg_str;//保存一个字符串类型的参数
  4. ngx_int_t arg_num;
  5. ngx_flag_t arg_flag;
  6. size_t arg_size;
  7. ngx_array_t* arg_str_array;
  8. ngx_array_t* arg_keyval;
  9. off_t arg_off;
  10. ngx_msec_t arg_msec;
  11. time_t arg_sec;
  12. ngx_bufs_t arg_bufs;
  13. ngx_uint_t arg_enum_seq;
  14. ngx_uint_t arg_bitmask;
  15. ngx_uint_t arg_access;
  16. ngx_path_t* arg_path;
  17. }ngx_http_mytest2_loc_conf_t;

需要注意的是,这个结构会Nginx的内存中保存许多份。http框架在解析nginx.conf文件时,只要遇到http{}、server{}、或者location{}配置块就会立刻分配一个新的结构体。

Nginx如何管理我们自定义的存储配置的结构体呢?

是通过ngx_http_module_t中的8个回调方法(ngx_http_config.h):

[cpp] view plaincopyprint?

  1. 24 typedef struct {
  2. 25     ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);
  3. 26     ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);
  4. 27
  5. 28     void       *(*create_main_conf)(ngx_conf_t *cf);
  6. 29     char       *(*init_main_conf)(ngx_conf_t *cf, void *conf);
  7. 30
  8. 31     void       *(*create_srv_conf)(ngx_conf_t *cf);
  9. 32     char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);
  10. 33
  11. 34     void       *(*create_loc_conf)(ngx_conf_t *cf);
  12. 35     char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
  13. 36 } ngx_http_module_t;

其中以create开头的三个回调方法负责把我们分配的用于保存配置项的结构体传递给http框架。为什么会定义三个回调方法呢?

http框架定义了三个级别的配置main、srv、loc,分别表示直接出现在http{}、server{}、location{}、块内的配置。当nginx.conf中出现http{}时,http框架会接管配置文件中http{}块内的配置项解析。当遇到http{}配置块时,http框架会调用所有的http模块可能实现的create_main_conf、create_srv_conf、create_loc_conf方法生成存储main级别的配置参数的结构体;在遇到server{}配置块时,会再次调用所有的http模块可能实现的create_srv_conf、create_loc_conf方法生成存储srv级别的配置参数的结构体;在遇到location{}配置块时,会再次调用所有的http模块可能实现的create_loc_conf方法生成存储loc级别的配置参数的结构体。实现三个回调方法的意义是不同的。在一个模块中,http块内只会调用一次create_main_conf,但是create_loc_conf可能会被调用很多次,也就是有许多由create_loc_conf生成的结构体。

普通http请求往往只实现create_loc_conf回调方法,因为它们只关注匹配某种URL的请求。

设定配置项的解析方式

我们在ngx_command_t结构体中设定配置项的解析方式:

[cpp] view plaincopyprint?

  1. 78 struct ngx_command_s {
  2. 79     ngx_str_t             name;//配置项名称
  3. 80     ngx_uint_t            type;//决定这个配置项可以在哪些块中出现以及可以携带的参数类型和个数
  4. 81     char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);//回调方法,可以自己实现也可以使用预设的14个方法
  5. 82     ngx_uint_t            conf;//配置项所处内存的相对偏移量
  6. 83     ngx_uint_t            offset;//当前配置项在整个存储配置项的结构体中的偏移位置
  7. 84     void                 *post;//配置项的回调方法
  8. 85 };

在本例中,前四个配置项都用预设的方法进行解析,而最后一个配置项mytest用自定义的方法,并在这个方法中将前面各个配置项的参数组合成一个字符串返回给客户。

我们需要通过定义ngx_command_t数组来设置配置项的解析方式:

[cpp] view plaincopyprint?

  1. //设置配置项的解析方式
  2. static ngx_command_t ngx_http_mytest2_commands[] = {
  3. {
  4. //test_str配置项
  5. ngx_string("test_str"),
  6. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  7. ngx_conf_set_str_slot,//预设的配置项解析方法
  8. NGX_HTTP_LOC_CONF_OFFSET,
  9. offsetof(ngx_http_mytest2_loc_conf_t,arg_str),
  10. NULL
  11. },
  12. {
  13. //test_flag配置项
  14. ngx_string("test_flag"),
  15. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  16. ngx_conf_set_flag_slot,//预设的配置项解析方法
  17. NGX_HTTP_LOC_CONF_OFFSET,
  18. offsetof(ngx_http_mytest2_loc_conf_t,arg_flag),
  19. NULL
  20. },
  21. {
  22. //test_num配置项
  23. ngx_string("test_num"),
  24. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  25. ngx_conf_set_num_slot,//预设的配置项解析方法
  26. NGX_HTTP_LOC_CONF_OFFSET,
  27. offsetof(ngx_http_mytest2_loc_conf_t,arg_num),
  28. NULL
  29. },
  30. {
  31. //test_size配置项
  32. ngx_string("test_size"),
  33. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  34. ngx_conf_set_size_slot,//预设的配置项解析方法
  35. NGX_HTTP_LOC_CONF_OFFSET,
  36. offsetof(ngx_http_mytest2_loc_conf_t,arg_size),
  37. NULL
  38. },
  39. {
  40. //mytest配置项
  41. ngx_string("mytest"),
  42. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,
  43. ngx_http_mytest2,
  44. NGX_HTTP_LOC_CONF_OFFSET,
  45. 0,
  46. NULL
  47. },
  48. ngx_null_command
  49. };

其中自定义的配置项解析方法ngx_http_mytest2:

[cpp] view plaincopyprint?

  1. //模块的回调方法
  2. static char *
  3. ngx_http_mytest2(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  4. {
  5. ngx_http_core_loc_conf_t *clcf;
  6. clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  7. clcf->handler = ngx_http_mytest2_handler;//每当遇到配置项mytest的时候会回调这个方法
  8. return NGX_CONF_OK;
  9. }

真正完成处理工作的handler是 ngx_http_mytest2_handler:

[cpp] view plaincopyprint?

  1. //模块真正完成处理工作的handler
  2. static ngx_int_t ngx_http_mytest2_handler(ngx_http_request_t *r)
  3. {
  4. ngx_http_mytest2_loc_conf_t *elcf;//存储配置项参数的结构体
  5. elcf = ngx_http_get_module_loc_conf(r,ngx_http_mytest2_module);
  6. if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD | NGX_HTTP_POST))) {
  7. return NGX_HTTP_NOT_ALLOWED;
  8. }
  9. ngx_int_t rc = ngx_http_discard_request_body(r);
  10. if (rc != NGX_OK) {
  11. return rc;
  12. }
  13. ngx_str_t type = ngx_string("text/plain");
  14. ngx_str_t str_format = ngx_string("test_str=%V,test_flag=%i,test_num=%i,test_size=%z");
  15. ngx_str_t test_str = elcf->arg_str;
  16. ngx_flag_t test_flag = elcf->arg_flag;
  17. ngx_int_t test_num = elcf->arg_num;
  18. size_t test_size = elcf->arg_size;
  19. int data_len = str_format.len + test_str.len + 1;
  20. r->headers_out.status = NGX_HTTP_OK;
  21. r->headers_out.content_length_n = data_len;//响应包包体内容长度
  22. r->headers_out.content_type = type;
  23. rc = ngx_http_send_header(r);
  24. if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
  25. return rc;
  26. }
  27. ngx_buf_t *b;
  28. b = ngx_create_temp_buf(r->pool,data_len);
  29. if (b == NULL) {
  30. return NGX_HTTP_INTERNAL_SERVER_ERROR;
  31. }
  32. ngx_snprintf(b->pos,data_len,(char *)str_format.data,&test_str,test_flag,test_num,test_size);
  33. b->last = b->pos + data_len;
  34. b->last_buf = 1;
  35. ngx_chain_t out;
  36. out.buf = b;
  37. out.next = NULL;
  38. return ngx_http_output_filter(r, &out);
  39. }

三、新添加模块的编译

普通编译方式是:

[cpp] view plaincopyprint?

  1. ./configure --prefix=/usr/local/nginx --add-module=XX(新模块的config文件以及源码所存放的目录)
  2. make
  3. sudo make install

但是这样的一个缺点是:每次都要编译所有的nginx源码,速度慢。如果自己编写的新模块中的源代码中有错误,调试起来很不方便。有一个方法是自己编写一个makefile文件,先单独编译新模块的代码,修正所有错误之后再将其编译进Nginx。

这是我编写的MakeFile文件:

[cpp] view plaincopyprint?

  1. #编译新模块的makefile文件
  2. ngx_http_mytest_module.o: ngx_http_mytest_module.c
  3. gcc -c -pipe  -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g   -I /home/xiajun/TEST/Nginx/nginx-1.4.1/src/core -I /home/xiajun/TEST/Nginx/nginx-1.4.1/src/event -I /home/xiajun/TEST/Nginx/nginx-1.4.1/src/event/modules -I /home/xiajun/TEST/Nginx/nginx-1.4.1/src/os/unix -I /home/xiajun/TEST/Nginx/nginx-1.4.1/objs -I /home/xiajun/TEST/Nginx/nginx-1.4.1/src/http -I /home/xiajun/TEST/Nginx/nginx-1.4.1/src/http/modules -I /home/xiajun/TEST/Nginx/nginx-1.4.1/src/mail -o ngx_http_mytest_module.o /home/xiajun/TEST/Nginx/nginx-1.4.1/mytest/ngx_http_mytest_module.c

四、完整代码及结果演示

config文件:

ngx_addon_name=ngx_http_mytest2

HTTP_MODULES="$HTTP_MODULES ngx_http_mytest2_module"

NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_mytest2_module.c"

ngx_http_mytest2_module.c:

[cpp] view plaincopyprint?

  1. //Nginx自定义模块实现代码
  2. //E-Mail:[email protected](江南烟雨)
  3. #include <ngx_config.h>
  4. #include <ngx_core.h>
  5. #include <ngx_http.h>
  6. static ngx_int_t
  7. ngx_http_mytest2_handler(ngx_http_request_t *r);
  8. static char *
  9. ngx_http_mytest2(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
  10. static void*
  11. ngx_http_mytest2_create_loc_conf(ngx_conf_t *cf);
  12. static char*
  13. ngx_http_mytest2_merge_loc_conf(ngx_conf_t *cf,void *parent,void *child);
  14. //存储配置项参数的结构体
  15. typedef struct{
  16. ngx_str_t arg_str;//保存一个字符串类型的参数
  17. ngx_int_t arg_num;
  18. ngx_flag_t arg_flag;
  19. size_t arg_size;
  20. ngx_array_t* arg_str_array;
  21. ngx_array_t* arg_keyval;
  22. off_t arg_off;
  23. ngx_msec_t arg_msec;
  24. time_t arg_sec;
  25. ngx_bufs_t arg_bufs;
  26. ngx_uint_t arg_enum_seq;
  27. ngx_uint_t arg_bitmask;
  28. ngx_uint_t arg_access;
  29. ngx_path_t* arg_path;
  30. }ngx_http_mytest2_loc_conf_t;
  31. //设置配置项的解析方式
  32. static ngx_command_t ngx_http_mytest2_commands[] = {
  33. {
  34. //test_str配置项
  35. ngx_string("test_str"),
  36. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  37. ngx_conf_set_str_slot,//预设的配置项解析方法
  38. NGX_HTTP_LOC_CONF_OFFSET,
  39. offsetof(ngx_http_mytest2_loc_conf_t,arg_str),
  40. NULL
  41. },
  42. {
  43. //test_flag配置项
  44. ngx_string("test_flag"),
  45. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  46. ngx_conf_set_flag_slot,//预设的配置项解析方法
  47. NGX_HTTP_LOC_CONF_OFFSET,
  48. offsetof(ngx_http_mytest2_loc_conf_t,arg_flag),
  49. NULL
  50. },
  51. {
  52. //test_num配置项
  53. ngx_string("test_num"),
  54. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  55. ngx_conf_set_num_slot,//预设的配置项解析方法
  56. NGX_HTTP_LOC_CONF_OFFSET,
  57. offsetof(ngx_http_mytest2_loc_conf_t,arg_num),
  58. NULL
  59. },
  60. {
  61. //test_size配置项
  62. ngx_string("test_size"),
  63. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
  64. ngx_conf_set_size_slot,//预设的配置项解析方法
  65. NGX_HTTP_LOC_CONF_OFFSET,
  66. offsetof(ngx_http_mytest2_loc_conf_t,arg_size),
  67. NULL
  68. },
  69. {
  70. //mytest配置项
  71. ngx_string("mytest"),
  72. NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,
  73. ngx_http_mytest2,
  74. NGX_HTTP_LOC_CONF_OFFSET,
  75. 0,
  76. NULL
  77. },
  78. ngx_null_command
  79. };
  80. //模块上下文定义
  81. static ngx_http_module_t ngx_http_mytest2_module_ctx = {
  82. NULL,
  83. NULL,
  84. NULL,
  85. NULL,
  86. NULL,
  87. NULL,
  88. ngx_http_mytest2_create_loc_conf,//创建数据结构存储loc级别的配置项的回调方法
  89. ngx_http_mytest2_merge_loc_conf//合并loc级别的配置项
  90. };
  91. //模块定义
  92. ngx_module_t ngx_http_mytest2_module = {
  93. NGX_MODULE_V1,
  94. &ngx_http_mytest2_module_ctx,
  95. ngx_http_mytest2_commands,
  96. NGX_HTTP_MODULE,
  97. NULL,
  98. NULL,
  99. NULL,
  100. NULL,
  101. NULL,
  102. NULL,
  103. NULL,
  104. NGX_MODULE_V1_PADDING
  105. };
  106. //模块的回调方法
  107. static char *
  108. ngx_http_mytest2(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  109. {
  110. ngx_http_core_loc_conf_t *clcf;
  111. clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  112. clcf->handler = ngx_http_mytest2_handler;
  113. //ngx_conf_set_str_slot(cf,cmd,conf);//预设的配置项处理方法
  114. return NGX_CONF_OK;
  115. }
  116. //模块真正完成处理工作的handler
  117. static ngx_int_t ngx_http_mytest2_handler(ngx_http_request_t *r)
  118. {
  119. ngx_http_mytest2_loc_conf_t *elcf;//存储配置项参数的结构体
  120. elcf = ngx_http_get_module_loc_conf(r,ngx_http_mytest2_module);
  121. if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD | NGX_HTTP_POST))) {
  122. return NGX_HTTP_NOT_ALLOWED;
  123. }
  124. ngx_int_t rc = ngx_http_discard_request_body(r);
  125. if (rc != NGX_OK) {
  126. return rc;
  127. }
  128. ngx_str_t type = ngx_string("text/plain");
  129. ngx_str_t str_format = ngx_string("test_str=%V,test_flag=%i,test_num=%i,test_size=%z");
  130. ngx_str_t test_str = elcf->arg_str;
  131. ngx_flag_t test_flag = elcf->arg_flag;
  132. ngx_int_t test_num = elcf->arg_num;
  133. size_t test_size = elcf->arg_size;
  134. int data_len = str_format.len + test_str.len + 1;
  135. r->headers_out.status = NGX_HTTP_OK;
  136. r->headers_out.content_length_n = data_len;//响应包包体内容长度
  137. r->headers_out.content_type = type;
  138. rc = ngx_http_send_header(r);
  139. if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
  140. return rc;
  141. }
  142. ngx_buf_t *b;
  143. b = ngx_create_temp_buf(r->pool,data_len);
  144. if (b == NULL) {
  145. return NGX_HTTP_INTERNAL_SERVER_ERROR;
  146. }
  147. ngx_snprintf(b->pos,data_len,(char *)str_format.data,&test_str,test_flag,test_num,test_size);
  148. b->last = b->pos + data_len;
  149. b->last_buf = 1;
  150. ngx_chain_t out;
  151. out.buf = b;
  152. out.next = NULL;
  153. return ngx_http_output_filter(r, &out);
  154. }
  155. static void*
  156. ngx_http_mytest2_create_loc_conf(ngx_conf_t *cf){
  157. ngx_http_mytest2_loc_conf_t *conf;
  158. conf = ngx_pcalloc(cf->pool,sizeof(ngx_http_mytest2_loc_conf_t));
  159. if(NULL == conf){
  160. return NGX_CONF_ERROR;
  161. }
  162. conf->arg_str.len = 0;
  163. conf->arg_str.data = NULL;
  164. //注意一下设定必不可少,否则会出错
  165. conf->arg_flag = NGX_CONF_UNSET;
  166. conf->arg_num = NGX_CONF_UNSET;
  167. conf->arg_str_array = NGX_CONF_UNSET_PTR;
  168. conf->arg_keyval = NULL;
  169. conf->arg_off = NGX_CONF_UNSET;
  170. conf->arg_msec = NGX_CONF_UNSET_MSEC;
  171. conf->arg_sec = NGX_CONF_UNSET;
  172. conf->arg_size = NGX_CONF_UNSET_SIZE;
  173. return conf;
  174. }
  175. static char*
  176. ngx_http_mytest2_merge_loc_conf(ngx_conf_t *cf,void *parent,void *child){
  177. ngx_http_mytest2_loc_conf_t *prev = parent;
  178. ngx_http_mytest2_loc_conf_t *conf = child;
  179. ngx_conf_merge_str_value(conf->arg_str,prev->arg_str,"");
  180. return NGX_CONF_OK;
  181. }

结果演示:

五、参考资料:

淘宝tengine

from:http://blog.csdn.net/xiajun07061225/article/details/9147265

时间: 2024-10-18 18:25:25

Nginx学习之二-配置项解析及编程实现的相关文章

Spring4的学习(二)之AOP编程

1. AOP 简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充. AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点. 在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里. AOP 的好处:

nginx 学习(二) hello world 程序

hello wrold 1 本节目的 2实现步骤 2.1config编写 2.2模块代码实现 2.3配置文件的编写 3将模块编译进nginx中 1本节的目的 本节用nginx来实现一个经典程序hello world,这个程序也是我们学任何编程语言时首先接触的程序,这个程序的目的是 初步了解nginx怎样嵌入第三方模块,也是学习nginx的HTTP模块的入门. 2实现步骤 nginx 提供了一种简单的方式将第三方模块嵌入nginx中:只需要三个步骤 步骤一:编写config 步骤二:实现模块的代码

nginx学习(二)——模块指令介绍

nginx.conf 配置文件详解 Nginx 配置文件主要分成四部分:main(全局设置).server(主机设置).upstream(上游服务器设置,主要为反向代理.负载均衡相关配置)和 location(URL匹配特定位置后的设置).main 部分设置的指令影响其他所有部分的设置:server 部分的指令主要用于制定虚拟主机域名.IP 和端口号:upstream 的指令用于设置一系列的后端服务器,设置反向代理及后端服务器的负载均衡:location 部分用于匹配网页位置(比如,根目录“/”

轻松学习JavaScript二十一:DOM编程学习之获取元素节点的子节点和属性节点

我们这里所说的获取元素节点的所有子节点包含元素子节点和文本节点两种.还是拿上一篇博文的代码实例进行 分析: <span style="font-size:18px;"><span style="font-size:18px;"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1

nginx学习(二)——基础概念之异步非阻塞

上面讲了很多关于nginx的进程模型,接下来,我们来看看nginx是如何处理事件的. 有人可能要问了,nginx采用多worker的方式来处理请求,每个worker里面只有一个主线程,那能够处理的并发数很有限啊,多少个worker就能处理多少个并发,何来高并发呢?非也,这就是nginx的高明之处,nginx采用了异步非阻塞的方式来处理请求,也就是说,nginx是可以同时处理成千上万个请求的.想想apache的常用工作方式(apache也有异步非阻塞版本,但因其与自带某些模块冲突,所以不常用),每

Nginx学习笔记二基本配置

1.Nginx的配置文件默认在Nginx程序安装目录的conf二级目录下,主配置文件为nginx.conf.假设您的Nginx安装 在/usr/local/webserver/nginx/目录下,那么默认的主配置文件则为/usr/local/webserver/nginx/nginx.conf.2.Nginx配置参数:(1)user www www 指定使用的用户和用户所在的组(2)worker_processes 8 指定工作衍生进程数(一般等于CPU的总核数或总核数的两倍,如两个四核CPU,

nodejs学习笔记二:解析express框架项目文件

上一章介绍了如何去创建一个express框架的工程项目,这章介绍一下express框架下的文件和用法解析,上一张我们创建的工程项目结构图如下: models是不属于原工程项目结构,为了实现数据模型后添加的,而node_modules这个文件夹内存放着项目需要的中间件,public是存放静态文件的文件夹,routes顾名思义就是路由解析文件的所在,views就是ejs模板引擎的视图文件,app.js是项目运行的入口存放着全局大量的配置,package.json是加载第三方包的配置文件.下面来一一解

nginx学习(二):初识配置文件

nginx的配置文件默认在nginx安装目录中的conf子目录中,主配置文件为nginx.conf, [email protected] conf]# pwd/usr/local/nginx/conf一.配置文件 [[email protected] conf]# vi nginx.conf  1      2 #user  nobody;         #指定运行的用户和组:      3 worker_processes  1;               #工作进程数,一般与CPU核数相

轻松学习JavaScript二十三:DOM编程学习之操作表格

一使用HTML标签创建表格: 代码: <span style="font-size:18px;"><table border="1px"width="300px"> <caption>人员表</caption> <thead> <tr> <th>姓名</th> <th>性别</th> <th>年龄</th>