解析规则

  1. 精确匹配的路径 location = /{}

(exact_match = 1 )

  1. 抢占式前缀匹配的路径 location ^~ /{}

(noregex = 1)

  1. 命名路径,比如location @a {}

(named = 1)

  1. 普通前端匹配的路径,例如location / {}

  2. 无名路径,比如if {}或者limit_except {}生成的路径

noname = 1

正则路径 regex != NULL

解析之后格式

{
    "http":{
        "servers":[
            {
                "server_name":"www.didichuxing.com",
                "port":80,
                "locations":[
                    {
                        "location":"/index",
                        "upstream_name":"upstream_index_com",
                        "upstream_servers":"127.0.0.1:8000, 127.0.0.1:80001"
                    },
                    {
                        "location":"/home",
                        "upstream_name":"upstream_index_com",
                        "upstream_servers":"127.0.0.1:8000, 127.0.0.1:80001"
                    },
                    {
                        "location":"/test",
                        "upstream_name":"upstream_test_com",
                        "upstream_servers":"127.0.0.1:8000, 127.0.0.1:80001"
                    }
                ]
            },
            {
                "server_name":"www.udache.com",
                "port":80,
                "locations":[
                    {
                        "location":"^/orderby",
                        "upstream_name":"upstream_test_com",
                        "upstream_servers":"127.0.0.1:8000, 127.0.0.1:80001"
                    },
                    {
                        "location":"^/list",
                        "upstream_name":"upstream_test_com",
                        "upstream_servers":"127.0.0.1:8000, 127.0.0.1:80001"
                    }
                ]
            }
        ]
    }
}

核心源码

static ngx_str_t                    HTTP_KEY = "http"
static ngx_str_t                    SERVERS_KEY = "servers"
static ngx_str_t                    SERVER_NAME_KEY = "server_name";
static ngx_str_t                    SERVER_PORT_KEY = "server_port";
static ngx_str_t                    LOCATIONS_KEY = "locations";
static ngx_str_t                    LOCATION_KEY = "location";

static void
ngx_http_lua_conf_get_static_locations(yajl_gen g, ngx_http_location_tree_node_t *node)
{
    if ( node == NULL ) {
        return;
    }

    yajl_gen_string(g, (const unsigned char *) LOCATION_KEY, strlen(LOCATION_KEY));
    yajl_gen_string(g, (unsigned char *)node->name, node->len);


    if ( node->left ) {
        return ngx_http_lua_conf_get_static_locations(g, node->left);
    }

    if ( node->right ) {
        return ngx_http_lua_conf_get_static_locations(g, node->right);
    }

}
//获取正则locations
static void
ngx_http_lua_conf_get_regex_locations(yajl_gen g, ngx_http_core_loc_conf_t **clcfp)
{

    if ( clcfp ) {
        return;
    }

    for ( ; *clcfp; clcfp++) {

        yajl_gen_string(g, (const unsigned char *) LOCATION_KEY, strlen(LOCATION_KEY));
        yajl_gen_string(g, (unsigned char *)(*clcfp)->name.data , (*clcfp)->name.len);
    }

}
/*
{
    "http":{
        "servers":[
            {
                "server_name": [
                    "www.didichuxing.com"
                ],
                "port":80,
                "locations":[
                    "location":"/index",
                    "location":"/home"
                ]
            }
        ]
    }
}
*/

//获取servers,server_name,server_port,location对应关系
static int
ngx_http_lua_ngx_get_conf(lua_State *L)
{
    size_t                                      s, i, j, n;
    size_t                                      len;
    ngx_http_conf_addr_t                        *addr;
    ngx_http_conf_port_t                        *port;
    const unsigned char                         *buf;
    ngx_http_request_t                          *r;
    ngx_http_core_main_conf_t                   *cmcf;
    ngx_http_core_loc_conf_t                    *clcf;
    ngx_http_core_srv_conf_t                    **server;
    ngx_http_server_name_t                      *name;
    yajl_gen                                    g;
    yajl_gen_status                             status;


    r = ngx_http_lua_get_req(L);
    if (r == NULL) {
        return luaL_error(L, "no request object found");
    }

    g = yajl_gen_alloc(NULL);
    if ( g == NULL ) {
        return NGX_ERROR;
    }

    yajl_gen_config(g, yajl_gen_beautify, 0);

    yajl_gen_map_open(g);

    //http
    yajl_gen_string(g, (unsigned char *)HTTP_KEY, strlen(HTTP_KEY));


    yajl_gen_map_open(g);

    //servers
    yajl_gen_string(g, (unsigned char *)SERVERS_KEY, ngx_strlen(SERVERS_KEY));

    yajl_gen_array_open(g);


    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

    port = cmcf->ports->elts;
    for (s = 0; s < cmcf->ports->nelts; s++) {

        addr = port[s].addrs.elts;
        for (i = 0; i < port[s].addrs.nelts; i++) {

            server = addr[i].servers.elts;
            for (j = 0; j < addr[i].servers.nelts; j++) {

                yajl_gen_map_open(g);

                name = server[j]->server_names.elts;

                for (n = 0; n < server[j]->server_names.nelts; n++) {

                    //server_name
                    yajl_gen_string(g, (unsigned char *)SERVER_NAME_KEY, ngx_strlen(SERVER_NAME_KEY));
                    yajl_gen_string(g, (unsigned char *)name[n].name.data, name[n].name.len);

                    //server_port
                    yajl_gen_string(g, (unsigned char *) SERVER_PORT_KEY, strlen(SERVER_PORT_KEY));
                    yajl_gen_string(g, (unsigned char *) addr[i].opt.addr, ngx_strlen(addr[i].opt.addr));
                }

                clcf = server[j]->ctx->loc_conf[ngx_http_core_module.ctx_index];

                yajl_gen_string(g, (unsigned char *) LOCATIONS_KEY, ngx_strlen(LOCATIONS_KEY));

                yajl_gen_array_open(g);

                ngx_http_lua_conf_get_static_locations(g, clcf->static_locations);

                ngx_http_lua_conf_get_regex_locations(g, clcf->regex_locations);

                yajl_gen_array_close(g);

                yajl_gen_map_close(g);
            }

        }
    }

    yajl_gen_array_close(g);

    yajl_gen_map_close(g);

    yajl_gen_map_close(g);

    status = yajl_gen_get_buf(g, &buf, &len);
    if(status != yajl_gen_status_ok) {
        yajl_gen_free(g);
        lua_pushnil(L);

        return 1;
    }

    lua_pushlstring(L, (char *) buf, len);

    return 1;
}
//格式化后的结果
{
    "http":{
        "servers":[
            {
                "server_name":[
                    "localhost"
                ],
                "server_port":"0.0.0.0:8012",
                "locations":[
                    "/search"
                ]
            },
            {
                "server_name":[
                    "www.test.com",
                    "www.test1.com"
                ],
                "server_port":"0.0.0.0:80",
                "locations":[
                    "/test"
                ]
            },
            {
                "server_name":[
                    "www.baidu.com"
                ],
                "server_port":"0.0.0.0:80",
                "locations":[
                    "/didi/",
                    "/aaa",
                    "/baidu/",
                    "/cccc/"
                ]
            }
        ]
    }
}
测试配置


#nginx.conf

server {
listen 8012;
server_name localhost;

location /search {
content_by_lua_block {
local body = ngx.config.get_conf();
ngx.say(body);
}
}

}


upstream upstream_test_com {
server 111.13.101.208:80;
}

server {
listen 80;
server_name www.test.com www.test1.com;

location =/test {
proxy_pass http://upstream_test_com;
}
}
server {
listen 80;
server_name www.baidu.com;


location = /aaa {
proxy_pass http://111.13.101.208:80;
}

location ^~ /didi/ {
proxy_pass http://111.13.101.208:80;
}

location ~ /baidu/ {
proxy_pass http://111.13.101.208:80;
}

location ~* /cccc/ {
proxy_pass http://111.13.101.208:80;
}
}

results matching ""

    No results matching ""