从零手写实现 nginx-21-modules 模块
实现一个Nginx模块涉及多个步骤,包括模块初始化、配置解析、日志记录等。以下是一个简单的Nginx模块骨架,它可以作为开始手写模块的起点。
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
// 模块的 context 结构体
typedef struct {
ngx_str_t test_str;
} ngx_http_mytest_conf_t;
// 解析配置项的回调函数
static char *ngx_http_mytest(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_mytest_handler;
// 获取配置项参数
ngx_str_t *value = cf->args->elts;
ngx_http_mytest_conf_t *lcf = conf;
lcf->test_str = value[1];
return NGX_CONF_OK;
}
// 模块处理请求的回调函数
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r) {
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_HTTP_NOT_ALLOWED;
}
ngx_int_t rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {
return rc;
}
// 设置响应头
ngx_str_t *test_str = ...; // 从配置中获取字符串
ngx_table_elt_t *h = ngx_list_push(&r->headers_out.headers);
if (h == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
h->key = ngx_http_mytest_header_name;
h->value = *test_str;
h->hash = 1; // 计算hash值
// 发送响应
ngx_int_t status = NGX_HTTP_OK;
ngx_str_t response = ngx_http_mytest_response;
ngx_buf_t *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->memory = 1;
b->last_buf = 1;
r->headers_out.status = status;
r->headers_out.content_length_n = response.len;
r->headers_out.content_type_len = sizeof("text/plain") - 1;
ngx_str_set(&r->headers_out.content_type, "text/plain");
return ngx_http_send_header(r) == NGX_ERROR
? NGX_HTTP_INTERNAL_SERVER_ERROR
: ngx_http_output_filter(r, b);
}
// 模块的定义
ngx_module_t ngx_http_mytest_module = {
..., // 模块的各种方法
ngx_http_mytest_create_conf, // 创建配置结构体的方法
ngx_http_mytest_init_conf // 初始化配置结构体的方法
};
// 配置指令结构体
static ngx_command_t ngx_http_
评论已关闭