牛骨文教育服务平台(让学习变的简单)
博文笔记

nginx模块开发—HTTP初始化之listen

创建时间:2015-11-19 投稿人: 浏览次数:698

1、知识百科

nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解。与网络有关的配置命令主要有两个:listen和sever_name。listen命令设置nginx监听地址,对于IP协议,这个地址就是address和port,对于UNIX域套接字协议,这个地址就是path,一条listen指令只能指定一个address或者port,address也可以是主机名,比如:

listen 127.0.0.1:8000;

 listen 127.0.0.1;

listen 8000;

 listen *:8000;

 listen localhost:8000;

 listen [::]:8000;

 listen [fe80::1];

 listen unix:/var/run/nginx.sock;

server_name指令列出虚拟主机的所有主机名,如server_name example.com *.example.com www.example.*,用空格分割。

2、数据结构

clip_image002

clip_image002[4]

ngx_http_conf_port_t(ngx_http_core_listen入口)

typedef struct {

    ngx_int_t                  family;

    in_port_t                  port;

    ngx_array_t                addrs;     /* array of ngx_http_conf_addr_t */

} ngx_http_conf_port_t;

ngx_http_conf_addr_t

typedef struct {

    ngx_http_listen_opt_t      opt;

    ngx_hash_t                 hash;

    ngx_hash_wildcard_t       *wc_head;

    ngx_hash_wildcard_t       *wc_tail;

 

    ngx_http_core_srv_conf_t  *default_server;

    ngx_array_t                servers;  /* array of ngx_http_core_srv_conf_t */

} ngx_http_conf_addr_t;

ngx_http_core_srv_conf_t

typedef struct {

    /* array of the ngx_http_server_name_t, "server_name" directive */

    ngx_array_t                 server_names;

 

    /* server ctx */

    ngx_http_conf_ctx_t        *ctx;

 

    ngx_str_t                   server_name;

 

    size_t                      connection_pool_size;

    size_t                      request_pool_size;

    size_t                      client_header_buffer_size;

 

    ngx_bufs_t                  large_client_header_buffers;

 

    ngx_msec_t                  client_header_timeout;

 

    ngx_flag_t                  ignore_invalid_headers;

    ngx_flag_t                  merge_slashes;

    ngx_flag_t                  underscores_in_headers;

 

    unsigned                    listen:1;

 

    ngx_http_core_loc_conf_t  **named_locations;

} ngx_http_core_srv_conf_t;

ngx_http_listen_opt_t(重要)

typedef struct {

    union {

        struct sockaddr        sockaddr;

        struct sockaddr_in     sockaddr_in;

        u_char              sockaddr_data[NGX_SOCKADDRLEN];

    } u;

 

    socklen_t                  socklen;

 

    unsigned                   set:1;                       // bind/backlog/…

    unsigned                   default_server:1;  // default_server

    unsigned                   bind:1;                    // bind/backlog/…

    unsigned                   wildcard:1;

#if (NGX_HTTP_SSL)

    unsigned                   ssl:1;

#endif

#if (NGX_HTTP_SPDY)

    unsigned                   spdy:1;                  // spdy

#endif

    unsigned                   so_keepalive:2;

    unsigned                   proxy_protocol:1;   // proxy_protocol

 

    int                        backlog;   // backlog

    int                        rcvbuf;    // rcvbuf

    int                        sndbuf;    // sndbuf

    。。。

 

    u_char                     addr[NGX_SOCKADDR_STRLEN + 1];  // 0.0.0.0:8000

} ngx_http_listen_opt_t;

ngx_listening_s(ngx_http_init_connection入口)

image

struct ngx_listening_s {

    ngx_socket_t        fd;

 

    struct sockaddr    *sockaddr;

    socklen_t           socklen;    /* size of sockaddr */

    size_t              addr_text_max_len;

    ngx_str_t           addr_text;

 

    int                 type;

 

    int                 backlog;

    int                 rcvbuf;

    int                 sndbuf;

 

    ngx_connection_handler_pt   handler;

 

    void               *servers;  /* array of ngx_http_port_t, for example */

    。。。

    ngx_listening_t    *previous;

    ngx_connection_t   *connection;

 

    unsigned            open:1;

    unsigned            remain:1;

    unsigned            ignore:1;

 

    unsigned            bound:1;       /* already bound */

    unsigned            inherited:1;   /* inherited from previous process */

    unsigned            nonblocking_accept:1;

    unsigned            listen:1;

    unsigned            nonblocking:1;

    unsigned            shared:1;    /* shared between threads or processes */

    unsigned            addr_ntop:1;

 

    unsigned            keepalive:2;

 

};

ngx_http_port_t

typedef struct {

    /* ngx_http_in_addr_t or ngx_http_in6_addr_t */

    void                      *addrs;

    ngx_uint_t                 naddrs;

} ngx_http_port_t;

ngx_http_in_addr_t

typedef struct {

    in_addr_t                  addr;

    ngx_http_addr_conf_t       conf;

} ngx_http_in_addr_t;

ngx_http_addr_conf_s

struct ngx_http_addr_conf_s {

    /* the default server configuration for this address:port */

    ngx_http_core_srv_conf_t  *default_server;

 

    ngx_http_virtual_names_t  *virtual_names;

 

#if (NGX_HTTP_SSL)

    unsigned                   ssl:1;

#endif

#if (NGX_HTTP_SPDY)

    unsigned                   spdy:1;

#endif

    unsigned                   proxy_protocol:1;

};

3、源码解析

clip_image002[6]

ngx_http_core_server_name

函数功能:解析server_name指令。

static char *

ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

    ngx_http_core_srv_conf_t *cscf = conf;

 

    u_char                   ch;

    ngx_str_t               *value;

    ngx_uint_t               i;

    ngx_http_server_name_t  *sn;

 

    value = cf->args->elts;

 

    for (i = 1; i < cf->args->nelts; i++) {

 

        ch = value[i].data[0];

 

        if ((ch == "*" && (value[i].len < 3 || value[i].data[1] != "."))

            || (ch == "." && value[i].len < 2))

        {

            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,

                               "server name "%V" is invalid", &value[i]);

            return NGX_CONF_ERROR;

        }

 

        if (ngx_strchr(value[i].data, "/")) {

            ngx_conf_log_error(NGX_LOG_WARN, cf, 0,

                               "server name "%V" has suspicious symbols",

                               &value[i]);

        }

 

        sn = ngx_array_push(&cscf->server_names);

        if (sn == NULL) {

            return NGX_CONF_ERROR;

        }

        sn->server = cscf;

 

        if (ngx_strcasecmp(value[i].data, (u_char *) "$hostname") == 0) {

            sn->name = cf->cycle->hostname;

        } else {

            sn->name = value[i];

        }

 

        if (value[i].data[0] != "~") {

            ngx_strlow(sn->name.data, sn->name.data, sn->name.len);

            continue;

        }

。。。

    }

 

    return NGX_CONF_OK;

}

ngx_http_core_listen

函数功能:解析listen指令。

static char *

ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

{

    ngx_http_core_srv_conf_t *cscf = conf;

 

    ngx_str_t              *value, size;

    ngx_url_t               u;

    ngx_uint_t              n;

    ngx_http_listen_opt_t   lsopt;

 

    cscf->listen = 1;

 

    value = cf->args->elts;

 

    ngx_memzero(&u, sizeof(ngx_url_t));

 

    u.url = value[1];

    u.listen = 1;

u.default_port = 80;

 

    //解析listen命令后面的参数,ip:port

    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {

        if (u.err) {

            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,

                               "%s in "%V" of the "listen" directive",

                               u.err, &u.url);

        }

 

声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。