【Nginx源码】ngx_command_t学习

结构体定义:
// 指令结构体,用于定义nginx指令
// ngx_command_t (ngx_core.h)
struct ngx_command_s {
    //指令的名字
    ngx_str_t             name;

    //指令的类型,是NGX_CONF_XXX的组合,决定指令出现的位置、参数数量、类型等
    // NGX_HTTP_MAIN_CONF/NGX_HTTP_SRV_CONF/NGX_HTTP_LOC_CONF
    ngx_uint_t            type;

    // 指令解析函数,是函数指针
    // 预设有ngx_conf_set_flag_slot等,见本文件
    // cf:解析的环境结构体,重要的是cf->args,是指令字符串数组
    // cmd:该指令的结构体
    // conf当前的配置结构体,需转型后才能使用
    char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);

    // 专门给http/stream模块使用,决定存储在main/srv/loc的哪个层次
    // NGX_HTTP_MAIN_CONF_OFFSET/NGX_HTTP_SRV_CONF_OFFSET/NGX_HTTP_LOC_CONF_OFFSET
    // NGX_STREAM_MAIN_CONF_OFFSET
    // 其他类型的模块不使用,直接为0
    ngx_uint_t            conf;

    // 变量在conf结构体里的偏移量,可用offsetof得到
    // 主要用于nginx内置的命令解析函数,自己写命令解析函数可以置为0
    ngx_uint_t            offset;

    //解析后处理的数据
    void                 *post;
};

多态函数调用搜索关键字-ngx_conf_file.c:
rv = cmd->set(cf, cmd, conf);



看看这个:
static char *
ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_core_loc_conf_t *clcf = conf;

    char        *rv;
    ngx_conf_t   save;

    if (clcf->types == NULL) {
        clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
        if (clcf->types == NULL) {
            return NGX_CONF_ERROR;
        }
    }

    save = *cf;
    cf->handler = ngx_http_core_type;
    cf->handler_conf = conf;

    rv = ngx_conf_parse(cf, NULL);

    *cf = save;

    return rv;
}


char *
ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    char  *p = conf;

    ngx_str_t        *field, *value;
    ngx_conf_post_t  *post;

    field = (ngx_str_t *) (p + cmd->offset);

    if (field->data) {
        return "is duplicate";
    }

    value = cf->args->elts;

    *field = value[1];

    if (cmd->post) {
        post = cmd->post;
        return post->post_handler(cf, post, field);
    }

    return NGX_CONF_OK;
}

比较这两个set函数,ngx_http_core_types这个函数里将cf->handler赋值了,但是
ngx_conf_set_str_slot没有,所以在ngx_conf_parse中:
char *
ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
{
   for ( ;; ) {
        rc = ngx_conf_read_token(cf);
        // ...
        if (cf->handler) 
		{

            /*
             * the custom handler, i.e., that is used in the http's
             * "types { ... }" directive
             */

            if (rc == NGX_CONF_BLOCK_START) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"{\"");
                goto failed;
            }
            
            // 特殊的解析处理函数,可以自己定义{}的解析处理,比较自由
            // 例如 types {}、content_by_lua_block {}
            //printf("file = %s, line= %d, func =%s.\n",__FILE__,__LINE__,__func__);
            rv = (*cf->handler)(cf, NULL, cf->handler_conf);
			//printf("file = %s, line= %d, func =%s.\n",__FILE__,__LINE__,__func__);
            if (rv == NGX_CONF_OK) {
				//printf("file = %s, line= %d, func =%s.\n",__FILE__,__LINE__,__func__);
                continue;
            }

            if (rv == NGX_CONF_ERROR) {
                goto failed;
            }

            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", rv);

            goto failed;
        }
   }
}

再看一个例子,它的handler也会被赋值:
char *
ngx_http_lua_content_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf)
{
    char        *rv;
    ngx_conf_t   save;

    save = *cf;
    cf->handler = ngx_http_lua_content_by_lua;
    cf->handler_conf = conf;

    rv = ngx_http_lua_conf_lua_block_parse(cf, cmd);

    *cf = save;

    return rv;
}

cmdname = access_log.                  cmdtype = ce000800.       cmdsetfunc = ngx_http_log_set_log
cmdname = add_header.                  cmdtype = 4e00000c.       cmdsetfunc = ngx_http_headers_expires
cmdname = body_filter_by_lua_file.     cmdtype = 4e000002.       cmdsetfunc = ngx_http_lua_body_filter_by_lua
cmdname = client_body_buffer_size.     cmdtype = e000002.        cmdsetfunc = ngx_conf_set_size_slot
cmdname = client_body_temp_path.       cmdtype = e00001e.        cmdsetfunc = ngx_conf_set_path_slot
cmdname = client_max_body_size.        cmdtype = e000002.        cmdsetfunc = ngx_conf_set_off_slot
cmdname = default_type.                cmdtype = e000002.        cmdsetfunc = ngx_conf_set_str_slot
cmdname = error_log.                   cmdtype = e000800.        cmdsetfunc = ngx_error_log|ngx_http_core_error_log|ngx_mail_core_error_log|ngx_stream_core_error_log
cmdname = error_page.                  cmdtype = 4e001000.       cmdsetfunc = ngx_http_core_error_page
cmdname = events.                      cmdtype = 1000101.        cmdsetfunc = ngx_events_block
cmdname = gzip.                        cmdtype = 4e000200.       cmdsetfunc = ngx_conf_set_flag_slot
cmdname = gzip_comp_level.             cmdtype = e000002.        cmdsetfunc = ngx_conf_set_num_slot
cmdname = gzip_disable.                cmdtype = e000800.        cmdsetfunc = ngx_http_gzip_disable
cmdname = gzip_min_length.             cmdtype = e000002.        cmdsetfunc = ngx_conf_set_size_slot
cmdname = gzip_types.                  cmdtype = e000800.        cmdsetfunc = ngx_conf_set_size_slot
cmdname = gzip_vary.                   cmdtype = e000200.        cmdsetfunc = ngx_conf_set_flag_slot
cmdname = http.                        cmdtype = 1000101.        cmdsetfunc = ngx_http_block
cmdname = if.                          cmdtype = c000900.        cmdsetfunc = ngx_http_rewrite_if|
cmdname = include.                     cmdtype = ff000002.       cmdsetfunc = ngx_conf_include
cmdname = init_by_lua_file.            cmdtype = 2000002.        cmdsetfunc = ngx_http_lua_init_by_lua
cmdname = keepalive_timeout.           cmdtype = e000006.        cmdsetfunc = ngx_http_core_keepalive|ngx_conf_set_msec_slot
cmdname = large_client_header_buffers. cmdtype = 6000004.        cmdsetfunc = ngx_conf_set_bufs_slot
cmdname = listen.                      cmdtype = 4000800.        cmdsetfunc = ngx_http_core_listen|ngx_mail_core_listen|ngx_stream_core_listen
cmdname = location.                    cmdtype = c000106.        cmdsetfunc = ngx_http_core_location
cmdname = log_format.                  cmdtype = 2001000.        cmdsetfunc = ngx_http_log_set_format|ngx_stream_log_set_format
cmdname = lua_code_cache.              cmdtype = 4e000200.       cmdsetfunc = ngx_http_lua_code_cache
cmdname = lua_shared_dict.             cmdtype = 2000004.        cmdsetfunc = ngx_http_lua_shared_dict
cmdname = map.                         cmdtype = 2000104.        cmdsetfunc = ngx_http_map_block|ngx_stream_map_block
cmdname = multi_accept.                cmdtype = 2000200.        cmdsetfunc = ngx_conf_set_flag_slot
cmdname = proxy_buffering.             cmdtype = e000200.        cmdsetfunc = ngx_conf_set_flag_slot
cmdname = proxy_buffers.               cmdtype = e000004.        cmdsetfunc = ngx_conf_set_bufs_slot
cmdname = proxy_buffer_size.           cmdtype = e000002.        cmdsetfunc = ngx_conf_set_size_slot|ngx_conf_set_size_slot
cmdname = proxy_busy_buffers_size.     cmdtype = e000002.        cmdsetfunc = ngx_conf_set_size_slot
cmdname = proxy_cache_path.            cmdtype = 2001000.        cmdsetfunc = ngx_http_file_cache_set_slot
cmdname = proxy_connect_timeout.       cmdtype = e000002.        cmdsetfunc = ngx_conf_set_msec_slot|ngx_conf_set_msec_slot
cmdname = proxy_http_version.          cmdtype = e000002.        cmdsetfunc = ngx_conf_set_enum_slot
cmdname = proxy_pass.                  cmdtype = c8000002.       cmdsetfunc = ngx_http_proxy_pass|ngx_stream_proxy_pass
cmdname = proxy_read_timeout.          cmdtype = e000002.        cmdsetfunc = ngx_conf_set_msec_slot
cmdname = proxy_send_timeout.          cmdtype = e000002.        cmdsetfunc = ngx_conf_set_msec_slot
cmdname = proxy_set_header.            cmdtype = e000004.        cmdsetfunc = ngx_conf_set_keyval_slot
cmdname = proxy_temp_file_write_size.  cmdtype = e000002.        cmdsetfunc = ngx_conf_set_size_slot
cmdname = return.                      cmdtype = 6c000006.       cmdsetfunc = ngx_http_rewrite_return|ngx_stream_return
cmdname = rewrite_by_lua_file.         cmdtype = 4e000002.       cmdsetfunc = ngx_http_lua_rewrite_by_lua
cmdname = root.                        cmdtype = 4e000002.       cmdsetfunc = ngx_http_core_root
cmdname = sendfile.                    cmdtype = 4e000200.       cmdsetfunc = ngx_conf_set_flag_slot
cmdname = server.                      cmdtype = 10000800.       cmdsetfunc = ngx_http_core_server|ngx_http_upstream_server|ngx_mail_core_server|ngx_stream_core_server|ngx_stream_upstream_server
cmdname = server.                      cmdtype = 2000101.        cmdsetfunc = ngx_http_core_server|ngx_http_upstream_server|ngx_mail_core_server|ngx_stream_core_server|ngx_stream_upstream_server
cmdname = server_name.                 cmdtype = 4000800.        cmdsetfunc = ngx_http_core_server_name|ngx_conf_set_str_slot
cmdname = set.                         cmdtype = 6c000004.       cmdsetfunc = ngx_http_rewrite_set|ngx_stream_set
cmdname = ssl_certificate.             cmdtype = 6000002.        cmdsetfunc = ngx_conf_set_str_array_slot|ngx_conf_set_str_array_slot|ngx_conf_set_str_array_slot
cmdname = ssl_certificate_key.         cmdtype = 6000002.        cmdsetfunc = ngx_conf_set_str_array_slot|ngx_conf_set_str_array_slot|ngx_conf_set_str_array_slot
cmdname = ssl_ciphers.                 cmdtype = 6000002.        cmdsetfunc = ngx_conf_set_str_slot|ngx_conf_set_str_slot|ngx_conf_set_str_slot
cmdname = ssl_prefer_server_ciphers.   cmdtype = 6000200.        cmdsetfunc = ngx_conf_set_flag_slot|ngx_conf_set_flag_slot|ngx_conf_set_flag_slot
cmdname = ssl_session_cache.           cmdtype = 6000006.        cmdsetfunc = ngx_http_ssl_session_cache|ngx_mail_ssl_session_cache|ngx_stream_ssl_session_cache
cmdname = ssl_session_timeout.         cmdtype = 6000002.        cmdsetfunc = ngx_conf_set_sec_slot|ngx_conf_set_sec_slot|ngx_conf_set_sec_slot
cmdname = sub_filter_once.             cmdtype = e000200.        cmdsetfunc = ngx_conf_set_flag_slot
cmdname = subs_filter.                 cmdtype = e001000.        cmdsetfunc = ngx_http_subs_filter
cmdname = subs_filter_types.           cmdtype = e000800.        cmdsetfunc = ngx_http_types_slot
cmdname = types.                       cmdtype = e000101.        cmdsetfunc = ngx_http_core_types
cmdname = upstream.                    cmdtype = 2000102.        cmdsetfunc = ngx_http_upstream|ngx_stream_upstream
cmdname = use.                         cmdtype = 2000002.        cmdsetfunc = ngx_event_use
cmdname = user.                        cmdtype = 1010006.        cmdsetfunc = ngx_set_user
cmdname = user_login.                  cmdtype = 8000001.        cmdsetfunc = ngx_http_user_login
cmdname = worker_connections.          cmdtype = 2000002.        cmdsetfunc = ngx_event_connections
cmdname = worker_processes.            cmdtype = 1010002.        cmdsetfunc = ngx_set_worker_processes
cmdname = worker_rlimit_nofile.        cmdtype = 1010002.        cmdsetfunc = ngx_conf_set_num_slot

你可能感兴趣的:(ngx_command_t,nginx源码)