nginx的http模塊開發--一個驗證url參數的例子


本文開發一個nginx http模塊基本的開發步驟和前篇http://www.cnblogs.com/yjf512/archive/2013/06/10/3130890.html 說的一樣,按照開發的六個步驟寫。

配置文件及功能

該模塊的功能是驗證請求url中的secret參數的值是否是約定的秘鑰。

它的nginx配置文件是這樣的:

worker_processes  1;

error_log logs/error.log debug;
master_process off;
daemon off;

events {
    worker_connections  1024;
}


http {
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       8001;
        server_name  localhost;

        access_log  /tmp/access.log; 
        error_log  /tmp/error.log debug;

        location / {
            root   html;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location = /mysecert {
            # 只有傳遞的secret參數值為secretpassword的時候才通過驗證
            # 1 通過驗證頁面顯示“secret right”
            # 2 不通過驗證頁面顯示“secret wrong”
            # 比如
            # http://abc.com:8001?secret=secretpassword通過
            # http://abc.com:8001?secret=123不通過
            mysecret secretpassword;
        }
    }

}

 

location為/mysecret的時候,需要傳遞值為secretpassword的mysecret參數。頁面會返回200並顯示secret right,否則頁面返回200並顯示secret wrong。

配置文件這里有幾個地方注意下:

為了調試方便,調整了幾個地方:

worker_processes  1; 
master_process off;
daemon off;
…
access_log  /tmp/access.log; 
error_log  /tmp/error.log debug;

而且在configure的時候我也加上了--with-debug參數

./configure --add-module=/home/yejianfeng/nginx/nginx_module/mysecret2/ --prefix=/home/yejianfeng/nginx/nginx/ --with-debug 

這樣讓調試更加方便

具體代碼

完整的代碼可以看:https://github.com/jianfengye/MyWorks/tree/master/nginx_module_mysecret

有幾個地方要說明:

1 這個模塊由於有從配置文件中讀取的信息,所以它是有屬於自己模塊的配置文件結構的

typedef struct {

     ngx_str_t secret;

} ngx_http_mysecret_conf_t;

所以有自己的配置文件,那么在模塊構造模塊上下文的時候create_loc_conf的階段就多一個功能是初始化配置文件結構

// 定義上下文, 只會在location中出現,所以都為null

static ngx_http_module_t ngx_http_mysecret_module_ctx = {

     NULL,

     NULL,

     NULL,

     NULL,

     NULL,

     NULL,

     ngx_http_mysecret_create_loc_conf,  //這里有使用自己的配置結構

     NULL

};

其中ngx_http_mysecret_create_loc_conf只要做的事情是初始化配置文件

2 如何將配置文件nginx.conf中的mysecret的一個參數放在配置文件結構中呢?

在ngx_http_mysecret這個命令回調函數中,有個ngx_conf_set_str_slot,這個是nginx預設的14個讀取配置文件的函數之一,調用它就可以把nginx.conf中的secrect秘鑰讀取到配置文件結構中了。

3 在handler中怎么獲取配置文件結構呢?

現在讀取配置文件結束了,也構造了配置文件結構,到具體的處理http請求的階段,如何獲取這個結構呢?

ngx_http_mysecret_conf_t *mycf;

mycf = ngx_http_get_module_loc_conf(r, ngx_http_mysecret_module);

使用這個方法就能在handler中獲取到自定義的配置文件結構了。

獲取配置結構后,后面的問題就是如何獲取請求參數呢

ngx_http_request_t中的args參數就是獲取請求參數的

比如http://abc.com?a=s&b=2 那么args就是ngx_string("a=s&b=2")

后面就可以使用nginx自定義的ngx_strncasecmp進行字符比較等操作了。

好了,完整的一個驗證請求參數的模塊就寫完了。

模塊變種

有人會對nginx.conf文件有點不舒服,可能希望設置驗證秘鑰是分為兩個步驟:

設置秘鑰和驗證秘鑰

即配置文件大致變成現在的樣子:

location = /mysecert {
            # 只有傳遞的secret參數值為secretpassword的時候才通過驗證
            # 1 通過驗證頁面顯示“secret right”
            # 2 不通過驗證頁面顯示“secret wrong”
            # 比如
            # http://abc.com:8001?secret=secretpassword通過
            # http://abc.com:8001?secret=123不通過
            setmysecret secretpassword;
            checksecret;
 }

原來的mysecret被兩個命令setmysecret和checksecret替換了

這兩個命令的功能其實是不一樣的,setmysecret只是讀取配置文件,並不會對請求做任何操作,而checksecret是直接修改請求的。

其實上一個例子稍微改一改就可以達到這樣的目的:

https://github.com/jianfengye/MyWorks/tree/master/nginx_module_mysecret2

定義模塊命令的結構就變成:

static ngx_command_t ngx_http_mysecret_commands[] = {
     {
          ngx_string("setmysecret"),
          NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
          ngx_conf_set_str_slot,
          NGX_HTTP_LOC_CONF_OFFSET,
          offsetof(ngx_http_mysecret_conf_t, secret),
          NULL,
     },
     {
          ngx_string("checksecret"),
          NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
          ngx_http_mysecret,
          NGX_HTTP_LOC_CONF_OFFSET,
          0,
          NULL,
     },

     ngx_null_command
};

這里的setmysecret直接使用nginx預設的ngx_conf_set_str_slot方法,它就不需要有任何定義handler的操作了。事實上,nginx很多模塊的像setmysecret這樣的讀取配置文件的命令(不做任何http請求的操作)都是直接使用nginx預設的14種方法的。具體的使用在《深入理解Nginx》第四章中有詳細說明了。

自然在checksecret命令中就不需要再讀取參數了(也沒有參數了,所以要注意這個命令中的命令類型要設置上NGX_CONF_NOARGS)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM