nginx模組開發

來源:互聯網
上載者:User

nginx模組開發

1. 配置-編譯-執行

./configure --add-module=ngx_module_echo/ --with-debug --with-cc-opt='-g'
make
make install
覆蓋 /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf

需預先安裝的類庫

yum -y install pcre-devel openssl openssl-devel

2. 讀request

http/ngx_http_request.h裡定義了ngx_http_request_s的格式,包括

typedef struct{    ngx_str_t                         request_line;    ngx_str_t                         uri;    ngx_str_t                         args;    ngx_str_t                         exten;    ngx_str_t                         unparsed_uri;    ngx_str_t                         method_name;    ngx_str_t                         http_protocol;     。。。。}ngx_http_request_s

其中ngx_str_t的格式為

typedef struct {    size_t      len;    u_char     *data;} ngx_str_t

在handler函數裡可讀出來。

3. 寫響應體

首先,模組需要先聲明buffer和鏈表:

ngx_buf_t    *b;ngx_chain_t   out;

其中 ngx_chain_t 為

struct ngx_chain_s {        ngx_buf_t    *buf;        ngx_chain_t  *next;};

其中ngx_buf_t為

struct ngx_buf_s {         u_char          *pos;         u_char          *last;         u_char          *start;         /* start of buffer */         u_char          *end;           /* end of buffer */            unsigned         memory:1;         unsigned         last_buf:1;         。。。。。。};

接著,需要給buffer分配空間,並將我們的響應資料指向它:

b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));    if (b == NULL) {        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,            "Failed to allocate response buffer.");        return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    b->pos = some_bytes; /* first position in memory of the data */    b->last = some_bytes + some_bytes_length; /* last position */    b->memory = 1; /* content is in read-only memory */    /* (i.e., filters should copy it rather than rewrite in place) */    b->last_buf = 1; /* there will be no more buffers in the request */

現在就可以把資料掛在鏈表上了:

    out.buf = b;
    out.next = NULL;

最後,我們發送這個響應體,傳回值是鏈表在一次調用後的狀態:(and return the status code of the output filter chain all in one go)

    return ngx_http_output_filter(r, &out);

static ngx_int_t ngx_cc_answer(ngx_http_request_t *r, char *output){ngx_buf_t*b;ngx_chain_tout;ngx_str_tmessage;// 設定返回內容message.data = (unsigned char*)output;message.len = strlen(output);// 設定返回格式r->headers_out.content_type_len = sizeof("text/html") - 1;r->headers_out.content_type.len = sizeof("text/html") - 1;r->headers_out.content_type.data = (u_char *) "text/html";r->headers_out.status = NGX_HTTP_OK;r->headers_out.content_length_n = message.len;// 設定返回bufb = ngx_pcalloc(r->pool , sizeof(ngx_buf_t));if (b == NULL){return NGX_ERROR;}b->pos = message.data;b->last = message.data + message.len;b->memory = 1;b->last_buf = 1;out.buf = b;out.next = NULL;// 調用訊息發送函數ngx_http_send_header(r);return ngx_http_output_filter(r, &out);}

4 編譯c++模組

./configure --add-module=ngx_module_cpp/ --with-debug --without-http_rewrite_module --with-ld-opt="-lstdc++" --with-cc-opt='-g'

標頭檔加extern "C"

ngx_http_core_loc_conf_t*等類型需加強制轉換

5. 讀變數

用nginx提供的架構有一個致命的缺點:若變數值中含有&符號,那麼&後的字元會被當做另一種變數處理,導致變數值錯誤。所以,該方法僅適用於變數值簡單,不包含&分隔字元的情況,其它情況還是自行解析r->args王道(見2)。

1)在nginx中添加要讀的變數, 如 set $type $arg_type

2)讀變數函數

首先在ngx_task_module_ctx中註冊

static ngx_http_module_t  ngx_task_module_ctx = {    NULL,                          /* preconfiguration */    ngx_http_task_module_init,           /* postconfiguration */    。。。}

接著實現:

// 從設定檔中讀取type定義ngx_int_t ngx_http_task_module_init(ngx_conf_t *cf){    printf("called:ngx_http_task_module_init\n");    // 讀type參數    if ((ngx_http_type_index = ngx_http_task_module_add_variable(cf, &ngx_http_type_value)) == NGX_ERROR)    {        return NGX_ERROR;    }    return NGX_OK;}static ngx_int_t ngx_http_task_module_variable_not_found(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data){    v->not_found = 1;    return NGX_OK;}static ngx_int_t ngx_http_task_module_add_variable(ngx_conf_t *cf, ngx_str_t *name){    ngx_http_variable_t *v;    v = ngx_http_add_variable(cf, name, NGX_HTTP_VAR_CHANGEABLE);    if (v == NULL) {        return NGX_ERROR;    }    v->get_handler = ngx_http_task_module_variable_not_found;    return ngx_http_get_variable_index(cf, name);}

3)加入讀變數邏輯

static ngx_int_t  ngx_http_type_index;static ngx_str_t  ngx_http_type_value = ngx_string("type");ngx_http_variable_value_t      *type_vv;

handler中:

//讀取URL裡面具體的type變數的值    type_vv = ngx_http_get_indexed_variable(r,ngx_http_type_index);    printf("%s\n", type_vv->data);

4)資料結構

typedef ngx_variable_value_t  ngx_http_variable_value_t;

typedef struct {    unsigned    len:28;    unsigned    valid:1;    unsigned    no_cacheable:1;    unsigned    not_found:1;    unsigned    escape:1;    u_char     *data;} ngx_variable_value_t;

注意len表示data的長度。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.