upstream nginx-0.7.39
[nginx.git] / nginx / src / http / ngx_http_core_module.c
index d44933c..88672f0 100644 (file)
@@ -112,8 +112,9 @@ static ngx_conf_enum_t  ngx_http_core_satisfy[] = {
 
 
 static ngx_conf_enum_t  ngx_http_core_if_modified_since[] = {
-    { ngx_string("exact"), 0 },
-    { ngx_string("before"), 1 },
+    { ngx_string("off"), NGX_HTTP_IMS_OFF },
+    { ngx_string("exact"), NGX_HTTP_IMS_EXACT },
+    { ngx_string("before"), NGX_HTTP_IMS_BEFORE },
     { ngx_null_string, 0 }
 };
 
@@ -1034,10 +1035,10 @@ ngx_int_t
 ngx_http_core_try_files_phase(ngx_http_request_t *r,
     ngx_http_phase_handler_t *ph)
 {
-    size_t                        len, root, alias;
-    ssize_t                       reserve, allocated;
+    size_t                        len, root, alias, reserve, allocated;
     u_char                       *p, *name;
     ngx_str_t                     path;
+    ngx_uint_t                    test_dir;
     ngx_http_try_file_t          *tf;
     ngx_open_file_info_t          of;
     ngx_http_script_code_pt       code;
@@ -1058,7 +1059,7 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
     allocated = 0;
     root = 0;
     name = NULL;
-    path.len = 0;
+    /* suppress MSVC warning */
     path.data = NULL;
 
     tf = clcf->try_files;
@@ -1085,12 +1086,8 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
             len = tf->name.len;
         }
 
-        reserve = len - r->uri.len;
-
         /* 16 bytes are preallocation */
-        reserve = reserve < 16 ? 16 : reserve + 16;
-
-        reserve += alias;
+        reserve = ngx_abs((ssize_t) (len - r->uri.len)) + alias + 16;
 
         if (reserve > allocated) {
 
@@ -1133,6 +1130,8 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
             }
         }
 
+        test_dir = tf->test_dir;
+
         tf++;
 
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1172,7 +1171,7 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
             continue;
         }
 
-        if (!of.is_file) {
+        if (of.is_dir && !test_dir) {
             continue;
         }
 
@@ -1194,6 +1193,11 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
             ngx_memcpy(p, name, path.len);
         }
 
+        if (ngx_http_set_exten(r) != NGX_OK) {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+            return NGX_OK;
+        }
+
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "try file uri: \"%V\"", &r->uri);
 
@@ -1547,7 +1551,7 @@ ngx_http_set_content_type(ngx_http_request_t *r)
 
                 exten = ngx_pnalloc(r->pool, r->exten.len);
                 if (exten == NULL) {
-                    return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                    return NGX_ERROR;
                 }
 
                 hash = ngx_hash_strlow(exten, r->exten.data, r->exten.len);
@@ -1676,8 +1680,7 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
             return NULL;
         }
 
-        if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0)== NGX_ERROR)
-        {
+        if (ngx_conf_full_name((ngx_cycle_t *) ngx_cycle, path, 0) != NGX_OK) {
             return NULL;
         }
 
@@ -1768,32 +1771,33 @@ ngx_http_server_addr(ngx_http_request_t *r, ngx_str_t *s)
 {
     socklen_t            len;
     ngx_connection_t    *c;
-    struct sockaddr_in   sin;
-
-    /* AF_INET only */
+    u_char               sa[NGX_SOCKADDRLEN];
 
     c = r->connection;
 
-    if (r->in_addr == 0) {
-        len = sizeof(struct sockaddr_in);
-        if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) {
+    if (c->local_sockaddr == NULL) {
+
+        len = NGX_SOCKADDRLEN;
+
+        if (getsockname(c->fd, (struct sockaddr *) &sa, &len) == -1) {
             ngx_connection_error(c, ngx_socket_errno, "getsockname() failed");
             return NGX_ERROR;
         }
 
-        r->in_addr = sin.sin_addr.s_addr;
+        c->local_sockaddr = ngx_palloc(r->connection->pool, len);
+        if (c->local_sockaddr == NULL) {
+            return NGX_ERROR;
+        }
 
-    } else {
-        sin.sin_family = c->sockaddr->sa_family;
-        sin.sin_addr.s_addr = r->in_addr;
+        c->local_socklen = len;
+        ngx_memcpy(c->local_sockaddr, &sa, len);
     }
 
     if (s == NULL) {
         return NGX_OK;
     }
 
-    s->len = ngx_sock_ntop((struct sockaddr *) &sin, s->data,
-                           NGX_INET_ADDRSTRLEN);
+    s->len = ngx_sock_ntop(c->local_sockaddr, s->data, s->len, 0);
 
     return NGX_OK;
 }
@@ -1997,7 +2001,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
 
     if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
                       sizeof(ngx_table_elt_t))
-        == NGX_ERROR)
+        != NGX_OK)
     {
         return NGX_ERROR;
     }
@@ -2052,10 +2056,6 @@ ngx_http_subrequest(ngx_http_request_t *r,
         c->data = sr;
     }
 
-    sr->in_addr = r->in_addr;
-    sr->port = r->port;
-    sr->port_text = r->port_text;
-
     sr->variables = r->variables;
 
     sr->log_handler = r->log_handler;
@@ -2589,7 +2589,7 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
     if (ngx_strcmp(value[0].data, "include") == 0) {
         file = value[1];
 
-        if (ngx_conf_full_name(cf->cycle, &file, 1) == NGX_ERROR){
+        if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
             return NGX_CONF_ERROR;
         }
 
@@ -2721,15 +2721,16 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
      *     conf->client_large_buffers.num = 0;
      */
 
-    if (ngx_array_init(&cscf->listen, cf->pool, 4, sizeof(ngx_http_listen_t))
-        == NGX_ERROR)
+    if (ngx_array_init(&cscf->listen, cf->temp_pool, 4,
+                       sizeof(ngx_http_listen_t))
+        != NGX_OK)
     {
         return NGX_CONF_ERROR;
     }
 
     if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
                        sizeof(ngx_http_server_name_t))
-        == NGX_ERROR)
+        != NGX_OK)
     {
         return NGX_CONF_ERROR;
     }
@@ -2753,6 +2754,7 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_http_core_srv_conf_t *conf = child;
 
     ngx_http_listen_t       *ls;
+    struct sockaddr_in      *sin;
     ngx_http_server_name_t  *sn;
 
     /* TODO: it does not merge, it inits only */
@@ -2765,18 +2767,25 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
 
         ngx_memzero(ls, sizeof(ngx_http_listen_t));
 
-        ls->addr = INADDR_ANY;
+        sin = (struct sockaddr_in *) &ls->sockaddr;
+
+        sin->sin_family = AF_INET;
 #if (NGX_WIN32)
-        ls->port = 80;
+        sin->sin_port = htons(80);
 #else
-        /* STUB: getuid() should be cached */
-        ls->port = (getuid() == 0) ? 80 : 8000;
+        sin->sin_port = htons((getuid() == 0) ? 80 : 8000);
 #endif
-        ls->family = AF_INET;
+        sin->sin_addr.s_addr = INADDR_ANY;
+
+        ls->socklen = sizeof(struct sockaddr_in);
 
         ls->conf.backlog = NGX_LISTEN_BACKLOG;
         ls->conf.rcvbuf = -1;
         ls->conf.sndbuf = -1;
+        ls->conf.wildcard = 1;
+
+        (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
+                             NGX_SOCKADDR_STRLEN, 1);
     }
 
     if (conf->server_name.data == NULL) {
@@ -2940,7 +2949,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
             conf->root.len = sizeof("html") - 1;
             conf->root.data = (u_char *) "html";
 
-            if (ngx_conf_full_name(cf->cycle, &conf->root, 0) == NGX_ERROR) {
+            if (ngx_conf_full_name(cf->cycle, &conf->root, 0) != NGX_OK) {
                 return NGX_CONF_ERROR;
             }
         }
@@ -3050,7 +3059,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
     ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
                               NGX_HTTP_SATISFY_ALL);
     ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
-                              0);
+                              NGX_HTTP_IMS_EXACT);
     ngx_conf_merge_value(conf->internal, prev->internal, 0);
     ngx_conf_merge_value(conf->client_body_in_file_only,
                               prev->client_body_in_file_only, 0);
@@ -3151,8 +3160,6 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
 }
 
 
-/* AF_INET only */
-
 static char *
 ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
@@ -3193,17 +3200,18 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
     ngx_memzero(ls, sizeof(ngx_http_listen_t));
 
-    ls->family = u.family;
-    ls->addr = u.addr.in_addr;
-    ls->port = u.port;
+    ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen);
+
+    ls->socklen = u.socklen;
     ls->file_name = cf->conf_file->file.name.data;
     ls->line = cf->conf_file->line;
     ls->conf.backlog = NGX_LISTEN_BACKLOG;
     ls->conf.rcvbuf = -1;
     ls->conf.sndbuf = -1;
+    ls->conf.wildcard = u.wildcard;
 
-    n = ngx_inet_ntop(AF_INET, &ls->addr, ls->conf.addr, NGX_INET_ADDRSTRLEN);
-    ngx_sprintf(&ls->conf.addr[n], ":%ui", ls->port);
+    (void) ngx_sock_ntop((struct sockaddr *) &ls->sockaddr, ls->conf.addr,
+                         NGX_SOCKADDR_STRLEN, 1);
 
     if (cf->args->nelts == 2) {
         return NGX_CONF_OK;
@@ -3513,7 +3521,7 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     }
 
     if (lcf->root.data[0] != '$') {
-        if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) == NGX_ERROR) {
+        if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) != NGX_OK) {
             return NGX_CONF_ERROR;
         }
     }
@@ -3853,6 +3861,11 @@ ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 
         tf[i].name = value[i + 1];
 
+        if (tf[i].name.data[tf[i].name.len - 1] == '/') {
+            tf[i].test_dir = 1;
+            tf[i].name.len--;
+        }
+
         n = ngx_http_script_variables_count(&tf[i].name);
 
         if (n) {