# HG changeset patch # User Igor Sysoev # Date 1161695215 0 # Node ID 472cd9768ac2d26fb8d6543b9702447194862496 # Parent 134a3c12d2986b999230129bd1e736e6340ef8c2 now the "listen" directives use ngx_parse_url() diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c --- a/src/core/ngx_inet.c +++ b/src/core/ngx_inet.c @@ -10,6 +10,9 @@ #include +static char *ngx_inet_parse_host_port(ngx_inet_upstream_t *u); + + /* * ngx_sock_ntop() and ngx_inet_ntop() may be implemented as * "ngx_sprintf(text, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3])", however, @@ -223,10 +226,11 @@ ngx_ptocidr(ngx_str_t *text, void *cidr) ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u) { - u_char *p; + u_char *p, *host; size_t len; ngx_int_t port; ngx_uint_t i; + struct hostent *h; #if (NGX_HAVE_UNIX_DOMAIN) struct sockaddr_un *saun; #endif @@ -390,6 +394,47 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t port: if (u->listen) { + if (u->portn == 0) { + if (u->default_portn == 0) { + u->err = "no port"; + return NGX_ERROR; + } + + u->portn = u->default_portn; + } + + if (u->host.len == 1 && u->host.data[0] == '*') { + u->host.len = 0; + } + + /* AF_INET only */ + + if (u->host.len) { + + host = ngx_palloc(cf->temp_pool, u->host.len + 1); + if (host == NULL) { + return NGX_ERROR; + } + + (void) ngx_cpystrn(host, u->host.data, u->host.len + 1); + + u->addr.in_addr = inet_addr((const char *) host); + + if (u->addr.in_addr == INADDR_NONE) { + h = gethostbyname((const char *) host); + + if (h == NULL || h->h_addr_list[0] == NULL) { + u->err = "host not found"; + return NGX_ERROR; + } + + u->addr.in_addr = *(in_addr_t *)(h->h_addr_list[0]); + } + + } else { + u->addr.in_addr = INADDR_ANY; + } + return NGX_OK; } @@ -737,7 +782,7 @@ ngx_inet_upstream_parse(ngx_conf_t *cf, } -char * +static char * ngx_inet_parse_host_port(ngx_inet_upstream_t *u) { size_t i; diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h --- a/src/core/ngx_inet.h +++ b/src/core/ngx_inet.h @@ -17,8 +17,8 @@ typedef struct { - in_addr_t addr; - in_addr_t mask; + in_addr_t addr; + in_addr_t mask; } ngx_inet_cidr_t; @@ -57,53 +57,60 @@ struct ngx_peers_s { }; -typedef struct { - ngx_int_t type; +typedef union { + in_addr_t in_addr; +} ngx_url_addr_t; - ngx_peers_t *peers; - ngx_str_t url; - ngx_str_t host; - ngx_str_t host_header; - ngx_str_t port; - ngx_str_t uri; +typedef struct { + ngx_int_t type; + + ngx_peers_t *peers; - in_port_t portn; - in_port_t default_portn; + ngx_str_t url; + ngx_str_t host; + ngx_str_t host_header; + ngx_str_t port; + ngx_str_t uri; + + in_port_t portn; + in_port_t default_portn; - unsigned listen:1; - unsigned uri_part:1; - unsigned upstream:1; + unsigned listen:1; + unsigned uri_part:1; + unsigned upstream:1; - unsigned default_port:1; - unsigned wildcard:1; + unsigned default_port:1; + unsigned wildcard:1; - char *err; + ngx_url_addr_t addr; + + char *err; } ngx_url_t; typedef struct { - ngx_str_t name; /* "schema:host:port/uri" */ - ngx_str_t url; /* "host:port/uri" */ - ngx_str_t host; - ngx_str_t uri; - ngx_str_t host_header; /* "host:port" */ - ngx_str_t port_text; /* "port" */ + ngx_str_t name; /* "schema:host:port/uri" */ + ngx_str_t url; /* "host:port/uri" */ + ngx_str_t host; + ngx_str_t uri; + ngx_str_t host_header; /* "host:port" */ + ngx_str_t port_text; /* "port" */ - in_port_t port; + in_port_t port; - in_port_t default_port_value; + in_port_t default_port_value; - unsigned default_port:1; - unsigned wildcard:1; + unsigned default_port:1; + unsigned wildcard:1; - unsigned uri_part:1; - unsigned port_only:1; + unsigned uri_part:1; + unsigned port_only:1; } ngx_inet_upstream_t; size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, - size_t len); + size_t len); size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len); ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr); @@ -111,7 +118,6 @@ ngx_int_t ngx_ptocidr(ngx_str_t *text, v ngx_peers_t *ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u); ngx_peers_t *ngx_inet_resolve_peer(ngx_conf_t *cf, ngx_str_t *name, in_port_t port); -char *ngx_inet_parse_host_port(ngx_inet_upstream_t *u); ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u); diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -2371,12 +2371,10 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx { ngx_http_core_srv_conf_t *scf = conf; - char *err; - ngx_str_t *value, size; - ngx_uint_t n; - struct hostent *h; - ngx_http_listen_t *ls; - ngx_inet_upstream_t inet_upstream; + ngx_str_t *value, size; + ngx_url_t u; + ngx_uint_t n; + ngx_http_listen_t *ls; /* * TODO: check duplicate 'listen' directives, @@ -2385,17 +2383,19 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx value = cf->args->elts; - ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t)); - - inet_upstream.url = value[1]; - inet_upstream.port_only = 1; - - err = ngx_inet_parse_host_port(&inet_upstream); - - if (err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in \"%V\" of the \"listen\" directive", - err, &inet_upstream.url); + ngx_memzero(&u, sizeof(ngx_url_t)); + + u.url = value[1]; + u.listen = 1; + u.default_portn = 80; + + if (ngx_parse_url(cf, &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); + } + return NGX_CONF_ERROR; } @@ -2407,41 +2407,14 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx ngx_memzero(ls, sizeof(ngx_http_listen_t)); ls->family = AF_INET; - ls->port = (in_port_t) (inet_upstream.default_port ? - 80 : inet_upstream.port); + ls->addr = u.addr.in_addr; + ls->port = u.portn; ls->file_name = cf->conf_file->file.name; ls->line = cf->conf_file->line; ls->conf.backlog = -1; ls->conf.rcvbuf = -1; ls->conf.sndbuf = -1; - if (inet_upstream.host.len == 1 && inet_upstream.host.data[0] == '*') { - inet_upstream.host.len = 0; - } - - if (inet_upstream.host.len) { - inet_upstream.host.data[inet_upstream.host.len] = '\0'; - - ls->addr = inet_addr((const char *) inet_upstream.host.data); - - if (ls->addr == INADDR_NONE) { - h = gethostbyname((const char *) inet_upstream.host.data); - - if (h == NULL || h->h_addr_list[0] == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "can not resolve host \"%s\" " - "in the \"listen\" directive", - inet_upstream.host.data); - return NGX_CONF_ERROR; - } - - ls->addr = *(in_addr_t *)(h->h_addr_list[0]); - } - - } else { - ls->addr = INADDR_ANY; - } - n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, INET_ADDRSTRLEN + 6); ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port); diff --git a/src/imap/ngx_imap_core_module.c b/src/imap/ngx_imap_core_module.c --- a/src/imap/ngx_imap_core_module.c +++ b/src/imap/ngx_imap_core_module.c @@ -471,56 +471,27 @@ ngx_imap_core_server(ngx_conf_t *cf, ngx static char * ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - char *err; ngx_str_t *value; - in_addr_t in_addr; + ngx_url_t u; ngx_uint_t i; - struct hostent *h; ngx_imap_listen_t *imls; - ngx_inet_upstream_t inet_upstream; ngx_imap_core_main_conf_t *cmcf; value = cf->args->elts; - ngx_memzero(&inet_upstream, sizeof(ngx_inet_upstream_t)); - - inet_upstream.url = value[1]; - inet_upstream.port_only = 1; - - err = ngx_inet_parse_host_port(&inet_upstream); + ngx_memzero(&u, sizeof(ngx_url_t)); - if (err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in \"%V\" of the \"listen\" directive", - err, &inet_upstream.url); - return NGX_CONF_ERROR; - } - - if (inet_upstream.host.len == 1 && inet_upstream.host.data[0] == '*') { - inet_upstream.host.len = 0; - } + u.url = value[1]; + u.listen = 1; - if (inet_upstream.host.len) { - inet_upstream.host.data[inet_upstream.host.len] = '\0'; - - in_addr = inet_addr((const char *) inet_upstream.host.data); - - if (in_addr == INADDR_NONE) { - h = gethostbyname((const char *) inet_upstream.host.data); - - if (h == NULL || h->h_addr_list[0] == NULL) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "can not resolve host \"%s\" " - "in the \"listen\" directive", - inet_upstream.host.data); - return NGX_CONF_ERROR; - } - - in_addr = *(in_addr_t *)(h->h_addr_list[0]); + if (ngx_parse_url(cf, &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); } - } else { - in_addr = INADDR_ANY; + return NGX_CONF_ERROR; } cmcf = ngx_imap_conf_get_module_main_conf(cf, ngx_imap_core_module); @@ -529,13 +500,12 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx for (i = 0; i < cmcf->listen.nelts; i++) { - if (imls[i].addr != in_addr || imls[i].port != inet_upstream.port) { + if (imls[i].addr != u.addr.in_addr || imls[i].port != u.portn) { continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate \"%V\" address and port pair", - &inet_upstream.url); + "duplicate \"%V\" address and port pair", &u.url); return NGX_CONF_ERROR; } @@ -546,8 +516,8 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx ngx_memzero(imls, sizeof(ngx_imap_listen_t)); - imls->addr = in_addr; - imls->port = inet_upstream.port; + imls->addr = u.addr.in_addr; + imls->port = u.portn; imls->family = AF_INET; imls->ctx = cf->ctx;