<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    Nginx學習之二-配置項解析及編程實現

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接 在開發功能靈活的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.   
    4. #error_log  logs/error.log;  
    5. #error_log  logs/error.log  notice;  
    6. #error_log  logs/error.log  info;  
    7.   
    8. #pid        logs/nginx.pid;  
    9.   
    10.   
    11. events {  
    12.     worker_connections  1024;  
    13. }  
    14.   
    15.   
    16. http {  
    17.     include       mime.types;  
    18.     default_type  application/octet-stream;  
    19.   
    20.     #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '  
    21.     #                  '$status $body_bytes_sent "$http_referer" '  
    22.     #                  '"$http_user_agent" "$http_x_forwarded_for"';  
    23.   
    24.     #access_log  logs/access.log  main;  
    25.   
    26.     sendfile        on;  
    27.     #tcp_nopush     on;  
    28.   
    29.     #keepalive_timeout  0;  
    30.     keepalive_timeout  65;  
    31.   
    32.     #gzip  on;  
    33.   
    34.     server {  
    35.         listen       80;  
    36.         server_name  localhost;  
    37.   
    38.         #charset koi8-r;  
    39.   
    40.         #access_log  logs/host.access.log  main;  
    41.   
    42.         location / {  
    43.             root   html;  
    44.             index  index.html index.htm;  
    45.         }  
    46.   
    47.         #error_page  404              /404.html;  
    48.   
    49.         # redirect server error pages to the static page /50x.html  
    50.         #  
    51.         error_page   500 502 503 504  /50x.html;  
    52.         location = /50x.html {  
    53.             root   html;  
    54.         }  
    55.   
    56.         # proxy the PHP scripts to Apache listening on 127.0.0.1:80  
    57.         #  
    58.         #location ~ \.php$ {  
    59.         #    proxy_pass   http://127.0.0.1;  
    60.         #}  
    61.   
    62.         # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000  
    63.         #  
    64.         #location ~ \.php$ {  
    65.         #    root           html;  
    66.         #    fastcgi_pass   127.0.0.1:9000;  
    67.         #    fastcgi_index  index.php;  
    68.         #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;  
    69.         #    include        fastcgi_params;  
    70.         #}  
    71.   
    72.         # deny access to .htaccess files, if Apache's document root  
    73.         # concurs with nginx's one  
    74.         #  
    75.         #location ~ /\.ht {  
    76.         #    deny  all;  
    77.         #}  
    78.     }  
    79.   
    80.   
    81.     # another virtual host using mix of IP-, name-, and port-based configuration  
    82.     #  
    83.     #server {  
    84.     #    listen       8000;  
    85.     #    listen       somename:8080;  
    86.     #    server_name  somename  alias  another.alias;  
    87.   
    88.     #    location / {  
    89.     #        root   html;  
    90.     #        index  index.html index.htm;  
    91.     #    }  
    92.     #}  
    93.   
    94.   
    95.     # HTTPS server  
    96.     #  
    97.     #server {  
    98.     #    listen       443;  
    99.     #    server_name  localhost;  
    100.   
    101.     #    ssl                  on;  
    102.     #    ssl_certificate      cert.pem;  
    103.     #    ssl_certificate_key  cert.key;  
    104.   
    105.     #    ssl_session_timeout  5m;  
    106.   
    107.     #    ssl_protocols  SSLv2 SSLv3 TLSv1;  
    108.     #    ssl_ciphers  HIGH:!aNULL:!MD5;  
    109.     #    ssl_prefer_server_ciphers   on;  
    110.   
    111.     #    location / {  
    112.     #        root   html;  
    113.     #        index  index.html index.htm;  
    114.     #    }  
    115.     #}  
    116.   
    117. }  

    塊配置項 配置文件中有很多塊配置項。塊配置項是由一個塊配置項名和一對大括號組成。例如上面代碼段中的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.   
    7.     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);  
    8.     clcf->handler = ngx_http_mytest2_handler;//每當遇到配置項mytest的時候會回調這個方法  
    9.   
    10.     return NGX_CONF_OK;  
    11. }  
    真正完成處理工作的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.   
    7.     if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD | NGX_HTTP_POST))) {  
    8.         return NGX_HTTP_NOT_ALLOWED;  
    9.     }  
    10.   
    11.     ngx_int_t rc = ngx_http_discard_request_body(r);  
    12.     if (rc != NGX_OK) {  
    13.         return rc;  
    14.     }  
    15.   
    16.     ngx_str_t type = ngx_string("text/plain");  
    17.         ngx_str_t str_format = ngx_string("test_str=%V,test_flag=%i,test_num=%i,test_size=%z");  
    18.         ngx_str_t test_str = elcf->arg_str;  
    19.         ngx_flag_t test_flag = elcf->arg_flag;  
    20.         ngx_int_t test_num = elcf->arg_num;  
    21.         size_t test_size = elcf->arg_size;  
    22.         int data_len = str_format.len + test_str.len + 1;  
    23.     r->headers_out.status = NGX_HTTP_OK;  
    24.     r->headers_out.content_length_n = data_len;//響應包包體內容長度  
    25.     r->headers_out.content_type = type;  
    26.   
    27.     rc = ngx_http_send_header(r);  
    28.     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {  
    29.         return rc;  
    30.     }  
    31.   
    32.     ngx_buf_t *b;  
    33.     b = ngx_create_temp_buf(r->pool,data_len);  
    34.         if (b == NULL) {  
    35.         return NGX_HTTP_INTERNAL_SERVER_ERROR;  
    36.     }  
    37.   
    38.         ngx_snprintf(b->pos,data_len,(char *)str_format.data,&test_str,test_flag,test_num,test_size);  
    39.         b->last = b->pos + data_len;  
    40.     b->last_buf = 1;  
    41.   
    42.     ngx_chain_t out;  
    43.     out.buf = b;  
    44.     out.next = NULL;  
    45.   
    46.     return ngx_http_output_filter(r, &out);  
    47. }  

    三、新添加模塊的編譯 普通編譯方式是: [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.   
    3. ngx_http_mytest_module.o: ngx_http_mytest_module.c  
    4.     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:xiajunhust@gmail.com(江南煙雨)  
    3.   
    4. #include <ngx_config.h>  
    5. #include <ngx_core.h>  
    6. #include <ngx_http.h>  
    7.   
    8. static ngx_int_t   
    9. ngx_http_mytest2_handler(ngx_http_request_t *r);  
    10.   
    11. static char *   
    12. ngx_http_mytest2(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);  
    13.   
    14. static void*  
    15. ngx_http_mytest2_create_loc_conf(ngx_conf_t *cf);  
    16.   
    17. static char*  
    18. ngx_http_mytest2_merge_loc_conf(ngx_conf_t *cf,void *parent,void *child);  
    19.   
    20. //存儲配置項參數的結構體  
    21. typedef struct{  
    22.         ngx_str_t arg_str;//保存一個字符串類型的參數  
    23.         ngx_int_t arg_num;  
    24.         ngx_flag_t arg_flag;  
    25.         size_t arg_size;  
    26.         ngx_array_t* arg_str_array;  
    27.         ngx_array_t* arg_keyval;  
    28.         off_t arg_off;  
    29.         ngx_msec_t arg_msec;  
    30.         time_t arg_sec;  
    31.         ngx_bufs_t arg_bufs;  
    32.         ngx_uint_t arg_enum_seq;  
    33.         ngx_uint_t arg_bitmask;  
    34.         ngx_uint_t arg_access;  
    35.         ngx_path_t* arg_path;  
    36. }ngx_http_mytest2_loc_conf_t;  
    37.   
    38. //設置配置項的解析方式  
    39. static ngx_command_t ngx_http_mytest2_commands[] = {  
    40.         {  
    41.                 //test_str配置項  
    42.                 ngx_string("test_str"),  
    43.         NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,  
    44.         ngx_conf_set_str_slot,//預設的配置項解析方法  
    45.                 NGX_HTTP_LOC_CONF_OFFSET,  
    46.                 offsetof(ngx_http_mytest2_loc_conf_t,arg_str),  
    47.                 NULL  
    48.         },  
    49.         {  
    50.                 //test_flag配置項  
    51.                 ngx_string("test_flag"),  
    52.         NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,  
    53.                 ngx_conf_set_flag_slot,//預設的配置項解析方法  
    54.         NGX_HTTP_LOC_CONF_OFFSET,  
    55.                 offsetof(ngx_http_mytest2_loc_conf_t,arg_flag),  
    56.                 NULL  
    57.         },  
    58.         {  
    59.                 //test_num配置項  
    60.                 ngx_string("test_num"),  
    61.         NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,  
    62.                 ngx_conf_set_num_slot,//預設的配置項解析方法  
    63.         NGX_HTTP_LOC_CONF_OFFSET,  
    64.                 offsetof(ngx_http_mytest2_loc_conf_t,arg_num),  
    65.                 NULL  
    66.         },  
    67.         {  
    68.                 //test_size配置項  
    69.                 ngx_string("test_size"),  
    70.         NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,  
    71.                 ngx_conf_set_size_slot,//預設的配置項解析方法  
    72.         NGX_HTTP_LOC_CONF_OFFSET,  
    73.                 offsetof(ngx_http_mytest2_loc_conf_t,arg_size),  
    74.                 NULL  
    75.         },  
    76.         {  
    77.                 //mytest配置項  
    78.                 ngx_string("mytest"),  
    79.         NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,  
    80.         ngx_http_mytest2,  
    81.                 NGX_HTTP_LOC_CONF_OFFSET,  
    82.                 0,  
    83.                 NULL  
    84.         },  
    85.     ngx_null_command  
    86. };  
    87.   
    88. //模塊上下文定義  
    89. static ngx_http_module_t ngx_http_mytest2_module_ctx = {  
    90.     NULL,  
    91.     NULL,  
    92.     NULL,  
    93.     NULL,  
    94.     NULL,  
    95.     NULL,  
    96.     ngx_http_mytest2_create_loc_conf,//創建數據結構存儲loc級別的配置項的回調方法  
    97.     ngx_http_mytest2_merge_loc_conf//合并loc級別的配置項  
    98. };  
    99.   
    100. //模塊定義  
    101. ngx_module_t ngx_http_mytest2_module = {  
    102.     NGX_MODULE_V1,  
    103.     &ngx_http_mytest2_module_ctx,  
    104.     ngx_http_mytest2_commands,  
    105.     NGX_HTTP_MODULE,  
    106.     NULL,  
    107.     NULL,  
    108.     NULL,  
    109.     NULL,  
    110.     NULL,  
    111.     NULL,  
    112.         NULL,  
    113.     NGX_MODULE_V1_PADDING  
    114. };  
    115.   
    116. //模塊的回調方法  
    117. static char *   
    118. ngx_http_mytest2(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)  
    119. {  
    120.     ngx_http_core_loc_conf_t *clcf;  
    121.   
    122.     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);  
    123.     clcf->handler = ngx_http_mytest2_handler;  
    124.         //ngx_conf_set_str_slot(cf,cmd,conf);//預設的配置項處理方法  
    125.   
    126.     return NGX_CONF_OK;  
    127. }  
    128.   
    129. //模塊真正完成處理工作的handler  
    130. static ngx_int_t ngx_http_mytest2_handler(ngx_http_request_t *r)  
    131. {  
    132.         ngx_http_mytest2_loc_conf_t *elcf;//存儲配置項參數的結構體  
    133.         elcf = ngx_http_get_module_loc_conf(r,ngx_http_mytest2_module);  
    134.   
    135.     if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD | NGX_HTTP_POST))) {  
    136.         return NGX_HTTP_NOT_ALLOWED;  
    137.     }  
    138.   
    139.     ngx_int_t rc = ngx_http_discard_request_body(r);  
    140.     if (rc != NGX_OK) {  
    141.         return rc;  
    142.     }  
    143.   
    144.     ngx_str_t type = ngx_string("text/plain");  
    145.         ngx_str_t str_format = ngx_string("test_str=%V,test_flag=%i,test_num=%i,test_size=%z");  
    146.         ngx_str_t test_str = elcf->arg_str;  
    147.         ngx_flag_t test_flag = elcf->arg_flag;  
    148.         ngx_int_t test_num = elcf->arg_num;  
    149.         size_t test_size = elcf->arg_size;  
    150.         int data_len = str_format.len + test_str.len + 1;  
    151.     r->headers_out.status = NGX_HTTP_OK;  
    152.     r->headers_out.content_length_n = data_len;//響應包包體內容長度  
    153.     r->headers_out.content_type = type;  
    154.   
    155.     rc = ngx_http_send_header(r);  
    156.     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {  
    157.         return rc;  
    158.     }  
    159.   
    160.     ngx_buf_t *b;  
    161.     b = ngx_create_temp_buf(r->pool,data_len);  
    162.         if (b == NULL) {  
    163.         return NGX_HTTP_INTERNAL_SERVER_ERROR;  
    164.     }  
    165.   
    166.         ngx_snprintf(b->pos,data_len,(char *)str_format.data,&test_str,test_flag,test_num,test_size);  
    167.         b->last = b->pos + data_len;  
    168.     b->last_buf = 1;  
    169.   
    170.     ngx_chain_t out;  
    171.     out.buf = b;  
    172.     out.next = NULL;  
    173.   
    174.     return ngx_http_output_filter(r, &out);  
    175. }  
    176.   
    177. static void*  
    178. ngx_http_mytest2_create_loc_conf(ngx_conf_t *cf){  
    179.         ngx_http_mytest2_loc_conf_t *conf;  
    180.         conf = ngx_pcalloc(cf->pool,sizeof(ngx_http_mytest2_loc_conf_t));  
    181.         if(NULL == conf){  
    182.                 return NGX_CONF_ERROR;  
    183.         }  
    184.         conf->arg_str.len = 0;  
    185.         conf->arg_str.data = NULL;  
    186.   
    187.         //注意一下設定必不可少,否則會出錯  
    188.         conf->arg_flag = NGX_CONF_UNSET;  
    189.         conf->arg_num = NGX_CONF_UNSET;  
    190.         conf->arg_str_array = NGX_CONF_UNSET_PTR;  
    191.         conf->arg_keyval = NULL;  
    192.         conf->arg_off = NGX_CONF_UNSET;  
    193.         conf->arg_msec = NGX_CONF_UNSET_MSEC;  
    194.         conf->arg_sec = NGX_CONF_UNSET;  
    195.         conf->arg_size = NGX_CONF_UNSET_SIZE;  
    196.   
    197.         return conf;  
    198. }  
    199.   
    200.   
    201. static char*  
    202. ngx_http_mytest2_merge_loc_conf(ngx_conf_t *cf,void *parent,void *child){  
    203.         ngx_http_mytest2_loc_conf_t *prev = parent;  
    204.         ngx_http_mytest2_loc_conf_t *conf = child;  
    205.         ngx_conf_merge_str_value(conf->arg_str,prev->arg_str,"");  
    206.   
    207.         return NGX_CONF_OK;  
    208. }  

    結果演示: RFID設備管理軟件


    五、參考資料: 淘寶tengine from:http://blog.csdn.net/xiajun07061225/article/details/9147265RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全