nginx配置解析模块分析
2013-11-13 16:34
316 查看
nginx配置解析模块分析
nginx提供配置文件供用户方便的定义nginx的行为,通过修改配置项可以指定nginx进程工作模块,指定log的输出方式,指定如何处理用户请求等等。ngx_conf_module模块提供ngx_conf_parse函数在nginx启动过程中被调用来解析配置文件,它读取配置文件内容并将配置项交由指定的模块处理,如将http配置项交由ngx_http_module处理。配置文件通常使用include配置项从其它文件中加载配置,如nginx.conf文件中使用”include mime.types”配置项加载mime.types文件。当在配置文件中发现include配置项时就调用ngx_conf_module模块提供的ngx_conf_include函数来解析,它首先分析出include配置项指定的文件名,对每一个文件分别调用ngx_conf_parse函数来解析。
ngx_conf_parse模块主要做三件事,第一提供ngx_conf_parse函数在nginx启动时被调用来处理配置文件。第二解析include配置项。第三提供预设的配置项解析回调函数(ngx_conf_module提供了12个回调函数)。
include配置项
include file| mask
在当前配置文件中包含其它配置文件,file用于指定被包含的某一个文件名,mask用于支持包含多个文件,如:
include mime.types;
include vhosts/*.conf;
ngx_conf_include函数分析
ngx_conf_parse函数分析
nginx提供配置文件供用户方便的定义nginx的行为,通过修改配置项可以指定nginx进程工作模块,指定log的输出方式,指定如何处理用户请求等等。ngx_conf_module模块提供ngx_conf_parse函数在nginx启动过程中被调用来解析配置文件,它读取配置文件内容并将配置项交由指定的模块处理,如将http配置项交由ngx_http_module处理。配置文件通常使用include配置项从其它文件中加载配置,如nginx.conf文件中使用”include mime.types”配置项加载mime.types文件。当在配置文件中发现include配置项时就调用ngx_conf_module模块提供的ngx_conf_include函数来解析,它首先分析出include配置项指定的文件名,对每一个文件分别调用ngx_conf_parse函数来解析。
ngx_conf_parse模块主要做三件事,第一提供ngx_conf_parse函数在nginx启动时被调用来处理配置文件。第二解析include配置项。第三提供预设的配置项解析回调函数(ngx_conf_module提供了12个回调函数)。
include配置项
include file| mask
在当前配置文件中包含其它配置文件,file用于指定被包含的某一个文件名,mask用于支持包含多个文件,如:
include mime.types;
include vhosts/*.conf;
ngx_conf_include函数分析
/* *配置文件中找到include配置项时该函数被调用 */ char * ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; ngx_int_t n; ngx_str_t *value, file, name; ngx_glob_t gl; value = cf->args->elts; file = value[1]; ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); /***判断文件路径,当include配置项指定的文件名带绝对路径时不做任何处理, 否则默认在nginx启动时指定的配置文件存放路径中查找该文件***/ if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) { return NGX_CONF_ERROR; } /***当文件名中包含"*?[" 字符时表示include配置项需包含多个文件***/ if (strpbrk((char *) file.data, "*?[") == NULL) { ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); return ngx_conf_parse(cf, &file); } ngx_memzero(&gl, sizeof(ngx_glob_t)); gl.pattern = file.data; gl.log = cf->log; gl.test = 1; /***调用glob函数将查找所有匹配模式的文件名***/ if (ngx_open_glob(&gl) != NGX_OK) { ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, ngx_open_glob_n " \"%s\" failed", file.data); return NGX_CONF_ERROR; } rv = NGX_CONF_OK; for ( ;; ) { /***获取匹配到的文件名***/ n = ngx_read_glob(&gl, &name); if (n != NGX_OK) { break; } file.len = name.len++; file.data = ngx_pstrdup(cf->pool, &name); ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); /***调用ngx_conf_parse函数解析该文件***/ rv = ngx_conf_parse(cf, &file); if (rv != NGX_CONF_OK) { break; } } /***释放glob_t对象***/ ngx_close_glob(&gl); return rv; }
ngx_conf_parse函数分析
/* * ngx_conf_parse函数在如下三种情况下被调用: * 1、nginx启动过程中。 * 2、解析带{}的配置项时。 * 3、解析include 配置项时。 */ char * ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { char *rv; ngx_fd_t fd; ngx_int_t rc; ngx_buf_t buf; ngx_conf_file_t *prev, conf_file; enum { parse_file = 0, parse_block, parse_param } type; #if (NGX_SUPPRESS_WARN) fd = NGX_INVALID_FILE; prev = NULL; #endif /***当filename不为空时表示将要打开一个未被解析的配置文件进行解析***/ if (filename) { /* open configuration file */ fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); if (fd == NGX_INVALID_FILE) { ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, ngx_open_file_n " \"%s\" failed", filename->data); return NGX_CONF_ERROR; } prev = cf->conf_file; cf->conf_file = &conf_file; if (ngx_fd_info(fd, &cf->conf_file->file.info) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, ngx_fd_info_n " \"%s\" failed", filename->data); } /***存放配置文件内容的buf***/ cf->conf_file->buffer = &buf; buf.start = ngx_alloc(NGX_CONF_BUFFER, cf->log); if (buf.start == NULL) { goto failed; } buf.pos = buf.start; buf.last = buf.start; buf.end = buf.last + NGX_CONF_BUFFER; buf.temporary = 1; cf->conf_file->file.fd = fd; cf->conf_file->file.name.len = filename->len; cf->conf_file->file.name.data = filename->data; cf->conf_file->file.offset = 0; cf->conf_file->file.log = cf->log; cf->conf_file->line = 1; /***打开一个新配置文件时,按行解析该文件中的配置项***/ type = parse_file; } else if (cf->conf_file->file.fd != NGX_INVALID_FILE) { /***在遇到带{}的配置项时,filename参数常为空,file.fd 描述符为该配置项所在文件被打开时的描述符***/ type = parse_block; } else { type = parse_param; } for ( ;; ) { /***解析配置项,每找到一个配置项或者出错时就返回***/ rc = ngx_conf_read_token(cf); /* * ngx_conf_read_token() may return * * NGX_ERROR there is error * NGX_OK the token terminated by ";" was found * NGX_CONF_BLOCK_START the token terminated by "{" was found * NGX_CONF_BLOCK_DONE the "}" was found * NGX_CONF_FILE_DONE the configuration file is done */ if (rc == NGX_ERROR) { goto done; } if (rc == NGX_CONF_BLOCK_DONE) { if (type != parse_block) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"}\""); goto failed; } goto done; } if (rc == NGX_CONF_FILE_DONE) { if (type == parse_block) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected end of file, expecting \"}\""); goto failed; } goto done; } if (rc == NGX_CONF_BLOCK_START) { if (type == parse_param) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "block directives are not supported " "in -g option"); goto failed; } } /* rc == NGX_OK || rc == NGX_CONF_BLOCK_START */ 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; } /***已找到一个有效的配置项,调用用户指定的回调函数***/ rv = (*cf->handler)(cf, NULL, cf->handler_conf); if (rv == NGX_CONF_OK) { continue; } if (rv == NGX_CONF_ERROR) { goto failed; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, rv); goto failed; } /***已找到一个有效的配置项,调用ngx_conf_handler函数查找该由那个模块来解析***/ rc = ngx_conf_handler(cf, rc); if (rc == NGX_ERROR) { goto failed; } } failed: rc = NGX_ERROR; done: if (filename) { if (cf->conf_file->buffer->start) { ngx_free(cf->conf_file->buffer->start); } if (ngx_close_file(fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, ngx_close_file_n " %s failed", filename->data); return NGX_CONF_ERROR; } cf->conf_file = prev; } if (rc == NGX_ERROR) { return NGX_CONF_ERROR; } return NGX_CONF_OK; }
相关文章推荐
- Nginx 源码分析-- 模块module 解析执行 nginx.conf 配置文件流程分析 二
- Nginx 源码分析-- 模块module 解析执行 nginx.conf 配置文件流程分析 一
- Nginx情景分析之配置文件解析
- nginx源代码分析--nginx模块解析
- [nginx源码分析]配置解析1
- nginx源码分析--nginx模块解析
- 配置nginx图片服务器之模块分析
- Nginx源码分析 - Event事件篇 - Event模块和配置的初始化
- Nginx源码分析 - 主流程篇 - 解析配置文件
- Nginx源码解析- http模块分析
- nginx http模块中配置的实现和解析---1
- FastDFS-Nginx扩展模块源码分析 -- mod_fastdfs原理解析
- [nginx源码分析]配置解析(http作用域)
- nginx http_core模块 配置文件解析 2
- Nginx源码解析- http模块分析
- Nginx 模块自主开发六:源码剖析配置文件解析过程
- [nginx源码分析]配置解析(server作用域)
- nginx 源码分析 1 - 配置解析
- Nginx模块的配置与解析
- [nginx源码分析]nginx handler 模块解析