Nginx 소스 코드 분석 - 주류 프로 세 스 - 프로필 분석

30175 단어
Nginx 소스 코드 에서 가장 중요 한 것 은 설정 파일 의 해석 입 니 다.일반적으로 / usr / local / nginx / conf / nginx. conf 파일 의 설정 정 보 를 분석 합 니 다.
앞의 글 에서 우 리 는 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);

좋은 웹페이지 즐겨찾기