diff src/http/ngx_http.c @ 326:f70f2f565fe0 NGINX_0_5_33

nginx 0.5.33 *) Change: now by default the "echo" SSI command uses entity encoding. *) Feature: the "encoding" parameter in the "echo" SSI command. *) Change: mail proxy was split on three modules: pop3, imap and smtp. *) Feature: the --without-mail_pop3_module, --without-mail_imap_module, and --without-mail_smtp_module configuration parameters. *) Feature: the "smtp_greeting_delay" and "smtp_client_buffer" directives of the ngx_mail_smtp_module. *) Feature: the "server_name" and "valid_referers" directives support regular expressions. *) Feature: the "server_name", "map", and "valid_referers" directives support the "www.example.*" wildcards. *) Bugfix: sub_filter did not work with empty substitution. *) Bugfix: in sub_filter parsing. *) Bugfix: a worker process may got caught in an endless loop, if the memcached was used. *) Bugfix: nginx supported low case only "close" and "keep-alive" values in the "Connection" request header line; bug appeared in 0.5.32. *) Bugfix: nginx could not start on Solaris if the shared PCRE library located in non-standard place was used.
author Igor Sysoev <http://sysoev.ru>
date Wed, 07 Nov 2007 00:00:00 +0300
parents 7cf404023f50
children
line wrap: on
line diff
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -73,7 +73,6 @@ static char *
 ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
     char                        *rv;
-    u_char                       ch;
     ngx_int_t                    rc, j;
     ngx_uint_t                   mi, m, s, l, p, a, i, n;
     ngx_uint_t                   find_config_index, use_rewrite, use_access;
@@ -99,6 +98,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
     ngx_http_core_loc_conf_t    *clcf;
     ngx_http_phase_handler_pt    checker;
     ngx_http_core_main_conf_t   *cmcf;
+#if (NGX_PCRE)
+    ngx_uint_t                   regex;
+#endif
 #if (NGX_WIN32)
     ngx_iocp_conf_t             *iocpcf;
 #endif
@@ -656,41 +658,32 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
                 return NGX_CONF_ERROR;
             }
 
+#if (NGX_PCRE)
+            regex = 0;
+#endif
+
             name = in_addr[a].names.elts;
+
             for (s = 0; s < in_addr[a].names.nelts; s++) {
 
-                ch = name[s].name.data[0];
-
-                if (ch == '*' || ch == '.') {
+#if (NGX_PCRE)
+                if (name[s].regex) {
+                    regex++;
                     continue;
                 }
+#endif
 
                 rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
-                                      0);
+                                      NGX_HASH_WILDCARD_KEY);
 
                 if (rc == NGX_ERROR) {
                     return NGX_CONF_ERROR;
                 }
 
-                if (rc == NGX_BUSY) {
-                    ngx_log_error(NGX_LOG_WARN, cf->log, 0,
-                                "conflicting server name \"%V\" on %s, ignored",
+                if (rc == NGX_DECLINED) {
+                    ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+                                "invalid server name or wildcard \"%V\" on %s",
                                 &name[s].name, in_addr[a].listen_conf->addr);
-                }
-            }
-
-            for (s = 0; s < in_addr[a].names.nelts; s++) {
-
-                ch = name[s].name.data[0];
-
-                if (ch != '*' && ch != '.') {
-                    continue;
-                }
-
-                rc = ngx_hash_add_key(&ha, &name[s].name, name[s].core_srv_conf,
-                                      NGX_HASH_WILDCARD_KEY);
-
-                if (rc == NGX_ERROR) {
                     return NGX_CONF_ERROR;
                 }
 
@@ -718,28 +711,70 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
                 }
             }
 
-            if (ha.dns_wildcards.nelts) {
+            if (ha.dns_wc_head.nelts) {
+
+                ngx_qsort(ha.dns_wc_head.elts,
+                          (size_t) ha.dns_wc_head.nelts,
+                          sizeof(ngx_hash_key_t),
+                          ngx_http_cmp_dns_wildcards);
+
+                hash.hash = NULL;
+                hash.temp_pool = ha.temp_pool;
 
-                ngx_qsort(ha.dns_wildcards.elts,
-                          (size_t) ha.dns_wildcards.nelts,
+                if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
+                                           ha.dns_wc_head.nelts)
+                    != NGX_OK)
+                {
+                    ngx_destroy_pool(ha.temp_pool);
+                    return NGX_CONF_ERROR;
+                }
+
+                in_addr[a].wc_head = (ngx_hash_wildcard_t *) hash.hash;
+            }
+
+            if (ha.dns_wc_tail.nelts) {
+
+                ngx_qsort(ha.dns_wc_tail.elts,
+                          (size_t) ha.dns_wc_tail.nelts,
                           sizeof(ngx_hash_key_t),
                           ngx_http_cmp_dns_wildcards);
 
                 hash.hash = NULL;
                 hash.temp_pool = ha.temp_pool;
 
-                if (ngx_hash_wildcard_init(&hash, ha.dns_wildcards.elts,
-                                           ha.dns_wildcards.nelts)
+                if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
+                                           ha.dns_wc_tail.nelts)
                     != NGX_OK)
                 {
                     ngx_destroy_pool(ha.temp_pool);
                     return NGX_CONF_ERROR;
                 }
 
-                in_addr[a].dns_wildcards = (ngx_hash_wildcard_t *) hash.hash;
+                in_addr[a].wc_tail = (ngx_hash_wildcard_t *) hash.hash;
             }
 
             ngx_destroy_pool(ha.temp_pool);
+
+#if (NGX_PCRE)
+
+            if (regex == 0) {
+                continue;
+            }
+
+            in_addr[a].nregex = regex;
+            in_addr[a].regex = ngx_palloc(cf->pool,
+                                       regex * sizeof(ngx_http_server_name_t));
+
+            if (in_addr[a].regex == NULL) {
+                return NGX_CONF_ERROR;
+            }
+
+            for (i = 0, s = 0; s < in_addr[a].names.nelts; s++) {
+                if (name[s].regex) {
+                    in_addr[a].regex[i++] = name[s];
+                }
+            }
+#endif
         }
 
         in_addr = in_port[p].addrs.elts;
@@ -857,8 +892,10 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
                 hip->addrs[i].core_srv_conf = in_addr[i].core_srv_conf;
 
                 if (in_addr[i].hash.buckets == NULL
-                    && (in_addr[i].dns_wildcards == NULL
-                        || in_addr[i].dns_wildcards->hash.buckets == NULL))
+                    && (in_addr[i].wc_head == NULL
+                        || in_addr[i].wc_head->hash.buckets == NULL)
+                    && (in_addr[i].wc_head == NULL
+                        || in_addr[i].wc_head->hash.buckets == NULL))
                 {
                     continue;
                 }
@@ -869,8 +906,13 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma
                 }
                 hip->addrs[i].virtual_names = vn;
 
-                vn->hash = in_addr[i].hash;
-                vn->dns_wildcards = in_addr[i].dns_wildcards;
+                vn->names.hash = in_addr[i].hash;
+                vn->names.wc_head = in_addr[i].wc_head;
+                vn->names.wc_tail = in_addr[i].wc_tail;
+#if (NGX_PCRE)
+                vn->nregex = in_addr[i].nregex;
+                vn->regex = in_addr[i].regex;
+#endif
             }
 
             if (done) {
@@ -929,7 +971,8 @@ ngx_http_add_address(ngx_conf_t *cf, ngx
 
     if (in_port->addrs.elts == NULL) {
         if (ngx_array_init(&in_port->addrs, cf->temp_pool, 4,
-                           sizeof(ngx_http_conf_in_addr_t)) != NGX_OK)
+                           sizeof(ngx_http_conf_in_addr_t))
+            != NGX_OK)
         {
             return NGX_ERROR;
         }
@@ -943,8 +986,13 @@ ngx_http_add_address(ngx_conf_t *cf, ngx
     in_addr->addr = lscf->addr;
     in_addr->hash.buckets = NULL;
     in_addr->hash.size = 0;
-    in_addr->dns_wildcards = NULL;
+    in_addr->wc_head = NULL;
+    in_addr->wc_tail = NULL;
     in_addr->names.elts = NULL;
+#if (NGX_PCRE)
+    in_addr->nregex = 0;
+    in_addr->regex = NULL;
+#endif
     in_addr->core_srv_conf = cscf;
     in_addr->default_server = lscf->conf.default_server;
     in_addr->bind = lscf->conf.bind;
@@ -977,13 +1025,15 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_h
 
     if (in_addr->names.elts == NULL) {
         if (ngx_array_init(&in_addr->names, cf->temp_pool, 4,
-                           sizeof(ngx_http_server_name_t)) != NGX_OK)
+                           sizeof(ngx_http_server_name_t))
+            != NGX_OK)
         {
             return NGX_ERROR;
         }
     }
 
     server_names = cscf->server_names.elts;
+
     for (i = 0; i < cscf->server_names.nelts; i++) {
 
         for (n = 0; n < server_names[i].name.len; n++) {
@@ -994,7 +1044,6 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_h
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
                        "name: %V", &server_names[i].name);
 
-
         name = ngx_array_push(&in_addr->names);
         if (name == NULL) {
             return NGX_ERROR;