]> git.kaiwu.me - nginx.git/commitdiff
nginx-0.0.1-2003-12-25-23:26:58 import
authorIgor Sysoev <igor@sysoev.ru>
Thu, 25 Dec 2003 20:26:58 +0000 (20:26 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Thu, 25 Dec 2003 20:26:58 +0000 (20:26 +0000)
21 files changed:
auto/lib/md5/makefile.msvc
auto/make
auto/options
auto/sources
src/core/nginx.c
src/core/ngx_conf_file.h
src/core/ngx_connection.h
src/core/ngx_regex.c
src/core/ngx_regex.h
src/event/ngx_event.c
src/http/modules/ngx_http_rewrite_handler.c [new file with mode: 0644]
src/http/modules/ngx_http_status.c [new file with mode: 0644]
src/http/ngx_http.c
src/http/ngx_http_core_module.c
src/http/ngx_http_core_module.h
src/http/ngx_http_log_handler.c
src/http/ngx_http_parse.c
src/http/ngx_http_request.c
src/http/ngx_http_request.h
src/os/unix/ngx_errno.h
src/os/unix/ngx_freebsd_sendfile_chain.c

index f44831c5675039d70c2e4786c2c44e5153043ef1..60a662407de25af5fa2ba8ddb018c197616cda70 100644 (file)
@@ -1,4 +1,5 @@
 
 all:
-       cl -nologo -c -MT -O2 -D MD5_ASM -D L_ENDIAN md5_dgst.c md5_one.c
+       cl -nologo -c -MT -O2 -Ob1 -Oi -Gs -D MD5_ASM -D L_ENDIAN       \
+               md5_dgst.c md5_one.c
        link -lib -out:md5.lib md5_dgst.obj md5_one.obj asm/m-win32.obj
index fa1354f3490d75fa1108c4d7cbdd94413a432cbe..c210d7e2b1a271bd43a51a5ca7b2556b38d576bf 100644 (file)
--- a/auto/make
+++ b/auto/make
@@ -11,6 +11,11 @@ HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES \
 
 HTTP_MODULES="$HTTP_MODULES $HTTP_STATIC_MODULE $HTTP_INDEX_MODULE"
 
+if [ $HTTP_REWRITE = YES ]; then
+    HTTP_MODULES="$HTTP_MODULES $HTTP_REWRITE_MODULE"
+    HTTP_SRCS="$HTTP_SRCS $HTTP_REWRITE_SRCS"
+fi
+
 if [ $HTTP_GZIP = YES ]; then
     HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_GZIP_FILTER_MODULE"
     HTTP_SRCS="$HTTP_SRCS $HTTP_GZIP_SRCS"
index 1eb45a28d7054e80b59265eb97cd8feb26f176d2..2356a76db3f17cd2592aa4fe2167d328763fe9fa 100644 (file)
@@ -6,6 +6,7 @@ OBJS=objs
 
 TEST_BUILD_DEVPOLL=NO
 
+HTTP_REWRITE=YES
 HTTP_GZIP=YES
 HTTP_PROXY=YES
 
@@ -34,6 +35,7 @@ do
 
         --builddir=*)                    OBJS="$value"              ;;
 
+        --without-http_rewrite_module)   HTTP_REWRITE=NO            ;;
         --without-http_gzip_module)      HTTP_GZIP=NO               ;;
         --without-http_proxy_module)     HTTP_PROXY=NO              ;;
 
index b2eec44264193d61fb015c270730008076b68511..1b3ffda68938c4f296109783cc4355e6bc634cc9 100644 (file)
@@ -193,6 +193,10 @@ HTTP_SRCS="src/http/ngx_http.c \
             src/http/modules/ngx_http_not_modified_filter.c"
 
 
+HTTP_REWRITE_MODULE=ngx_http_rewrite_module
+HTTP_REWRITE_SRCS=src/http/modules/ngx_http_rewrite_handler.c
+
+
 HTTP_GZIP_FILTER_MODULE=ngx_http_gzip_filter_module
 HTTP_GZIP_SRCS=src/http/modules/ngx_http_gzip_filter.c
 HTTP_GZIP_UNIX_LIBS=-lz
index 7deb24fd3d9bc4364a05805decf09a346c5c99e0..eee88dc3f3c4d0049a0ee763324c154d7e1fec15 100644 (file)
@@ -204,11 +204,13 @@ int main(int argc, char *const *argv)
                 ngx_process_events(cycle->log);
 
                 if (done) {
+#if !(WIN32)
                     if (ngx_delete_file(pidfile.name.data) == NGX_FILE_ERROR) {
                         ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
                                       ngx_delete_file_n " \"%s\" failed",
                                       pidfile.name.data);
                     }
+#endif
 
                     ngx_log_error(NGX_LOG_INFO,
                                   cycle->log, 0, "exiting");
@@ -291,11 +293,11 @@ ngx_log_debug(log, "REOPEN: %d:%d:%s" _ fd _ file[i].fd _ file[i].name.data);
 static ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle, ngx_log_t *log)
 {
     int               i, n, failed;
-    ngx_fd_t          fd;
     ngx_str_t         conf_file;
     ngx_conf_t        conf;
     ngx_pool_t       *pool;
     ngx_cycle_t      *cycle, **old;
+    ngx_socket_t      fd;
     ngx_core_conf_t  *ccf;
     ngx_open_file_t  *file;
     ngx_listening_t  *ls, *nls;
@@ -457,7 +459,7 @@ ngx_log_debug(log, "OPEN: %d:%s" _ file[i].fd _ file[i].name.data);
 
                         fd /= 4;
 #endif
-                        if (fd >= cycle->connection_n) {
+                        if (fd >= (ngx_socket_t) cycle->connection_n) {
                             ngx_log_error(NGX_LOG_EMERG, log, 0,
                                         "%d connections is not enough to hold "
                                         "an open listening socket on %s, "
index eb9e63b512128870a7abf2fd222e2ee622d09083..536294779fbf5e5e6ff5c4c5d17f2f39fec2c3b0 100644 (file)
 #define NGX_CONF_TAKE9       0x00000200
 
 #define NGX_CONF_TAKE12      (NGX_CONF_TAKE1|NGX_CONF_TAKE2)
-
 #define NGX_CONF_TAKE13      (NGX_CONF_TAKE1|NGX_CONF_TAKE3)
 
+#define NGX_CONF_TAKE23      (NGX_CONF_TAKE2|NGX_CONF_TAKE3)
+
 #define NGX_CONF_TAKE1234    (NGX_CONF_TAKE1|NGX_CONF_TAKE2|NGX_CONF_TAKE3   \
                               |NGX_CONF_TAKE4)
 
index 9312fba60cc51ba5b66d67e034bc3e5f9e3ce482..adb47911f6c81e158f8f542d30430e8d5ae2c1bf 100644 (file)
@@ -81,7 +81,7 @@ struct ngx_connection_s {
 
     ngx_hunk_t       *buffer;
 
-    int               number;
+    ngx_int_t         number;
 
     unsigned          pipeline:1;
     unsigned          unexpected_eof:1;
index a5d47d58c3b455d96157cd4e66699688d158f2a3..167907be97e213726cb6b8aa1c53cd14ddaea43d 100644 (file)
@@ -45,11 +45,12 @@ ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
 }
 
 
-ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s)
+ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s,
+                         int *matches, ngx_int_t size)
 {
     int  rc;
 
-    rc = pcre_exec(re, NULL, s->data, s->len, 0, 0, NULL, 0);
+    rc = pcre_exec(re, NULL, s->data, s->len, 0, 0, matches, size);
 
     if (rc == -1) {
         return NGX_DECLINED;
index b6828cf5437cdf4b32f90620a06d883e0a705396..3a99a2f36ba29d45b39dfb602bed27c1e2fc97a9 100644 (file)
@@ -15,7 +15,8 @@ typedef pcre  ngx_regex_t;
 void ngx_regex_init();
 ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
                                ngx_pool_t *pool, ngx_str_t *err);
-ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s);
+ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s,
+                         int *matches, ngx_int_t size);
 
 #define ngx_regex_exec_n  "pcre_exec()"
 
index 48cb33434b9e137aebcd04c9758661286d4d49ee..0d81c125b2efb190baa60534ed978b0ff0e3627c 100644 (file)
@@ -8,6 +8,7 @@
 
 
 extern ngx_module_t ngx_select_module;
+extern ngx_event_module_t ngx_select_module_ctx;
 
 #if (HAVE_KQUEUE)
 #include <ngx_kqueue_module.h>
diff --git a/src/http/modules/ngx_http_rewrite_handler.c b/src/http/modules/ngx_http_rewrite_handler.c
new file mode 100644 (file)
index 0000000..03414aa
--- /dev/null
@@ -0,0 +1,340 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+#define NGX_HTTP_REWRITE_COPY_MATCH  0
+#define NGX_HTTP_REWRITE_COPY_SHORT  1
+#define NGX_HTTP_REWRITE_COPY_LONG   2
+
+
+typedef struct {
+    ngx_int_t    op;
+    size_t       len;
+    uintptr_t    data;
+} ngx_http_rewrite_op_t;
+
+
+typedef struct {
+    ngx_regex_t  *regex;
+    ngx_uint_t    msize;
+
+    ngx_array_t   ops;
+    ngx_uint_t    size;
+
+    ngx_str_t     re_name;
+    ngx_str_t     s_name;
+
+    unsigned      last:1;
+} ngx_http_rewrite_rule_t;
+
+
+typedef struct {
+    ngx_array_t   rules;
+    unsigned      log:1;
+} ngx_http_rewrite_srv_conf_t;
+
+
+static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf);
+static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd,
+                                   void *conf);
+static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle);
+
+
+static ngx_command_t  ngx_http_rewrite_commands[] = {
+
+    { ngx_string("rewrite"),
+      NGX_HTTP_SRV_CONF|NGX_CONF_TAKE23,
+      ngx_http_rewrite_rule,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      0,
+      NULL },
+
+      ngx_null_command
+};
+
+
+ngx_http_module_t  ngx_http_rewrite_module_ctx = {
+    NULL,                                  /* pre conf */
+
+    NULL,                                  /* create main configuration */
+    NULL,                                  /* init main configuration */
+
+    ngx_http_rewrite_create_loc_conf,      /* create server configuration */
+    NULL,                                  /* merge server configuration */
+
+    NULL,                                  /* create location configration */
+    NULL,                                  /* merge location configration */
+};
+
+
+ngx_module_t  ngx_http_rewrite_module = {
+    NGX_MODULE,
+    &ngx_http_rewrite_module_ctx,          /* module context */
+    ngx_http_rewrite_commands,             /* module directives */
+    NGX_HTTP_MODULE,                       /* module type */
+    ngx_http_rewrite_init,                 /* init module */
+    NULL                                   /* init child */
+};
+
+
+static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r)
+{
+    int                          *matches;
+    char                         *p;
+    size_t                        len;
+    uintptr_t                     data;
+    ngx_int_t                     rc, i, n, m;
+    ngx_str_t                     uri;
+    ngx_http_rewrite_op_t        *op;
+    ngx_http_rewrite_rule_t      *rule;
+    ngx_http_rewrite_srv_conf_t  *scf;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http rewrite handler");
+
+    scf = ngx_http_get_module_srv_conf(r, ngx_http_rewrite_module);
+
+    rule = scf->rules.elts;
+    for (i = 0; i < scf->rules.nelts; i++) {
+
+        if (rule[i].msize) {
+            if (!(matches = ngx_palloc(r->pool, rule[i].msize * sizeof(int)))) {
+                return NGX_HTTP_INTERNAL_SERVER_ERROR;
+            }
+
+        } else {
+            matches = NULL;
+        }
+
+        rc = ngx_regex_exec(rule[i].regex, &r->uri, matches, rule[i].msize);
+
+        if (rc == NGX_DECLINED) {
+            if (scf->log) {
+                ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
+                              "\"%s\" is not matched", rule[i].re_name.data);
+            }
+
+            continue;
+        }
+
+        if (rc < 0) {
+            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+                          ngx_regex_exec_n
+                          " failed: %d on \"%s\" using \"%s\"",
+                          rc, r->uri.data, rule[i].re_name.data);
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        if (scf->log) {
+            ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
+                          "\"%s\" matched", rule[i].re_name.data);
+        }
+
+        uri.len = rule[i].size;
+
+        for (n = 1; n < rc; n++) {
+           uri.len += matches[2 * n + 1] - matches[2 * n];
+        }
+
+        if (!(uri.data = ngx_palloc(r->pool, uri.len + 1))) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        p = uri.data;
+
+        op = rule[i].ops.elts;
+        for (n = 0; n < rule[i].ops.nelts; n++) {
+            if (op[n].op == NGX_HTTP_REWRITE_COPY_SHORT) {
+                len = op[n].len;
+                data = op[n].data;
+                while (len--) {
+                    *p++ = data & 0xff;
+                    data >>= 8;
+                }
+
+            } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) {
+                p = ngx_cpymem(p, (void *) op[n].data, op[n].len);
+
+            } else { /* NGX_HTTP_REWRITE_COPY_MATCH */
+                m = 2 * op[n].data;
+                p = ngx_cpymem(p, &r->uri.data[matches[m]],
+                               matches[m + 1] - matches[m]);
+            }
+        }
+
+        *p = '\0';
+
+        if (scf->log) {
+            ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
+                          "rewritten uri: \"%s\"", uri.data);
+        }
+
+        r->uri = uri;
+
+        if (ngx_http_set_exten(r) != NGX_OK) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
+        if (rule[i].last) {
+            return NGX_DECLINED;
+        }
+    }
+
+    return NGX_DECLINED;
+}
+
+
+static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf)
+{
+    ngx_http_rewrite_srv_conf_t  *conf;
+
+    if (!(conf = ngx_palloc(cf->pool, sizeof(ngx_http_rewrite_srv_conf_t)))) {
+        return NGX_CONF_ERROR;
+    }
+
+    ngx_init_array(conf->rules, cf->pool, 5, sizeof(ngx_http_rewrite_rule_t),
+                   NGX_CONF_ERROR);
+
+    conf->log = 1;
+
+    return conf;
+}
+
+
+static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd,
+                                   void *conf)
+{
+    ngx_http_rewrite_srv_conf_t *scf = conf;
+
+    char                     *data, *p;
+    size_t                    len;
+    ngx_str_t                *value, err;
+    ngx_uint_t                i;
+    ngx_http_rewrite_op_t    *op;
+    ngx_http_rewrite_rule_t  *rule;
+    char                      errstr[NGX_MAX_CONF_ERRSTR];
+
+    if (!(rule = ngx_push_array(&scf->rules))) {
+        return NGX_CONF_ERROR;
+    }
+
+    ngx_init_array(rule->ops, cf->pool, 5, sizeof(ngx_http_rewrite_op_t),
+                   NGX_CONF_ERROR);
+
+    rule->msize = 0;
+    rule->size = 0;
+
+    value = cf->args->elts;
+
+    /* STUB */ {
+        err.len = NGX_MAX_CONF_ERRSTR;
+        err.data = errstr;
+
+        rule->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);
+    
+        if (rule->regex == NULL) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
+            return NGX_CONF_ERROR;
+        }
+    
+        rule->re_name = value[1];
+        rule->s_name = value[2];
+
+        for (i = 0; i < value[2].len; /* void */) {
+
+            if (!(op = ngx_push_array(&rule->ops))) {
+                return NGX_CONF_ERROR;
+            }
+
+            data = &value[2].data[i];
+
+            if (value[2].data[i] == '$'
+                && i < value[2].len
+                && value[2].data[i + 1] >= '1'
+                && value[2].data[i + 1] <= '9')
+            {
+                op->op = NGX_HTTP_REWRITE_COPY_MATCH; 
+                op->data = value[2].data[++i] - '0';
+
+                if (rule->msize < op->data) {
+                    rule->msize = op->data;
+                }
+
+                i++;
+
+            } else {
+                i++;
+
+                while (i < value[2].len && value[2].data[i] != '$') {
+                    i++;
+                }
+
+                len = &value[2].data[i] - data;
+                rule->size += len;
+
+                if (len) {
+
+                    op->len = len;
+
+                    if (len <= sizeof(uintptr_t)) {
+                        op->op = NGX_HTTP_REWRITE_COPY_SHORT; 
+                        op->data = 0;
+
+                        while (len--) {
+                            op->data <<= 8;
+                            op->data |= data[len];
+                        }
+
+                    } else {
+                        op->op = NGX_HTTP_REWRITE_COPY_LONG;
+
+                        if (!(p = ngx_palloc(cf->pool, len))) {
+                            return NGX_CONF_ERROR;
+                        }
+
+                        ngx_memcpy(p, data, len);
+                        op->data = (uintptr_t) p;
+                    }
+                }
+            }
+        }
+
+        rule->msize++;
+        rule->msize *= 3;
+
+        if (cf->args->nelts > 3) {
+            if (ngx_strcmp(value[3].data, "last") == 0) {
+                rule->last = 1;
+
+            } else {
+                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                                   "invalid parameter \"%s\"", value[3].data);
+                return NGX_CONF_ERROR;
+            }
+        }
+    }
+
+    return NGX_CONF_OK;
+}
+
+
+static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle)
+{
+    ngx_http_handler_pt        *h;
+    ngx_http_conf_ctx_t        *ctx;
+    ngx_http_core_main_conf_t  *cmcf;
+
+    ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index];
+    cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
+
+    h = ngx_push_array(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
+    if (h == NULL) {
+        return NGX_ERROR;
+    }
+
+    *h = ngx_http_rewrite_handler;
+
+    return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_status.c b/src/http/modules/ngx_http_status.c
new file mode 100644 (file)
index 0000000..1007364
--- /dev/null
@@ -0,0 +1,61 @@
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+static ngx_command_t  ngx_http_status_commands[] = {
+
+      ngx_null_command
+};
+
+
+ngx_http_module_t  ngx_http_status_module_ctx = {
+    NULL,                                  /* pre conf */
+
+    NULL,                                  /* create main configuration */
+    NULL,                                  /* init main configuration */
+
+    NULL,                                  /* create server configuration */
+    NULL,                                  /* merge server configuration */
+
+    ngx_http_status_create_loc_conf,       /* create location configration */
+    ngx_http_status_merge_loc_conf         /* merge location configration */
+};
+
+
+ngx_module_t  ngx_http_status_module = {
+    NGX_MODULE,
+    &ngx_http_status_module_ctx,           /* module context */ 
+    ngx_http_status_commands,              /* module directives */
+    NGX_HTTP_MODULE,                       /* module type */
+    ngx_http_status_init,                  /* init module */
+    NULL                                   /* init child */
+};
+
+
+static char http_states = "IRPCUWLK";
+
+
+int ngx_http_status_handler(ngx_http_request_t *r)
+{
+    ngx_int_t            i, http;
+    ngx_connection_t    *c;
+    ngx_http_request_t  *sr;
+
+    c = ngx_cycle->connections;
+
+    for (i = 0; i < ngx_cycle->connection_n; i++) {
+        if (c[i].module != http || c[i].data == NULL) {
+            continue;
+        }
+
+        if (c[i].data == NULL && c[i].fd != -1) {
+            'A'
+        }
+
+        sr = c[i].data;
+    }
+
+    return NGX_OK;
+}
index 9cb3fdc5f896f86332f2cd77a10458170339078e..8aeefac5f5d73b97126a0fe90bf81b434ed56106 100644 (file)
@@ -50,19 +50,19 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
     int                          port_found, addr_found, virtual_names;
     char                        *rv;
     struct sockaddr_in          *addr_in;
+    ngx_conf_t                   pcf;
     ngx_array_t                  in_ports;
     ngx_listening_t             *ls;
+    ngx_http_listen_t           *lscf;
     ngx_http_module_t           *module;
-    ngx_conf_t                   pcf;
     ngx_http_handler_pt         *h;
     ngx_http_conf_ctx_t         *ctx;
     ngx_http_in_port_t          *in_port, *inport;
     ngx_http_in_addr_t          *in_addr, *inaddr;
-    ngx_http_core_main_conf_t   *cmcf;
+    ngx_http_server_name_t      *s_name, *name;
     ngx_http_core_srv_conf_t   **cscfp, *cscf;
     ngx_http_core_loc_conf_t   **clcfp, *clcf;
-    ngx_http_listen_t           *lscf;
-    ngx_http_server_name_t      *s_name, *name;
+    ngx_http_core_main_conf_t   *cmcf;
 #if (WIN32)
     ngx_iocp_conf_t             *iocpcf;
 #endif
index 6d5bc0dd82b94d581df700e6f0fde285facbbdf7..873267f4014b5329e3727f2cba468de3451d7adf 100644 (file)
@@ -469,7 +469,7 @@ int ngx_http_find_location_config(ngx_http_request_t *r)
                                  clcfp[i]->regex ? "~ " : "",
                            clcfp[i]->name.data);
 
-            rc = ngx_regex_exec(clcfp[i]->regex, &r->uri);
+            rc = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0);
 
             if (rc == NGX_DECLINED) {
                 continue;
@@ -613,44 +613,55 @@ int ngx_http_error(ngx_http_request_t *r, int error)
 }
 
 
-int ngx_http_internal_redirect(ngx_http_request_t *r,
-                               ngx_str_t *uri, ngx_str_t *args)
+ngx_int_t ngx_http_set_exten(ngx_http_request_t *r)
 {
-    int  i;
-
-    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "internal redirect: \"%s\"", uri->data);
-
-    r->uri.len = uri->len;
-    r->uri.data = uri->data;
-
-    if (args) {
-        r->args.len = args->len;
-        r->args.data = args->data;
-    }
+    ngx_int_t  i;
 
     r->exten.len = 0;
     r->exten.data = NULL;
 
-    for (i = uri->len - 1; i > 1; i--) {
-        if (uri->data[i] == '.' && uri->data[i - 1] != '/') {
-            r->exten.len = uri->len - i - 1;
+    for (i = r->uri.len - 1; i > 1; i--) {
+        if (r->uri.data[i] == '.' && r->uri.data[i - 1] != '/') {
+            r->exten.len = r->uri.len - i - 1;
 
             if (r->exten.len > 0) {
-                ngx_test_null(r->exten.data,
-                              ngx_palloc(r->pool, r->exten.len + 1),
-                              NGX_HTTP_INTERNAL_SERVER_ERROR);
+                if (!(r->exten.data = ngx_palloc(r->pool, r->exten.len + 1))) {
+                    return NGX_ERROR;
+                }
 
-                ngx_cpystrn(r->exten.data, &uri->data[i + 1], r->exten.len + 1);
+                ngx_cpystrn(r->exten.data, &r->uri.data[i + 1],
+                            r->exten.len + 1);
             }
 
             break;
 
-        } else if (uri->data[i] == '/') {
+        } else if (r->uri.data[i] == '/') {
             break;
         }
     }
 
+    return NGX_OK;
+}
+
+
+int ngx_http_internal_redirect(ngx_http_request_t *r,
+                               ngx_str_t *uri, ngx_str_t *args)
+{
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "internal redirect: \"%s\"", uri->data);
+
+    r->uri.len = uri->len;
+    r->uri.data = uri->data;
+
+    if (args) {
+        r->args.len = args->len;
+        r->args.data = args->data;
+    }
+
+    if (ngx_http_set_exten(r) != NGX_OK) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     if (r->err_ctx) {
 
         /* allocate the new modules contexts */
@@ -872,7 +883,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
     clcf->loc_conf = ctx->loc_conf;
 
-    value = (ngx_str_t *) cf->args->elts;
+    value = cf->args->elts;
 
     if (cf->args->nelts == 3) {
         if (value[1].len == 1 && value[1].data[0] == '=') {
@@ -898,8 +909,7 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
                 return NGX_CONF_ERROR;
             }
 
-            clcf->name.len = value[2].len;
-            clcf->name.data = value[2].data;
+            clcf->name = value[2];
 #else
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "the using of the regex \"%s\" "
index 17ee46fcbb83f6002b02d638472b9f1117af707a..6673a18d5e419679d14254a7884c88d8f3550a6e 100644 (file)
@@ -156,6 +156,7 @@ int ngx_http_find_location_config(ngx_http_request_t *r);
 int ngx_http_core_translate_handler(ngx_http_request_t *r);
 
 ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r);
+ngx_int_t ngx_http_set_exten(ngx_http_request_t *r);
 
 int ngx_http_internal_redirect(ngx_http_request_t *r,
                                ngx_str_t *uri, ngx_str_t *args);
index ecdd0795491563b858f4c07a9798b7775d714a68..8b4c763581a1321d3b164437c7bcedee4826db10 100644 (file)
@@ -470,14 +470,14 @@ static char *ngx_http_log_header_out(ngx_http_request_t *r, char *buf,
         && ngx_strncasecmp(s->data, "Connection", s->len) == 0)
     {
         op->op = ngx_http_log_connection_header_out;
-        op->data = NULL;
+        op->data = (uintptr_t) NULL;
         return NULL;
     }
 
     if (s->len == sizeof("Transfer-Encoding") - 1
         && ngx_strncasecmp(s->data, "Transfer-Encoding", s->len) == 0) {
         op->op = ngx_http_log_transfer_encoding_header_out;
-        op->data = NULL;
+        op->data = (uintptr_t) NULL;
         return NULL;
     }
 
index 599114c4953eecd6b44f1f2378a0bbf77a84377f..92ab2f7a2267bf65a3596750c83c36c97962aa69 100644 (file)
@@ -463,7 +463,7 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
                     break;
                 }
 
-                if (ch == '-') {
+                if (ch == '-' || ch == '_' || ch == '~') {
                     break;
                 }
 
@@ -489,7 +489,7 @@ ngx_int_t ngx_http_parse_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
                 break;
             }
 
-            if (ch == '-') {
+            if (ch == '-' || ch == '_' || ch == '~') {
                 break;
             }
 
index 6a5fa981113cbbdee855c12f6459e3fca53ab0b6..6d11f4bbb9c8e86e385104f63824d51d82d458d9 100644 (file)
@@ -142,6 +142,8 @@ static void ngx_http_init_request(ngx_event_t *rev)
         }
     }
 
+    r->http_state = NGX_HTTP_INITING_REQUEST_STATE;
+
     /* find the server configuration for the address:port */
 
     /* AF_INET only */
@@ -1519,6 +1521,7 @@ void ngx_http_close_connection(ngx_connection_t *c)
     }
 
     c->fd = -1;
+    c->data = NULL;
 
     ngx_destroy_pool(c->pool);
 
@@ -1545,13 +1548,13 @@ static void ngx_http_client_error(ngx_http_request_t *r,
 
     if (ctx->url) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                     client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
-                     ctx->client, ctx->url);
+                    client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
+                    ctx->client, ctx->url);
 
     } else {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                     client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
-                     ctx->client);
+                    client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR],
+                    ctx->client);
     }
 
     r->connection->log->handler = ngx_http_log_error;
index 785c8e16e2b676d03f067fb918fb282399a5fd34..5b396b11c1f3bd0ffa8b99dd790eb7fe5c814acd 100644 (file)
 #define NGX_HTTP_GATEWAY_TIME_OUT          504
 
 
+typedef enum {
+    NGX_HTTP_INITING_REQUEST_STATE = 0,
+    NGX_HTTP_READING_REQUEST_STATE,
+    NGX_HTTP_PROCESS_REQUEST_STATE,
 
-#define NGX_HTTP_STATIC_HANDLER     0
-#define NGX_HTTP_DIRECTORY_HANDLER  1
+    NGX_HTTP_CONNECT_UPSTREAM_STATE,
+    NGX_HTTP_WRITING_UPSTREAM_STATE,
+    NGX_HTTP_READING_UPSTREAM_STATE,
+
+    NGX_HTTP_WRITING_REQUEST_STATE,
+    NGX_HTTP_LINGERING_CLOSE_STATE,
+    NGX_HTTP_KEEPALIVE_STATE
+} ngx_http_state_e;
 
 
 typedef struct {
@@ -223,6 +233,8 @@ struct ngx_http_request_s {
     void               **err_ctx;
     int                  err_status;
 
+    unsigned             http_state:4;
+
     /* URI is not started with '/' - "GET http://" */
     unsigned             unusual_uri:1;
     /* URI with "/.", "%" and on Win32 with "//" */
index f9e68b4eafe46e8a4fd19f02af62376e5c7a1271..bead5f9b3275b9ce241b5773c47753c528b5b3c6 100644 (file)
@@ -10,16 +10,18 @@ typedef int               ngx_err_t;
 
 #define NGX_ENOENT        ENOENT
 #define NGX_EINTR         EINTR
+#define NGX_ECHILD        ECHILD
 #define NGX_EACCES        EACCES
+#define NGX_EBUSY         EBUSY
 #define NGX_EEXIST        EEXIST
 #define NGX_ENOTDIR       ENOTDIR
+#define NGX_EPIPE         EPIPE
 #define NGX_EAGAIN        EWOULDBLOCK
 #define NGX_EINPROGRESS   EINPROGRESS
 #define NGX_EADDRINUSE    EADDRINUSE
 #define NGX_ECONNRESET    ECONNRESET
 #define NGX_ETIMEDOUT     ETIMEDOUT
 #define NGX_ECANCELED     ECANCELED
-#define NGX_ECHILD        ECHILD
 #define NGX_ENOMOREFILES  0
 
 
index 6ca15fb9aaec921ff83dcc8958f94f668ac794cd..63c877f7d8aec282697c80675681c25a5e6569ab 100644 (file)
@@ -26,7 +26,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
     char            *prev;
     off_t            sent, fprev;
     size_t           hsize, fsize, size;
-    ngx_int_t        eintr, eagain;
+    ngx_int_t        eintr, eagain, level;
     struct iovec    *iov;
     struct sf_hdtr   hdtr;
     ngx_err_t        err;
@@ -59,6 +59,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
         hsize = 0;
         eintr = 0;
         eagain = 0;
+        level = NGX_LOG_CRIT;
 
         ngx_init_array(header, c->pool, 10, sizeof(struct iovec),
                        NGX_CHAIN_ERROR);
@@ -186,10 +187,12 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
 
                 if (err == NGX_EINTR) {
                     eintr = 1;
-                }
 
-                if (err == NGX_EAGAIN) {
+                } else if (err == NGX_EAGAIN) {
                     eagain = 1;
+
+                } else if (err == NGX_EPIPE) {
+                    level = NGX_LOG_INFO;
                 }
 
                 if (err == NGX_EAGAIN || err == NGX_EINTR) {
@@ -199,7 +202,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
 
                 } else {
                     wev->error = 1;
-                    ngx_log_error(NGX_LOG_CRIT, c->log, err,
+                    ngx_log_error(level, c->log, err,
                                   "sendfile() failed");
                     return NGX_CHAIN_ERROR;
                 }
@@ -217,6 +220,9 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
 
                 if (err == NGX_EINTR) {
                     eintr = 1;
+
+                } else if (err == NGX_EPIPE) {
+                    level = NGX_LOG_INFO;
                 }
 
                 if (err == NGX_EAGAIN || err == NGX_EINTR) {
@@ -225,7 +231,7 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
 
                 } else {
                     wev->error = 1;
-                    ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
+                    ngx_log_error(level, c->log, err, "writev() failed");
                     return NGX_CHAIN_ERROR;
                 }
             }