upstream nginx-0.7.43
[nginx.git] / nginx / src / http / ngx_http_request.c
index faa8d7f..c80ae10 100644 (file)
@@ -310,8 +310,6 @@ ngx_http_init_request(ngx_event_t *rev)
          * is required to determine a server address
          */
 
-        c->local_sockaddr = NULL;
-
         if (ngx_http_server_addr(r, NULL) != NGX_OK) {
             ngx_http_close_connection(c);
             return;
@@ -1645,6 +1643,7 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
 #if (NGX_PCRE)
 
     if (vn->nregex) {
+        size_t                   ncaptures;
         ngx_int_t                n;
         ngx_uint_t               i;
         ngx_str_t                name;
@@ -1653,11 +1652,33 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
         name.len = len;
         name.data = server;
 
+        ncaptures = 0;
+
         sn = vn->regex;
 
         for (i = 0; i < vn->nregex; i++) {
 
-            n = ngx_regex_exec(sn[i].regex, &name, NULL, 0);
+            if (sn[i].captures && r->captures == NULL) {
+
+                ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3;
+
+                r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int));
+                if (r->captures == NULL) {
+                    return NGX_ERROR;
+                }
+
+                if (server == buf) {
+                    server = ngx_pnalloc(r->pool, len);
+                    if (server == NULL) {
+                        return NGX_ERROR;
+                    }
+
+                    ngx_memcpy(server, buf, len);
+                    name.data = server;
+                }
+            }
+
+            n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);
 
             if (n == NGX_REGEX_NO_MATCHED) {
                 continue;
@@ -1675,6 +1696,9 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
 
             cscf = sn[i].core_srv_conf;
 
+            r->ncaptures = ncaptures;
+            r->captures_data = server;
+
             goto found;
         }
     }
@@ -2395,8 +2419,15 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
                        (const void *) &tcp_nodelay, sizeof(int))
             == -1)
         {
+#if (NGX_SOLARIS)
+            /* Solaris returns EINVAL if a socket has been shut down */
+            c->log_error = NGX_ERROR_IGNORE_EINVAL;
+#endif
+
             ngx_connection_error(c, ngx_socket_errno,
                                  "setsockopt(TCP_NODELAY) failed");
+
+            c->log_error = NGX_ERROR_INFO;
             ngx_http_close_connection(c);
             return;
         }