1. nginx添加自定義http模塊(簡單)
阿新 • • 發佈:2019-01-18
訪問 quest cmd return 頭部 true card char* 內存
步驟
1. 新建模塊目錄
2. 添加模塊配置文件
3. 編寫模塊源碼文件
4. 在主配置文件中配置訪問location
5. 編譯加入模塊文件
6. 測試
新建模塊目錄
mkdir /opt/nginx/ext/hello_world/
添加模塊配置文件
vim /opt/nginx/ext/hello_world/config # 添加如下內容 ngx_addon_name=ngx_http_hello_world_module HTTP_MODULES="$HTTP_MODULES ngx_http_hello_world_module" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_hello_world_module.c" CORE_LIBS="$CORE_LIBS -lpcre" # ngx_addon_name 表示模塊名稱 # HTTP_MODULES 表示定義HTTP_MODULES模塊,多個模塊以空格分開,為了不覆蓋之前的模塊,使用$HTTP_MODULES代表已經存在的 # NGX_ADDON_SRCS 代表模塊代碼路徑 # CORE_LIBS 代表模塊需要的庫文件
編寫模塊文件
文件直接放在模塊目錄下即可(vim /opt/nginx/ext/hello_world/ngx_http_hello_world_module.c)
定義HTTP模塊
static ngx_command_t ngx_http_hello_world_commands[] = { { ngx_string("hello_world"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | \ NGX_CONF_NOARGS, ngx_http_hello_world, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command }; // hello_world: 這個與nginx.conf中定義的location中的名字一致 // NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS: 指定出現的位置,可以出現在location {}中 // nginx_http_hello_world: 這個ngx_command_t中的set成員,當某塊位置出現hello_world時候,nginx將會啟動ngx_http_hello_world方法,所以需要定義該函數 static ngx_http_module_t ngx_http_hello_world_module_ctx = { NULL, /* preconfiguration */ NULL, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ NULL, /* create server configuration */ NULL, /* merge server configuration */ NULL, /* create location configuration */ NULL /* merge location configuration */ }; ngx_module_t ngx_http_hello_world_module = { NGX_MODULE_V1, &ngx_http_hello_world_module_ctx, ngx_http_hello_world_commands, NGX_HTTP_MODULE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NGX_MODULE_V1_PADDING }; // NGX_MODULE_V1 代表版本號 // ngx_http_hello_world_module_ctx 代表模塊上下文結構,HTTP框架要求,固定用法 // ngx_http_hello_world_commands 代表模塊的配置文件參數,這個在nginx.conf文件解析 // NGX_HTTP_MODULE 代表這是一個http模塊
定義模塊觸發函數
static char * ngx_http_hello_world(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_world_handler; return NGX_CONF_OK; } // ngx_http_conf_get_module_loc_conf: 這個函數會首先找到hello_world配置所屬的配置塊 // handler: http框架在處理用戶請求進行到NGX_HTTP_CONTENT_PHASE階段,如果請求的主機域名,URL和hello_world相匹配,那麽就調用這handler指向的方法ngx_http_hello_world_handler
編寫請求處理方法handler
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r) { ngx_int_t rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } ngx_str_t type = ngx_string("text/plain"); ngx_str_t response = ngx_string("Hello World"); r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = response.len; r->headers_out.content_type = type; rc = ngx_http_send_header(r);//發送頭部 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } ngx_buf_t *b; b = ngx_create_temp_buf(r->pool, response.len);//異步發送,要用堆內存空間 if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_memcpy(b->pos, response.data, response.len); b->last = b->pos + response.len; b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; return ngx_http_output_filter(r, &out);//向用戶發送響應包 }
完整的代碼匯總
#include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r); static char* ngx_http_hello_world(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_command_t ngx_http_hello_world_commands[] = { { ngx_string("hello_world"), NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS, ngx_http_hello_world, NGX_HTTP_LOC_CONF_OFFSET, 0, NULL }, ngx_null_command }; static ngx_http_module_t ngx_http_hello_world_module_ctx = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; ngx_module_t ngx_http_hello_world_module = { NGX_MODULE_V1, &ngx_http_hello_world_module_ctx, ngx_http_hello_world_commands, NGX_HTTP_MODULE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NGX_MODULE_V1_PADDING }; static char *ngx_http_hello_world(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_world_handler; return NGX_CONF_OK; } static ngx_int_t ngx_http_hello_world_handler(ngx_http_request_t *r) { ngx_int_t rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { return rc; } ngx_str_t type = ngx_string("text/plain"); ngx_str_t response = ngx_string("Hello World"); r->headers_out.status = NGX_HTTP_OK; r->headers_out.content_length_n = response.len; r->headers_out.content_type = type; rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } ngx_buf_t *b; b = ngx_create_temp_buf(r->pool, response.len); if (b == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_memcpy(b->pos, response.data, response.len); b->last = b->pos + response.len; b->last_buf = 1; ngx_chain_t out; out.buf = b; out.next = NULL; return ngx_http_output_filter(r, &out); }
在主配置文件中配置訪問location
vim /etc/nginx 添加 location / {hello_world}; server { ... location / { hello_world; } ... }
編譯加入模塊文件
./configure --add-module=/opt/nginx/ext/hello_world/ make && make install
測試
/usr/local/nginx/sbin/nginx curl http://localhost
1. nginx添加自定義http模塊(簡單)