1. 程式人生 > 其它 >02_nginx開發自己的http服務

02_nginx開發自己的http服務

技術標籤:nginx

02_nginx開發自己的http服務

1. 下載原始碼

2. 新增檔案

在原始碼目錄下新建extends\ngx_http_hello_module目錄,在目錄下新建configngx_http_hello_module.c

兩個資料夾
目錄結構如下:
config檔案路徑

3. 配置config

此處第三方模組的路徑在配置時候需要我們手動新增,./configure --add-module=

#模組名稱
ngx_addon_name=ngx_http_hello_module

#HTTP_MODULES表示定義HTTP_MODULES模組
HTTP_MODULES="$HTTP_MODULES ngx_http_hello_module"

#NGX_ADDON_SRCS 代表程式碼路徑
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_module.c"

4. 補充ngx_http_hello_module.c

4.1 新增標頭檔案

#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_config.h>

4.2 定義HTTP模組

/* 
     定義HTTP模組
*/
static ngx_command_t ngx_http_hello_commands[]={
     {     
          ngx_string("hello"),                  //http服務模組名,這裡需要和nginx.conf中一致
          NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,
          ngx_http_hello,                       //hello模組的響應觸發函式
          NGX_HTTP_LOC_CONF_OFFSET,
          0,
          NULL
     },
     ngx_null_command
};

4.3 定義模組上下文資訊

/* The module context. */
static ngx_http_module_t ngx_http_hello_module_ctx = {
     NULL,                    /* 預配置 */
     NULL,                    /* 後配置 */
     NULL,                    /* 建立主配置 */
     NULL,                    /* 初始化主配置 */
     NULL,                    /* 建立服務配置 */
     NULL,                    /* 合併服務配置 */
     NULL,                    /* 建立本地配置 */
     NULL,                    /* 合併本地配置 */
};

4.4 模組定義

ngx_module_t ngx_http_hello_module={
     NGX_MODULE_V1,
     &ngx_http_hello_module_ctx,    
     ngx_http_hello_commands,
     NGX_HTTP_MODULE,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NGX_MODULE_V1_PADDING
};

4.5 定義模組觸發函式

/*
     定義模組觸發函式
*/
static char* ngx_http_hello(ngx_conf_t *cf,ngx_command_t *cmd,void *conf)
{
     ngx_http_core_loc_conf_t *clcf;
     clcf = ngx_http_conf_get_module_loc_conf(cf,ngx_http_core_module);
     clcf->handler = ngx_http_hello_handler;                    //此處的ngx_http_hello_handler()是真正的處理函式
     return NGX_CONF_OK;
}

4.6 請求處理handler

/*
     請求處理方法handler
*/
static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r)
{
    ngx_buf_t *b;
    ngx_chain_t out;
    
    /*******************************設定報文內容************************/
    ngx_str_t response;
    response.data = (u_char*) "OK";
    response.len = 3;
    //為b分配空間
    b = ngx_create_temp_buf(r->pool, response.len);
    //將Hello World拷貝到ngx_buf_t指向的記憶體中
    ngx_memcpy(b->pos, response.data, response.len);
    //注意,一定要設定好last指標
    b->last = b->pos + response.len;
    //宣告這是最後一塊緩衝區
    b->last_buf = 1;

    /* 插入緩衝鏈。 */
     out.buf = b;
     out.next = NULL; /* just one buffer */

     /*********************************修改報文頭相關資訊*****************/
     /* 設定內容型別標題. */
     r->headers_out.content_type.len = sizeof("text/plain") - 1;
     r->headers_out.content_type.data = (u_char *)"text/plain";
     /* 傳送回覆的標題. */
     r->headers_out.status = NGX_HTTP_OK; /* 200 status code */
     /* 獲取正文的內容長度. */
     r->headers_out.content_length_n = response.len - 1;

     /********************************傳送報文*************************/
     //傳送報文頭部
     ngx_http_send_header(r); 

     //傳送報文內容:ngx_http_output_filter()是在連線r中傳送out;
     ngx_http_finalize_request(r, ngx_http_output_filter(r, &out));
}

4.7 大作業

#include <ngx_core.h>
#include <ngx_http.h>
#include <ngx_config.h>

static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r);
static char* ngx_http_hello(ngx_conf_t *cf,ngx_command_t *cmd,void *conf);



/* 
     定義HTTP模組
*/
static ngx_command_t ngx_http_hello_commands[]={
     {     
          ngx_string("hello"),
          NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_NOARGS,
          ngx_http_hello,
          NGX_HTTP_LOC_CONF_OFFSET,
          0,
          NULL
     },
     ngx_null_command
};

static ngx_http_module_t ngx_http_hello_module_ctx = {
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
};

ngx_module_t ngx_http_hello_module={
     NGX_MODULE_V1,
     &ngx_http_hello_module_ctx,
     ngx_http_hello_commands,
     NGX_HTTP_MODULE,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NULL,
     NGX_MODULE_V1_PADDING
};


/*
     定義模組觸發函式
*/
static char* ngx_http_hello(ngx_conf_t *cf,ngx_command_t *cmd,void *conf)
{
     ngx_http_core_loc_conf_t *clcf;
     clcf = ngx_http_conf_get_module_loc_conf(cf,ngx_http_core_module);
     clcf->handler = ngx_http_hello_handler;
     return NGX_CONF_OK;
}

static ngx_int_t ngx_http_hello_handler(ngx_http_request_t *r)
{
    ngx_buf_t *b;
    ngx_chain_t out;
    
    /*******************************設定報文內容************************/
    ngx_str_t response;
    response.data = (u_char*) "OK";
    response.len = 3;
    //為b分配空間
    b = ngx_create_temp_buf(r->pool, response.len);
    //將Hello World拷貝到ngx_buf_t指向的記憶體中
    ngx_memcpy(b->pos, response.data, response.len);
    //注意,一定要設定好last指標
    b->last = b->pos + response.len;
    //宣告這是最後一塊緩衝區
    b->last_buf = 1;

    /* 插入緩衝鏈。 */
     out.buf = b;
     out.next = NULL; /* just one buffer */

     /*********************************修改報文頭相關資訊*****************/
     /* 設定內容型別標題. */
     r->headers_out.content_type.len = sizeof("text/plain") - 1;
     r->headers_out.content_type.data = (u_char *)"text/plain";
     /* 傳送回覆的標題. */
     r->headers_out.status = NGX_HTTP_OK; /* 200 status code */
     /* 獲取正文的內容長度. */
     r->headers_out.content_length_n = response.len - 1;

     /********************************傳送報文*************************/
     //傳送報文頭部
     ngx_http_send_header(r); 

     //傳送報文內容:ngx_http_output_filter()是在連線r中傳送out;
     ngx_http_finalize_request(r, ngx_http_output_filter(r, &out));
}

5. 配置nginx.conf

在server模組中新增或者修改

location /hello{
    hello;
}

6.配置、編譯、執行

6.1 配置

在原始碼的根目錄下執行,此處路徑就為configngx_http_hello_module.c的目錄

./configure --add-module=/home/tianyiyi/nginx/nginx-1.19.6/extends/ngx_http_hello_module

6.2 編譯

make && make install

6.3 執行

/usr/local/nginx/sbin/nginx