Nginx 소스 코드 분석 - 주류 프로 세 스 - 프로필 분석
앞의 글 에서 우 리 는 Nginx 의 모듈 화 를 소개 했다.Nginx 의 기능 모듈 은 모두 cycle - > modules 모듈 을 통 해 관리 된다.모든 모듈 에는 자신의 프로필 이 있 습 니 다.
Nginx 프로필 nginx. conf
1. Nginx 의 프로필 은 줄 마다 명령 입 니 다.
2. 가장 바깥쪽 이 핵심 모듈 의 설정 매개 변수;내부 에 포 함 된 각 키 모듈 의 설정 입 니 다.
3. 이벤트 {} 이벤트 모듈
4. http {} 은 HTTP 모듈
5. http 모듈 에 다 층 끼 워 넣 기
6. 다 층 끼 워 넣 기 는 후속 이벤트 모듈 에서 소개 합 니 다.최상 위 코어 모듈 의 해석 만 소개 합 니 다.설정 한 계층 구 조 는 다음 그림 과 같 습 니 다:
Main CODE
/ \
Events Http
/ \ / \
epoll kqueue Server Server
/ \ \
Location Location Location
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
데이터 구조 논리 관계 도
관련 데이터 구조
ngx_cycle_s 의 confctx 와 modules
cycle->conf_ctx: 파일 상하 문 그룹 을 설정 합 니 다.각 모듈 의 프로필 데이터 구조의 포인터 주 소 는 모듈 의 index 색인 에 따라 cycle - > conf 에 놓 입 니 다.ctx 배열 중.
cycle - > modules: 모듈 배열.모듈 도 모듈 의 색인 index 에 따라 cycle - > modules 배열 에 놓 습 니 다.구체 적 으로 는 에서 ngx 를 참고 할 수 있다.cycle_modules 방법.
/**
* Nginx cycle
*/
struct ngx_cycle_s {
void ****conf_ctx; /* , */
ngx_pool_t *pool; /* */
...
ngx_module_t **modules; /* */
ngx_uint_t modules_n; /* */
ngx_uint_t modules_used; /* unsigned modules_used:1; */
...
};
ngx_module_s 의 index 와 commands
index: 모듈 의 색인 값 입 니 다.
commands: 모듈 이 지원 하 는 명령 집합 입 니 다.각 모듈 의 프로필 데이터 구조 에 설정 정 보 를 설정 하 는 데 사 용 됩 니 다 (예 를 들 어 핵심 모듈 의 ngx core conf t).
/**
*
*/
struct ngx_module_s {
ngx_uint_t ctx_index;
ngx_uint_t index; /* */
char *name; /* */
...
void *ctx; /* */
ngx_command_t *commands; /* */
ngx_uint_t type; /* */
...
};
ngx_command_s 명령 집합 구조
set: 반전 함수 입 니 다.최종 값 을 설정 할 때 set 의 반전 함 수 를 호출 합 니 다.
/**
*
*/
struct ngx_command_s {
ngx_str_t name; /* */
ngx_uint_t type; /* */
char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); /* set */
ngx_uint_t conf;
ngx_uint_t offset; /* , */
void *post; /* ; NULL*/
};
핵심 모듈 의 정의
위의 데이터 구조 에서 우 리 는 모든 모듈 이 하나의 모듈 의 데이터 구조 ngx 를 정의 해 야 한 다 는 것 을 알 고 있다.module_s. 주로 각 모듈 의 구체 적 인 정 보 를 관리 하 는 데 사용 된다.각 모듈 마다 ngx 를 정의 합 니 다.command_t 배열 은 해석 해 야 할 명령 집합 을 저장 하 는 규칙 입 니 다.
최종 프로필 정 보 는 각 모듈 의 설정 구조 가 다 르 기 때문에 cycle - > confctx 는 각 모듈 설정 파일 데이터 구조의 포인터 주소 만 저장 합 니 다.
핵심 모듈 은 nginx. c 의 파일 헤더 에 있 습 니 다.
핵심 모듈
/**
* ngx_command_t
*/
static ngx_command_t ngx_core_commands[] = {
{ ngx_string("daemon"), /* */
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, /* */
ngx_conf_set_flag_slot, /* */
0,
offsetof(ngx_core_conf_t, daemon), /* ; , ngx_core_module_create_conf*/
NULL },
{ ngx_string("master_process"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
0,
offsetof(ngx_core_conf_t, master),
NULL },
{ ngx_string("timer_resolution"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
0,
offsetof(ngx_core_conf_t, timer_resolution),
NULL },
{ ngx_string("pid"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
0,
offsetof(ngx_core_conf_t, pid),
NULL },
{ ngx_string("lock_file"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
0,
offsetof(ngx_core_conf_t, lock_file),
NULL },
{ ngx_string("worker_processes"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_set_worker_processes,
0,
0,
NULL },
{ ngx_string("debug_points"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_enum_slot,
0,
offsetof(ngx_core_conf_t, debug_points),
&ngx_debug_points },
{ ngx_string("user"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE12,
ngx_set_user,
0,
0,
NULL },
{ ngx_string("worker_priority"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_set_priority,
0,
0,
NULL },
{ ngx_string("worker_cpu_affinity"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_1MORE,
ngx_set_cpu_affinity,
0,
0,
NULL },
{ ngx_string("worker_rlimit_nofile"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_num_slot,
0,
offsetof(ngx_core_conf_t, rlimit_nofile),
NULL },
{ ngx_string("worker_rlimit_core"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_off_slot,
0,
offsetof(ngx_core_conf_t, rlimit_core),
NULL },
{ ngx_string("working_directory"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
0,
offsetof(ngx_core_conf_t, working_directory),
NULL },
{ ngx_string("env"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_set_env,
0,
0,
NULL },
{ ngx_string("load_module"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_load_module,
0,
0,
NULL },
ngx_null_command
};
/**
*
* ngx_core_module_create_conf
* ngx_core_module_init_conf
*/
static ngx_core_module_t ngx_core_module_ctx = {
ngx_string("core"),
ngx_core_module_create_conf,
ngx_core_module_init_conf
};
/**
*
*/
ngx_module_t ngx_core_module = {
NGX_MODULE_V1,
&ngx_core_module_ctx, /* module context */
ngx_core_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
설명:
1. ngx_core_module 핵심 모듈.핵심 모듈 의 정 보 를 주로 관리 합 니 다.
2. ngx_core_module_ctx 핵심 모듈 의 상하 문.각 모듈 의 상하 문 이 다 르 기 때문에 모듈 구조 에서 하나의 void 지침 형식 만 주 고 서로 다른 데이터 구 조 를 가리 킬 수 있다.핵심 모듈 의 ngxcore_module_ctx 는 주로 ngx 를 정의 합 니 다.core_module_create_conf 와 ngxcore_module_init_conf 리 셋 함수 (설정 파일 생 성 및 초기 화)
3. ngx_core_commands 핵심 모듈 이 정의 하 는 명령 집합 입 니 다.nginx. conf 의 명령 이 간소화 되면 이 명령 집합 을 통 해 핵심 모듈 의 명령 을 핵심 모듈 의 설정 파일 데이터 구조 에 하나씩 할당 합 니 다.
핵심 모듈 의 구성 구조 ngxcore_conf_t
핵심 모듈 의 구성 구조 ngxcore_conf_t。ngx_core_conf_t 의 포인터 주 소 는 모듈 의 index 색인 에 따라 cycle - > conf 에 놓 습 니 다.ctx 배열 중.
ngx_core_conf_t 구조의 생 성과 초기 화, ngxcore_module_create_conf 와 ngxcore_module_init_conf 방법.
/**
*
* nginx.conf
* #user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
*/
typedef struct {
ngx_flag_t daemon;
ngx_flag_t master;
ngx_msec_t timer_resolution;
ngx_int_t worker_processes;
ngx_int_t debug_points;
ngx_int_t rlimit_nofile;
off_t rlimit_core;
int priority;
ngx_uint_t cpu_affinity_auto;
ngx_uint_t cpu_affinity_n;
ngx_cpuset_t *cpu_affinity;
char *username;
ngx_uid_t user;
ngx_gid_t group;
ngx_str_t working_directory;
ngx_str_t lock_file;
ngx_str_t pid;
ngx_str_t oldpid;
ngx_array_t env;
char **environment;
} ngx_core_conf_t;
구체 적 해석 절차
우리 쪽 에 서 는 주로 핵심 모듈 설정 정보의 해석 을 설명 합 니 다.핵심 모듈 의 분석 프로 세 스 에 대한 이 해 를 통 해 전체 Nginx 의 모듈 관리 와 설정 관리 프로 세 스 를 이해 하 는 데 도움 을 줄 수 있 습 니 다.HTTP 등 모듈 의 프로필 분석 은 더욱 복잡 하지만 기본 원 리 는 일치 합 니 다.
1. 핵심 모듈 설정 파일 데이터 구조 ngx 만 들 기core_conf_t
ngx_init_cycle 전역 변수 초기 화 에 서 는 Nginx 의 핵심 모듈 설정 정보 가 초기 화 됩 니 다.핵심 모듈 의 설정 매개 변 수 는 nginx. conf 파일 의 맨 위 에 있 는 매개 변수 설정 입 니 다.
다음 코드 는 모듈 배열 을 옮 겨 다 니 며 핵심 모듈 이 라면 핵심 모듈 의 컨 텍스트 cycle - > modules [i] - > ctx 를 얻 을 수 있 습 니 다. 핵심 모듈 컨 텍스트 는 사용자 정의 데이터 구조 ngx 입 니 다.core_module_ctx, 설정 파일 이 만 든 리 셋 함수 ngx 가 포함 되 어 있 습 니 다.core_module_create_conf
PS: 여 기 는 그냥 맞 춤 형 NGXCORE_MODULE 은 프로필 을 만 들 고 프로필 을 초기 화 합 니 다.
/*
*
* nginx.c ngx_core_module_create_conf
* init_conf, :ngx_event_core_module_ctx ngx_event_core_create_conf
* */
for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->type != NGX_CORE_MODULE) {
continue;
}
module = cycle->modules[i]->ctx;
if (module->create_conf) {
rv = module->create_conf(cycle); // ,
if (rv == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
cycle->conf_ctx[cycle->modules[i]->index] = rv; //
}
}
2. 임시 ngx 만 들 기conf_구조
ngx_conf_s 는 분석 해 야 할 프로필, 분석 해 야 할 모듈 형식 과 명령 집합 형식의 정 보 를 정의 합 니 다.보조 분석 프로필.
/* */
ngx_memzero(&conf, sizeof(ngx_conf_t));
/* STUB: init array ? */
conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
if (conf.args == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
/* , ;conf */
conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
if (conf.temp_pool == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
conf.ctx = cycle->conf_ctx;
conf.cycle = cycle;
conf.pool = pool;
conf.log = log;
conf.module_type = NGX_CORE_MODULE; /* */
conf.cmd_type = NGX_MAIN_CONF; /* */
3. 해석 설정 함수 ngx 호출conf_param 과 ngxconf_parse
1. ngx_conf_param: 명령 행 의 핵심 모듈 설정 파 라미 터 를 분석 합 니 다. 예 를 들 어 nginx - t - c / usr / local / nginx / conf / nginx. conf 2. ngxconf_parse: 설정 파일 / usr / local / nginx / conf / nginx. conf 정 보 를 분석 합 니 다.
3. ngx_conf_param: 최종 호출 ngxconf_parse
/* ; :nginx -t -c /usr/local/nginx/conf/nginx.conf */
if (ngx_conf_param(&conf) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
/* /usr/local/nginx/conf/nginx.conf */
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
4. 프로필 핵심 해석 함수 ngxconf_parse
ngx_conf_parse 는 명령 의 설정 정보 와 파일 의 설정 정 보 를 분석 합 니 다.
주요 작업 은 줄 에 따라 설정 파일 을 읽 고 token 배열 로 해석 하 며 token 배열 을 모듈 comend 명령 집합 과 일치 하 게 설정 하 는 것 입 니 다.
그 중에서 비교적 중요 한 함수:
1. ngx_conf_read_token 은 줄 에 따라 설정 파일 을 읽 고 명령 을 token 배열 cf - > args 로 해석 합 니 다.
2. ngx_conf_handler 는 명령 token 배열 을 모듈 명령 집합 과 일치 시 키 고 모듈 설정 파일 데이터 구조 에 설정 합 니 다.
/**
*
* :
*/
char *
ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename)
{
...
/* : /usr/local/nginx/conf/nginx.conf */
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, 4096 */
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 */
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) {
/**
* :events { worker_connections 1024; }
*/
type = parse_block;
} else {
type = parse_param;
}
for ( ;; ) {
/* token; , */
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;
}
/* , 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;
}
/* , 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 */
/* NGX_CONF_BLOCK_START NGX_OK*/
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;
}
/* ; */
rc = ngx_conf_handler(cf, rc);
if (rc == NGX_ERROR) {
goto failed;
}
}
failed:
...
return NGX_CONF_OK;
}
5. token 해석 명령 ngxconf_read_token
ngx_conf_read_token 은 주로 설정 파일 을 단어 배열 로 분해 합 니 다.예 를 들 어 설정 파일 에서 '빈 칸' 을 만나면 구분자, ';' 는 끝 문자 입 니 다.
모든 배열 은 명령 어 를 설정 하 는 것 입 니 다.배열 은 cf - > args 배열 에 놓 입 니 다.
nginx. conf 설정 파일 은 다음 과 같 습 니 다.
user nfsnobody nfsnobody;
worker_processes 8;
error_log /usr/local/nginx-1.4.7/nginx_error.log crit;
pid /usr/local/nginx-1.4.7/nginx.pid;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 65535;
events
{
use epoll;
worker_connections 65535;}
다음 형식 으로 해석:# :
user
nfsnobody
nfsnobody
worker_processes
8
error_log
/usr/local/nginx-1.4.7/nginx_error.log
crit
pid
/usr/local/nginx-1.4.7/nginx.pid
worker_rlimit_nofile
65535
events
구체 적 인 논리 실현:/**
*
* cf->args {} ;
* :
* user nfsnobody nfsnobody;
* worker_processes 8;
* error_log /usr/local/nginx-1.4.7/nginx_error.log crit;
* pid /usr/local/nginx-1.4.7/nginx.pid;
* #Specifies the value for maximum file descriptors that can be opened by this process.
* worker_rlimit_nofile 65535;
* events
* {
* use epoll;
* worker_connections 65535;}
*
* :
* user
* nfsnobody
* nfsnobody
* worker_processes
* 8
* error_log
* /usr/local/nginx-1.4.7/nginx_error.log
* crit
* pid
* /usr/local/nginx-1.4.7/nginx.pid
* worker_rlimit_nofile
* 65535
* events
*
*/
static ngx_int_t
ngx_conf_read_token(ngx_conf_t *cf)
{
u_char *start, ch, *src, *dst;
off_t file_size;
size_t len;
ssize_t n, size;
ngx_uint_t found, need_space, last_space, sharp_comment, variable;
ngx_uint_t quoted, s_quoted, d_quoted, start_line;
ngx_str_t *word;
ngx_buf_t *b, *dump;
found = 0; // token
need_space = 0;
last_space = 1; // , token
sharp_comment = 0; // #
variable = 0; // $
quoted = 0; // ,
s_quoted = 0; // , ,
d_quoted = 0; // , ,
cf->args->nelts = 0;
b = cf->conf_file->buffer; //buffer 4096
dump = cf->conf_file->dump;
start = b->pos;
start_line = cf->conf_file->line;
file_size = ngx_file_size(&cf->conf_file->file.info);
for ( ;; ) {
/* buf , , , */
if (b->pos >= b->last) {
/* , NGX_CONF_FILE_DONE */
if (cf->conf_file->file.offset >= file_size) {
if (cf->args->nelts > 0 || !last_space) {
if (cf->conf_file->file.fd == NGX_INVALID_FILE) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"unexpected end of parameter, "
"expecting \";\"");
return NGX_ERROR;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"unexpected end of file, "
"expecting \";\" or \"}\"");
return NGX_ERROR;
}
return NGX_CONF_FILE_DONE;
}
/* buf */
len = b->pos - start;
/* len=4096 buf ; 4096 , " ' , , */
if (len == NGX_CONF_BUFFER) {
cf->conf_file->line = start_line;
if (d_quoted) {
ch = '"';
} else if (s_quoted) {
ch = '\'';
} else {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"too long parameter \"%*s...\" started",
10, start);
return NGX_ERROR;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"too long parameter, probably "
"missing terminating \"%c\" character", ch);
return NGX_ERROR;
}
/* buf */
if (len) {
ngx_memmove(b->start, start, len);
}
/* buf , buf */
size = (ssize_t) (file_size - cf->conf_file->file.offset);
if (size > b->end - (b->start + len)) {
size = b->end - (b->start + len);
}
n = ngx_read_file(&cf->conf_file->file, b->start + len, size,
cf->conf_file->file.offset);
if (n == NGX_ERROR) {
return NGX_ERROR;
}
if (n != size) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ngx_read_file_n " returned "
"only %z bytes instead of %z",
n, size);
return NGX_ERROR;
}
/* b->pos b->last , start */
b->pos = b->start + len;
b->last = b->pos + n;
start = b->start;
if (dump) {
dump->last = ngx_cpymem(dump->last, b->pos, size);
}
}
/* ch */
ch = *b->pos++;
/*
*/
if (ch == LF) {
cf->conf_file->line++;
/*
, , sharp_comment = 0; sharp_comment=1 */
if (sharp_comment) {
sharp_comment = 0;
}
}
/* , */
if (sharp_comment) {
continue;
}
/* , , */
if (quoted) {
quoted = 0;
continue;
}
/* , */
if (need_space) {
...
}
}
}
모듈 프로필 데이터 구조 에 값 설정 ngxconf_handler
ngx_conf_handler 방법 은 주로 받 은 token 배열 cf - > args 를 모듈 의 명령 집합 cycle - > modules [i] - > commands 에 따라 값 을 설정 합 니 다.(이벤트 와 http 헤드 핵심 모듈 을 뒤에서 분석 할 때 사용 합 니 다)
1. 모듈 의 index 색인 값 을 통 해 cycle - > ctx 모듈 에서 파일 데이터 구 조 를 설정 합 니 다.
2. rv = cmd - > set (cf, cmd, conf) 를 통 해 명령 이 집중 적 으로 정의 하 는 설정 값 의 반전 방법 을 호출 합 니 다.
여 기 는 모듈 유형 에 따라 설정 정 보 를 해당 모듈 에 하나씩 해석 합 니 다.
/**
*
* cycle->modules
*/
static ngx_int_t
ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last)
{
char *rv;
void *conf, **confp;
ngx_uint_t i, found;
ngx_str_t *name;
ngx_command_t *cmd;
name = cf->args->elts;
found = 0;
/* */
for (i = 0; cf->cycle->modules[i]; i++) {
cmd = cf->cycle->modules[i]->commands;
if (cmd == NULL) {
continue;
}
for ( /* void */ ; cmd->name.len; cmd++) {
if (name->len != cmd->name.len) {
continue;
}
/* token , , */
if (ngx_strcmp(name->data, cmd->name.data) != 0) {
continue;
}
found = 1;
if (cf->cycle->modules[i]->type != NGX_CONF_MODULE
&& cf->cycle->modules[i]->type != cf->module_type)
{
continue;
}
...
/* is the directive's argument count right ? */
if (!(cmd->type & NGX_CONF_ANY)) {
...
}
/* set up the directive's configuration context */
conf = NULL;
/* ; */
if (cmd->type & NGX_DIRECT_CONF) {
/* ngx_core_module; */
conf = ((void **) cf->ctx)[cf->cycle->modules[i]->index];
} else if (cmd->type & NGX_MAIN_CONF) {
conf = &(((void **) cf->ctx)[cf->cycle->modules[i]->index]);
} else if (cf->ctx) {
confp = *(void **) ((char *) cf->ctx + cmd->conf);
if (confp) {
conf = confp[cf->cycle->modules[i]->ctx_index];
}
}
/**
* ;
* conf ;
* cmd ;
* conf conf
*
*/
rv = cmd->set(cf, cmd, conf);
if (rv == NGX_CONF_OK) {
return NGX_OK;
}
if (rv == NGX_CONF_ERROR) {
return NGX_ERROR;
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%s\" directive %s", name->data, rv);
return NGX_ERROR;
}
}
...
return NGX_ERROR;
}
nginx_conf_file. c 파일 에서 다양한 프로필 값 설정 방법 을 정의 합 니 다.char *ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_str_array_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
char *ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_off_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
char *ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
핵심 모듈 설정 호출
핵심 모듈 통과 ngxcore_module 의 색인 index 값 은 핵심 설정 의 데이터 구 조 를 얻 을 수 있 습 니 다. ngx_core_conf_t
/* ngx_core_conf_t */
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.