首先 看看完整的源码

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

static char *set(ngx_conf_t *, ngx_command_t *, void *);
static ngx_int_t handler(ngx_http_request_t *);

static ngx_command_t test_commands[] = {
    {
        ngx_string("hello_world"),
        NGX_HTTP_LOC_CONF | NGX_CONF_NOARGS,
        set,
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        NULL
    },
    ngx_null_command
};
//这里没有什么需要进行配置的之后在讲解
static ngx_http_module_t test_ctx = {
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

ngx_module_t ngx_http_test_module = {
    NGX_MODULE_V1,//定义module版本
    &test_ctx,//module context
    test_commands,//commands
    NGX_HTTP_MODULE,//定义是http_module
    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
    NGX_MODULE_V1_PADDING
};

static char *set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
    ngx_http_core_loc_conf_t *corecf;
    corecf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    corecf->handler = handler;
    return NGX_CONF_OK;
};

static ngx_int_t handler(ngx_http_request_t *req) {
    // 响应内容
    u_char html[1024] = "&lt;h1&gt;hello world, foorbar!!!&lt;/h1&gt;";
    //返回状态码
    req->headers_out.status = 200;
    int len = sizeof(html) - 1;
    //content_length
    req->headers_out.content_length_n = len;
    //content_type
    ngx_str_set(&req->headers_out.content_type, "text/html");
    //先发送header
    ngx_http_send_header(req);

    ngx_buf_t *b;
    b = ngx_pcalloc(req->pool, sizeof(ngx_buf_t));
    ngx_chain_t out;
    out.buf = b;
    out.next = NULL;
    b->pos = html;
    b->last = html + len;
    b->memory = 1;
    b->last_buf = 1;
    //发送http包体
    return ngx_http_output_filter(req, &out);
}

ngx_command_t解析

首先来解析ngx_command_t这个结构体

static ngx_command_t  ngx_http_mirror_commands[] = {
    { ngx_string("hello_world"), //定义名称
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,//定义改配置出现的位置
      set,//配置handler
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL }

第一行ngx_string("hello_world")这个定义了名称,只要配置文件中出现了该配置项,就能够启用该模块,比如下面这样的模式

location /hello_world {
      hello_world;
 }

第二行NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1定义了出现的位置 分别代表了可以出现在main{}、server{}和location{}。NGX_CONF_TAKE1:配置指令接受1个参数。

第三行set

static char *set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
    //配处理的handler
    ngx_http_core_loc_conf_t *corecf;
    corecf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    //这块是处理用户请求到NGX_HTTP_CONTENT_PHASE这个阶段的时候
    corecf->handler = handler;
    return NGX_CONF_OK;
};

下面是请求的各个处理阶段,咱们的hello_world模块是属于NGX_HTTP_CONTENT_PHASE处理阶段


typedef enum {
    //接受到头部的阶段
    NGX_HTTP_POST_READ_PHASE = 0,
    //在还没有查询到URL匹配的location前,这时rewrite重写URL也作为一个独立的HTTP阶段
    NGX_HTTP_SERVER_REWRITE_PHASE,
    //根据url寻找匹配的location,这个阶段通常由ngx_http_core_module模块实现,
    NGX_HTTP_FIND_CONFIG_PHASE,
    //这个是NGX_HTTP_FIND_CONFIG_PHASE之后的阶段,Location请求地址重写阶段
    NGX_HTTP_REWRITE_PHASE,
    //这一阶段是用于在rewrite重写URL后重写跳转到NGX_HTTP_FIND_CONFIG_PHASE的阶段
    NGX_HTTP_POST_REWRITE_PHASE,
    //http模块可以介入处理的阶段
    NGX_HTTP_PREACCESS_PHASE,
    //这个阶段用于让HTTP模块判断是否允许这个请求访问Nginx服务器
    NGX_HTTP_ACCESS_PHASE,
    //这个阶段将负责构造拒绝服务的用户响应
    NGX_HTTP_POST_ACCESS_PHASE,
    //content的预处理阶段
    NGX_HTTP_PRECONTENT_PHASE,
    //用于处理HTTP请求内容的阶段,
    NGX_HTTP_CONTENT_PHASE,
    //处理完请求后记录日志的阶段,
    NGX_HTTP_LOG_PHASE
} ngx_http_phases;

results matching ""

    No results matching ""