]> git.kaiwu.me - nginx.git/commitdiff
nginx-0.0.1-2002-12-10-21:05:12 import
authorIgor Sysoev <igor@sysoev.ru>
Tue, 10 Dec 2002 18:05:12 +0000 (18:05 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Tue, 10 Dec 2002 18:05:12 +0000 (18:05 +0000)
24 files changed:
src/core/nginx.c
src/core/ngx_connection.h
src/core/ngx_listen.h
src/event/ngx_event.c
src/event/ngx_event_accept.c
src/http/modules/ngx_http_event_proxy_handler.c
src/http/modules/ngx_http_event_proxy_handler.h
src/http/modules/ngx_http_index_handler.c
src/http/modules/ngx_http_index_handler.h
src/http/modules/ngx_http_static_handler.c
src/http/ngx_http.c
src/http/ngx_http.h
src/http/ngx_http_config.c
src/http/ngx_http_core.c
src/http/ngx_http_event.c
src/http/ngx_http_get_time.c
src/http/ngx_http_header_filter.c
src/http/ngx_http_modules.c
src/http/ngx_http_output_filter.c
src/http/ngx_http_parse.c
src/http/ngx_http_parse_time.c [new file with mode: 0644]
src/http/ngx_http_special_response.c [new file with mode: 0644]
src/http/ngx_http_write_filter.c
src/os/unix/ngx_files.h

index b2f3f5fba6a30909aac700dcfd2e7333df5515d6..b33ce293e44e76afc1f23af19c97e15c914dd4a0 100644 (file)
@@ -18,6 +18,7 @@
 /* */
 
 
+static void ngx_set_signals(ngx_log_t *log);
 static void ngx_open_listening_sockets(ngx_log_t *log);
 
 
@@ -42,6 +43,8 @@ int main(int argc, char *const *argv)
     ngx_pool = ngx_create_pool(16 * 1024, &ngx_log);
     /* */
 
+    ngx_set_signals(&ngx_log);
+
     ngx_init_sockets(&ngx_log);
 
     /* TODO: read config */
@@ -70,6 +73,20 @@ int main(int argc, char *const *argv)
     return 0;
 }
 
+static void ngx_set_signals(ngx_log_t *log)
+{
+    struct sigaction sa;
+
+    ngx_memzero(&sa, sizeof(struct sigaction));
+    sa.sa_handler = SIG_IGN;
+    sigemptyset(&sa.sa_mask);
+    if (sigaction(SIGPIPE, &sa, NULL) == -1) {
+        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
+                      "sigaction(SIGPIPE, SIG_IGN) failed");
+        exit(1);
+    }
+}
+
 static void ngx_open_listening_sockets(ngx_log_t *log)
 {
     int           times, failed, reuseaddr, i;
index 2450ea3b83894623092b818aaf63337ed2009dd4..b486f4be85c56532595552261a1cb9cef5458f39 100644 (file)
@@ -5,6 +5,7 @@
 #include <ngx_log.h>
 #include <ngx_hunk.h>
 #include <ngx_alloc.h>
+#include <ngx_string.h>
 #include <ngx_server.h>
 
 typedef struct ngx_connection_s  ngx_connection_t;
@@ -38,8 +39,7 @@ struct ngx_connection_s {
     struct sockaddr  *sockaddr;
     socklen_t         socklen;
     size_t            addr;
-    char             *addr_text;
-    size_t            addr_textlen;
+    ngx_str_t         addr_text;
 
     ngx_hunk_t       *buffer;
     unsigned int      post_accept_timeout;
index 8108d837d6e897502a21123acac3975d690c1703..cf4a2ad0f69ae302665cb2826f5e050a3e1e6189 100644 (file)
@@ -14,8 +14,7 @@ typedef struct {
     struct sockaddr  *sockaddr;
     socklen_t         socklen;
     size_t            addr;
-    char             *addr_text;
-    size_t            addr_textlen;
+    ngx_str_t         addr_text;
 
     int           family;
     int           type;
index 68b6bf812ee67685b2c1ad51873bcfd6c7e805fe..8e918f0efca4b8862bee81682958028b39a24d17 100644 (file)
@@ -74,7 +74,6 @@ void ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
         ngx_connections[fd].sockaddr = ngx_palloc(pool, s[i].socklen);
         ngx_connections[fd].addr = s[i].addr;
         ngx_connections[fd].addr_text = s[i].addr_text;
-        ngx_connections[fd].addr_textlen = s[i].addr_textlen;
         ngx_connections[fd].post_accept_timeout = s[i].post_accept_timeout;
 
         ngx_connections[fd].server = s[i].server;
index fd36e3511f86ab7457720085b84872c22da480f2..ef6f85e48941ad16b10b2030b1952c735677acac 100644 (file)
@@ -54,7 +54,7 @@ int ngx_event_accept(ngx_event_t *ev)
         ngx_connections[s].family = cn->family;
         ngx_connections[s].socklen = cn->socklen;
         ngx_connections[s].addr = cn->addr;
-        ngx_connections[s].addr_textlen = cn->addr_textlen;
+        ngx_connections[s].addr_text.len = cn->addr_text.len;
         ngx_connections[s].post_accept_timeout = cn->post_accept_timeout;
 
         ngx_read_events[s].data = ngx_write_events[s].data
index b67bb2516f76f92e5d6b8754dae73c2226d0af89..af3546863ebd549a108182f2928357223b23560e 100644 (file)
@@ -65,8 +65,9 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
     ngx_chain_t      *chain;
     ngx_table_elt_t  *header;
 
-    /* "+ 4" is for "\r\n" after request line and at the header end */
-    len = r->request_line.len + 4;
+    /* 2 is for "\r\n" after request line
+       and 2 is for "\r\n" at the header end */
+    len = r->request_line.len + 2 + 2;
 
     /* "Connection: close\r\n" */
     len += sizeof(conn_close) - 1;
@@ -79,8 +80,8 @@ static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_request_t *r)
         if (&header[i] == r->headers_in.connection)
             continue;
 
-        /* "+ 4" is for ": " and "\r\n" */
-        len += header[i].key.len + header[i].value.len + 4;
+        /* 2 is for ": " and 2 is for "\r\n" */
+        len += header[i].key.len + 2 + header[i].value.len + 2;
     }
 
     /* STUB */ len++;
@@ -320,6 +321,7 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
         ngx_http_proxy_process_status_line(r, p)
         ngx_http_proxy_process_reponse_header(r, p) */
 
+#if 0
     do {
         rc = (p->state_handler)(r, p);
 
@@ -329,6 +331,7 @@ static int ngx_http_proxy_read_response_header(ngx_event_t *ev)
         /* rc == NGX_OK || rc == NGX_AGAIN */
 
     } while (p->header_in->pos.mem < p->header_in->last.mem);
+#endif
 
     ev->event_handler = ngx_http_proxy_read_response_body;
     if (p->header_in->end - p->header_in->last.mem == 0)
@@ -342,11 +345,11 @@ static int ngx_http_proxy_process_status_line(ngx_http_request_t *r,
 {
     int  rc;
 
-    ngx_log_debug(r->connection->log, "STATUS: %d" _ p->status);
-
     rc = ngx_read_http_proxy_status_line(p);
 
-    ngx_log_debug(r->connection->log, "STATUS: %d" _ p->status);
+    if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) {
+        p->status = 200;
+    }
 
     if (rc == NGX_OK) {
         /* STUB */
@@ -365,6 +368,11 @@ static int ngx_http_proxy_process_status_line(ngx_http_request_t *r,
     /* STUB */ return NGX_ERROR;
 }
 
+static int ngx_http_proxy_process_response_header(ngx_http_request_t *r,
+                                                  ngx_http_proxy_ctx_t *p)
+{
+}
+
 static int ngx_http_proxy_read_response_body(ngx_event_t *ev)
 {
     int     n;
@@ -560,8 +568,10 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
 
             ctx->status = ctx->status * 10 + ch - '0';
 
-            if (++ctx->status_count == 3)
+            if (++ctx->status_count == 3) {
                 state = sw_space_after_status;
+                ctx->status_line = p - 3;
+            }
 
             break;
 
@@ -569,7 +579,6 @@ fprintf(stderr, "state: %d, pos: %x, end: %x, char: '%c', status: %d\n",
          case sw_space_after_status:
             switch (ch) {
             case ' ':
-                ctx->status_text = p - 1;
                 state = sw_status_text;
                 break;
             case CR:
index ffc3a151cad3a002044611ba114204155c9d857c..596a1937a09ebb1e4762fe758724df407c160ecc 100644 (file)
@@ -30,7 +30,7 @@ struct ngx_http_proxy_ctx_s {
     int          state;
     int          status;
     int          status_count;
-    char        *status_text;
+    char        *status_line;
     char        *request_end;
     int        (*state_handler)(ngx_http_request_t *r, ngx_http_proxy_ctx_t *p);
 };
index 6877b334187bdbfda79c7713fa611f812708092e..b6e0adb854f084cad5c57dd3e3783db692ee1948 100644 (file)
 
 
 static void *ngx_http_index_create_conf(ngx_pool_t *pool);
-static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf, char *value);
+static void *ngx_http_index_merge_conf(ngx_pool_t *p,
+                                       void *parent, void *child);
+static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf,
+                                      ngx_str_t *value);
 
 static ngx_command_t ngx_http_index_commands[];
 
 
 ngx_http_module_t  ngx_http_index_module = {
     NGX_HTTP_MODULE,
+
     NULL,                                  /* create server config */
     ngx_http_index_create_conf,            /* create location config */
     ngx_http_index_commands,               /* module directives */
+
     NULL,                                  /* init module */
+    NULL,                                  /* translate handler */
+
     NULL,                                  /* init output body filter */
 };
 
@@ -36,32 +43,32 @@ static ngx_command_t ngx_http_index_commands[] = {
 
 };
 
+
 int ngx_http_index_handler(ngx_http_request_t *r)
 {
-    int          index_len, i;
-    char        *name, *loc, *file;
+    int          i;
+    char        *name, *file;
+    ngx_str_t    loc, *index;
     ngx_err_t    err;
     ngx_fd_t     fd;
 
-    ngx_http_index_file_t  *index;
     ngx_http_index_conf_t  *cf;
 
     cf = (ngx_http_index_conf_t *)
                             ngx_get_module_loc_conf(r, ngx_http_index_module);
 
-    index_len = (*(r->uri_end - 1) == '/') ? cf->max_index_len : 0;
-
     ngx_test_null(name,
-                  ngx_palloc(r->pool, r->uri_end - r->uri_start + index_len
-                                      + r->server->doc_root_len),
+                  ngx_palloc(r->pool,
+                             r->server->doc_root_len + r->uri.len
+                             + cf->max_index_len),
                   NGX_HTTP_INTERNAL_SERVER_ERROR);
 
-    loc = ngx_cpystrn(name, r->server->doc_root, r->server->doc_root_len);
-    file = ngx_cpystrn(loc, r->uri_start, r->uri_end - r->uri_start + 1);
+    loc.data = ngx_cpystrn(name, r->server->doc_root, r->server->doc_root_len);
+    file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1);
 
-    index = (ngx_http_index_file_t *) cf->indices->elts;
+    index = (ngx_str_t *) cf->indices->elts;
     for (i = 0; i < cf->indices->nelts; i++) {
-        ngx_memcpy(file, index[i].name, index[i].len);
+        ngx_memcpy(file, index[i].data, index[i].len + 1);
 
         fd = ngx_open_file(name, NGX_FILE_RDONLY);
         if (fd == -1) {
@@ -75,15 +82,18 @@ int ngx_http_index_handler(ngx_http_request_t *r)
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
 
-        r->filename = name; 
+        r->filename.len = r->server->doc_root_len + r->uri.len + index[i].len;
+        r->filename.data = name; 
         r->fd = fd; 
 
+        loc.len = r->uri.len + index[i].len;
         return ngx_http_internal_redirect(r, loc);
     }
 
     return NGX_DECLINED;
 }
 
+
 static void *ngx_http_index_create_conf(ngx_pool_t *pool)
 {
     ngx_http_index_conf_t  *conf;
@@ -91,38 +101,42 @@ static void *ngx_http_index_create_conf(ngx_pool_t *pool)
     ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_index_conf_t)), NULL);
 
     ngx_test_null(conf->indices,
-                  ngx_create_array(pool, sizeof(ngx_http_index_file_t), 3),
+                  ngx_create_array(pool, sizeof(ngx_str_t), 3),
                   NULL);
 
     return conf;
 }
 
+
 static void *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
 {
     ngx_http_index_conf_t *prev = (ngx_http_index_conf_t *) parent;
     ngx_http_index_conf_t *conf = (ngx_http_index_conf_t *) child;
-    ngx_http_index_file_t *index;
+    ngx_str_t  *index;
 
     if (conf->max_index_len == 0) {
         if (prev->max_index_len != 0)
             return prev;
 
         ngx_test_null(index, ngx_push_array(conf->indices), NULL);
-        index->name = NGX_HTTP_INDEX;
-        conf->max_index_len = index->len = sizeof(NGX_HTTP_INDEX) + 1;
+        index->len = sizeof(NGX_HTTP_INDEX) - 1;
+        index->data = NGX_HTTP_INDEX;
+        conf->max_index_len = sizeof(NGX_HTTP_INDEX);
     }
 
     return conf;
 }
 
-static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf, char *value)
+
+static char *ngx_http_index_set_index(ngx_pool_t *p, void *conf,
+                                      ngx_str_t *value)
 {
     ngx_http_index_conf_t *cf = (ngx_http_index_conf_t *) conf;
-    ngx_http_index_file_t *index;
+    ngx_str_t  *index;
 
     ngx_test_null(index, ngx_push_array(cf->indices), NULL);
-    index->name = value;
-    index->len = strlen(value) + 1;
+    index->len = value->len;
+    index->data = value->data;
 
     if (cf->max_index_len < index->len)
         cf->max_index_len = index->len;
index 721bf25200e7db47e11a17f5d6f0d3719738e17d..66261b0bc0a4cc37bae810346489e7bf1aad375d 100644 (file)
@@ -14,11 +14,6 @@ typedef struct {
     size_t        max_index_len;
 } ngx_http_index_conf_t;
 
-typedef struct {
-    char   *name;
-    size_t  len;
-} ngx_http_index_file_t;
-
 
 extern ngx_http_module_t  ngx_http_index_module;
 
index 6b2083991b09557b4ec7d5c74c21881aa473b48c..cded5f017461f5f52148888a96c2e358d8f277bd 100644 (file)
@@ -40,11 +40,13 @@ int ngx_http_static_handler(ngx_http_request_t *r)
     ctx = r->connection->log->data;
     ctx->action = "sending response";
 
-    r->fd = ngx_open_file(r->filename, NGX_FILE_RDONLY);
+    if (r->fd != -1)
+        r->fd = ngx_open_file(r->filename.data, NGX_FILE_RDONLY);
+
     if (r->fd == -1) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
                       "ngx_http_static_handler: "
-                      ngx_open_file_n " %s failed", r->filename);
+                      ngx_open_file_n " %s failed", r->filename.data);
 
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
@@ -52,7 +54,7 @@ int ngx_http_static_handler(ngx_http_request_t *r)
     if (ngx_stat_fd(r->fd, &r->fileinfo) == -1) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
                       "ngx_http_static_handler: "
-                      ngx_stat_fd_n " %s failed", r->filename);
+                      ngx_stat_fd_n " %s failed", r->filename.data);
 
         /* close fd */
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -64,25 +66,35 @@ int ngx_http_static_handler(ngx_http_request_t *r)
     r->headers_out.last_modified = ngx_file_mtime(r->fileinfo);
 */
 
+    ngx_test_null(r->headers_out.content_type,
+                  ngx_push_table(r->headers_out.headers),
+                  NGX_HTTP_INTERNAL_SERVER_ERROR);
+    r->headers_out.content_type->key.len = 12;
+    r->headers_out.content_type->key.data = "Content-Type";
+
     /* STUB */
-    if (r->exten) {
-        if (strcasecmp(r->exten, "html") == 0)
-            r->headers_out.content_type = "text/html; charset=koi8-r";
-        else if (strcasecmp(r->exten, "gif") == 0)
-            r->headers_out.content_type = "image/gif";
-        else if (strcasecmp(r->exten, "jpg") == 0)
-            r->headers_out.content_type = "image/jpeg";
-        else if (strcasecmp(r->exten, "pdf") == 0)
-            r->headers_out.content_type = "application/pdf";
+    if (r->exten.len) {
+        if (strcasecmp(r->exten.data, "html") == 0) {
+            r->headers_out.content_type->value.len = 25;
+            r->headers_out.content_type->value.data =
+                                                   "text/html; charset=koi8-r";
+        } else if (strcasecmp(r->exten.data, "gif") == 0) {
+            r->headers_out.content_type->value.len = 9;
+            r->headers_out.content_type->value.data = "image/gif";
+        } else if (strcasecmp(r->exten.data, "jpg") == 0) {
+            r->headers_out.content_type->value.len = 10;
+            r->headers_out.content_type->value.data = "image/jpeg";
+        }
 
     } else {
-        r->headers_out.content_type = "text/html; charset=koi8-r";
+        r->headers_out.content_type->value.len = 25;
+        r->headers_out.content_type->value.data = "text/html; charset=koi8-r";
     }
 
     /* STUB */
     rc = ngx_http_header_filter(r);
 /*
-    rc = ngx_send_http_header(r->headers_out);
+    rc = ngx_send_http_header(r);
 */
     if (r->header_only)
         return rc;
index 7cecd5d7019ae37a4ab5f3d21590a8deb6c9ff46..9c2e21b7bc564a079bd6a0385fda14664bc6b2af 100644 (file)
@@ -66,8 +66,8 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log)
     ls->sockaddr = (struct sockaddr *) &addr;
     ls->socklen = sizeof(struct sockaddr_in);
     ls->addr = offsetof(struct sockaddr_in, sin_addr);
-    ls->addr_text = addr_text;
-    ls->addr_textlen = INET_ADDRSTRLEN;
+    ls->addr_text.len = INET_ADDRSTRLEN;
+    ls->addr_text.data = addr_text;
     ls->backlog = -1;
     ls->post_accept_timeout = 10000;
     ls->nonblocking = 1;
index 30e3159f07cc51aae17d31cb24f4de9902f2c1f7..0f60fe694528602d9a21babc3f3e6645a3361ba6 100644 (file)
@@ -12,6 +12,8 @@
 #include <ngx_config_command.h>
 
 
+#define NGX_HTTP_VERSION_10       1000
+
 #define NGX_HTTP_GET   1
 #define NGX_HTTP_HEAD  2
 #define NGX_HTTP_POST  3
@@ -73,23 +75,29 @@ typedef struct {
 } ngx_http_headers_in_t;
 
 typedef struct {
-    int     status;
-    int     connection;
-    off_t   content_length;
-    char   *location;
-    char   *content_type;
-    char   *charset;
-    char   *etag;
-    char   *server;
-    time_t  date;
-    time_t  last_modified;
+    int               status;
+    ngx_str_t         status_line;
+
+    ngx_table_elt_t  *server;
+    ngx_table_elt_t  *date;
+    ngx_table_elt_t  *content_type;
+    ngx_table_elt_t  *location;
+    ngx_table_elt_t  *last_modified;
+
+    ngx_table_t      *headers;
+
+    off_t             content_length;
+    char             *charset;
+    char             *etag;
+    time_t            date_time;
+    time_t            last_modified_time;
 } ngx_http_headers_out_t;
 
 typedef struct ngx_http_request_s ngx_http_request_t;
 
 struct ngx_http_request_s {
-    char  *filename;
-    char  *location;
+    ngx_str_t  filename;
+
     ngx_fd_t  fd;
 
     void  **ctx;
@@ -116,8 +124,8 @@ struct ngx_http_request_s {
     int    http_minor;
 
     ngx_str_t  request_line;
-    char  *uri;
-    char  *exten;
+    ngx_str_t  uri;
+    ngx_str_t  exten;
     ngx_http_request_t *main;
 
     ngx_connection_t  *connection;
@@ -132,7 +140,6 @@ struct ngx_http_request_s {
     unsigned  lingering_close:1;
 
     unsigned  header_read:1;
-    unsigned  process_header:1;
     unsigned  header_timeout:1;
 
     unsigned  logging:1;
@@ -165,10 +172,15 @@ typedef struct {
 
 typedef struct {
     int               index;
+
     void           *(*create_srv_conf)(ngx_pool_t *p);
     void           *(*create_loc_conf)(ngx_pool_t *p);
     ngx_command_t    *commands;
+
     int             (*init_module)(ngx_pool_t *p);
+
+    int             (*translate_handler)(ngx_http_request_t *r);
+
     int             (*init_output_body_filter)(int (**next_filter)
                                      (ngx_http_request_t *r, ngx_chain_t *ch));
 } ngx_http_module_t;
index ab23a11cef6f2eae11d6c27fc86894d8837bc330..36037c6cf75a041bc9038e897bb4b5e96ee00e04 100644 (file)
@@ -100,13 +100,16 @@ ngx_http_write_filter_set_stub(ngx_pool_t *pool, ngx_http_module_t **modules)
 ngx_http_index_set_stub(ngx_pool_t *pool, ngx_http_module_t **modules)
 {
     int i;
+    ngx_str_t index;
     ngx_command_t *cmd;
 
     for (i = 0; modules[i]; i++) {
         if (modules[i] == &ngx_http_index_module) {
             for (cmd = modules[i]->commands; cmd->name; cmd++) {
                 if (strcmp(cmd->name, "index") == 0) {
-                    cmd->set(pool, ngx_loc_conf[i], "index.html");
+                    index.len = sizeof("index.html") - 1;
+                    index.data = "index.html";
+                    cmd->set(pool, ngx_loc_conf[i], &index);
                 }
             }
         }
index d8f829423e5e6b0963f7ec0617f851aa1ec9653b..99b4b7d77f7019332ef38cfaf523d53273aee952 100644 (file)
@@ -1,13 +1,21 @@
 
 #include <ngx_config.h>
+#include <ngx_core.h>
 #include <ngx_config_command.h>
 #include <ngx_http.h>
 #include <ngx_http_core.h>
 #include <ngx_http_config.h>
 
+/* STUB */
+#include <ngx_http_output_filter.h>
+int ngx_http_static_handler(ngx_http_request_t *r);
+int ngx_http_index_handler(ngx_http_request_t *r);
+int ngx_http_proxy_handler(ngx_http_request_t *r);
+/**/
 
 static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool);
 static void *ngx_http_core_create_loc_conf(ngx_pool_t *pool);
+static int ngx_http_core_translate_handler(ngx_http_request_t *r);
 
 
 static ngx_command_t ngx_http_core_commands[];
@@ -15,10 +23,14 @@ static ngx_command_t ngx_http_core_commands[];
 
 ngx_http_module_t  ngx_http_core_module = {
     NGX_HTTP_MODULE,
+
     ngx_http_core_create_srv_conf,         /* create server config */
     ngx_http_core_create_loc_conf,         /* create location config */
     ngx_http_core_commands,                /* module directives */
-    NULL,                                  /* init module */
+
+    /* STUB */ NULL,                                  /* init module */
+    ngx_http_core_translate_handler,       /* translate handler */
+
     NULL                                   /* init output body filter */
 };
 
@@ -35,6 +47,168 @@ static ngx_command_t ngx_http_core_commands[] = {
 };
 
 
+int ngx_http_handler(ngx_http_request_t *r)
+{
+    int  rc, i;
+
+    r->connection->unexpected_eof = 0;
+    r->lingering_close = 1;
+    r->keepalive = 1;
+
+#if 1
+    r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
+#endif
+
+    /* run translation phase */
+    for (i = 0; ngx_http_modules[i]; i++) {
+        if (ngx_http_modules[i]->translate_handler) {
+            rc = ngx_http_modules[i]->translate_handler(r);
+            if (rc == NGX_OK)
+                break;
+
+            if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
+                return ngx_http_special_response(r, rc);
+        }
+    }
+
+    rc = r->handler(r);
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
+        return ngx_http_special_response(r, rc);
+
+    return rc;
+}
+
+
+static int ngx_http_core_translate_handler(ngx_http_request_t *r)
+{
+    char      *loc, *last;
+    ngx_err_t  err;
+    ngx_table_elt_t  *h;
+
+    /* TODO: find location conf */
+
+    if (r->uri.data[r->uri.len - 1] == '/') {
+        /* TODO: find index handler */
+        /* STUB */ r->handler = ngx_http_index_handler;
+
+        return NGX_OK;
+    }
+
+    r->filename.len = r->server->doc_root_len + r->uri.len + 2;
+
+    ngx_test_null(r->filename.data,
+                  ngx_palloc(r->pool, r->filename.len + 1),
+                  NGX_HTTP_INTERNAL_SERVER_ERROR);
+
+    loc = ngx_cpystrn(r->filename.data, r->server->doc_root,
+                      r->server->doc_root_len);
+    last = ngx_cpystrn(loc, r->uri.data, r->uri.len + 1);
+
+    ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename.data);
+
+    if (ngx_file_type(r->filename.data, &r->fileinfo) == -1) {
+        err = ngx_errno;
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, err,
+                      ngx_file_type_n " %s failed", r->filename.data);
+
+        if (err == NGX_ENOENT)
+            return NGX_HTTP_NOT_FOUND;
+        else
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
+    if (ngx_is_dir(r->fileinfo)) {
+        ngx_log_debug(r->connection->log, "HTTP DIR: '%s'" _ r->filename.data);
+
+        /* BROKEN: need to include server name */
+
+        ngx_test_null(h, ngx_push_table(r->headers_out.headers),
+                      NGX_HTTP_INTERNAL_SERVER_ERROR);
+
+        *last++ = '/';
+        *last = '\0';
+        h->key.len = 8;
+        h->key.data = "Location" ;
+        h->value.len = last - loc;
+        h->value.data = loc;
+        r->headers_out.location = h;
+
+        return NGX_HTTP_MOVED_PERMANENTLY;
+    }
+
+    /* TODO: r->handler = loc_conf->default_handler; */
+    /* STUB */ r->handler = ngx_http_static_handler;
+
+    return NGX_OK;
+}
+
+
+
+int ngx_http_redirect(ngx_http_request_t *r, int redirect)
+{
+    /* STUB */
+
+    /* log request */
+
+    return ngx_http_close_request(r);
+}
+
+
+int ngx_http_error(ngx_http_request_t *r, int error) 
+{
+    /* STUB */
+    ngx_log_debug(r->connection->log, "http error: %d" _ error);
+
+    /* log request */
+
+    return ngx_http_close_request(r);
+}
+
+
+int ngx_http_close_request(ngx_http_request_t *r)
+{
+    ngx_assert((r->fd != -1), /* void */; , r->connection->log,
+               "file already closed");
+
+    if (r->fd != -1) {
+        if (ngx_close_file(r->fd) == -1)
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno,
+                          ngx_close_file_n " failed");
+    }
+
+/*
+    if (r->logging)
+        ngx_http_log_request(r);
+*/
+
+    ngx_destroy_pool(r->pool);
+
+    ngx_log_debug(r->connection->log, "http close");
+
+    ngx_del_timer(r->connection->read);
+    ngx_del_timer(r->connection->write);
+
+    return NGX_DONE;
+}
+
+
+int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri)
+{
+    ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri.data);
+
+    r->uri.len = uri.len;
+    r->uri.data = uri.data;
+
+    /* NEEDED ? */
+    r->uri_start = uri.data;
+    r->uri_end = uri.data + uri.len;
+    /**/
+
+    return ngx_http_handler(r);
+}
+
+
 static void *ngx_http_core_create_srv_conf(ngx_pool_t *pool)
 {
     ngx_http_core_srv_conf_t *conf;
index 30d1ac5b4a8970c4f7c14d2a64ed96289294c966..905af4736ce060230f9fbcfbf0fc107d2149b204 100644 (file)
 int ngx_http_static_handler(ngx_http_request_t *r);
 int ngx_http_index_handler(ngx_http_request_t *r);
 int ngx_http_proxy_handler(ngx_http_request_t *r);
-/* */
+/**/
 
 int ngx_http_init_connection(ngx_connection_t *c);
 
 static int ngx_http_init_request(ngx_event_t *ev);
-static int ngx_http_process_request(ngx_event_t *ev);
+static int ngx_http_process_request_header(ngx_event_t *ev);
 
 static int ngx_http_process_request_line(ngx_http_request_t *r);
-static int ngx_http_process_request_header(ngx_http_request_t *r);
+static int ngx_http_process_request_headers(ngx_http_request_t *r);
 static int ngx_http_process_request_header_line(ngx_http_request_t *r);
 
+static int ngx_http_event_handler(ngx_http_request_t *r);
 static int ngx_http_block_read(ngx_event_t *ev);
+
+
 static int ngx_http_read_discarded_body(ngx_event_t *ev);
 
-static int ngx_http_event_handler(ngx_http_request_t *r);
-static int ngx_http_handler(ngx_http_request_t *r);
+int ngx_http_handler(ngx_http_request_t *r);
 static int ngx_http_set_default_handler(ngx_http_request_t *r);
 
 static int ngx_http_writer(ngx_event_t *ev);
@@ -45,11 +47,13 @@ static int ngx_http_set_lingering_close(ngx_http_request_t *r);
 static int ngx_http_keepalive_handler(ngx_event_t *ev);
 static int ngx_http_lingering_close(ngx_event_t *ev);
 
-static int ngx_http_special_response(ngx_http_request_t *r, int error);
-static int ngx_http_redirect(ngx_http_request_t *r, int redirect);
-static int ngx_http_error(ngx_http_request_t *r, int error);
+#if 0
+int ngx_http_special_response(ngx_http_request_t *r, int error);
+int ngx_http_redirect(ngx_http_request_t *r, int redirect);
+int ngx_http_error(ngx_http_request_t *r, int error);
+int ngx_http_close_request(ngx_http_request_t *r);
+#endif
 
-static int ngx_http_close_request(ngx_http_request_t *r);
 static int ngx_http_close_connection(ngx_event_t *ev);
 static size_t ngx_http_log_error(void *data, char *buf, size_t len);
 
@@ -99,19 +103,22 @@ int ngx_http_init_connection(ngx_connection_t *c)
     ngx_memcpy(addr, c->sockaddr, c->socklen);
     c->sockaddr = addr;
 
-    ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen),
+    ngx_test_null(c->addr_text.data, ngx_palloc(c->pool, c->addr_text.len),
                   NGX_ERROR);
+
+    /* STUB: should be ngx_inet_ntop() */
 #if (WIN32)
-    c->addr_text = inet_ntoa((struct in_addr *)
+    c->addr_text.data = inet_ntoa((struct in_addr *)
                                               ((char *)c->sockaddr + c->addr));
 #else
     inet_ntop(c->family, (char *)c->sockaddr + c->addr,
-              c->addr_text, c->addr_textlen);
+              c->addr_text.data, c->addr_text.len);
 #endif
+    /**/
 
     ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)),
                   NGX_ERROR);
-    ctx->client = c->addr_text;
+    ctx->client = c->addr_text.data;
     ctx->action = "reading client request line";
     c->log->data = ctx;
     c->log->handler = ngx_http_log_error;
@@ -121,6 +128,7 @@ int ngx_http_init_connection(ngx_connection_t *c)
         return ngx_http_init_request(ev);
     } else {
 #endif
+        /* STUB: post_accept_timeout should be in http_conf */
         ngx_add_timer(ev, c->post_accept_timeout);
 #if (USE_KQUEUE)
         return ngx_add_event(ev, NGX_READ_EVENT, NGX_CLEAR_EVENT);
@@ -159,8 +167,10 @@ static int ngx_http_init_request(ngx_event_t *ev)
     r->connection = c;
     r->server = srv;
 
+    /* STUB */
     r->srv_conf = ngx_srv_conf;
     r->loc_conf = ngx_loc_conf;
+    /**/
 
     if (c->buffer == NULL) {
         ngx_test_null(c->buffer,
@@ -179,16 +189,15 @@ static int ngx_http_init_request(ngx_event_t *ev)
     ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module),
                   ngx_http_close_request(r));
 
-    ev->event_handler = ngx_http_process_request;
+    ev->event_handler = ngx_http_process_request_header;
     r->state_handler = ngx_http_process_request_line;
-    r->process_header = 1;
     r->header_timeout = 1;
 
-    return ngx_http_process_request(ev);
+    return ngx_http_process_request_header(ev);
 }
 
 
-static int ngx_http_process_request(ngx_event_t *ev)
+static int ngx_http_process_request_header(ngx_event_t *ev)
 {
     int n, rc;
     ngx_connection_t *c ;
@@ -213,6 +222,8 @@ static int ngx_http_process_request(ngx_event_t *ev)
             if (r->header_timeout) {
                 r->header_timeout = 0;
                 ngx_del_timer(ev);
+                /* STUB: r->server->header_timeout
+                         OR r->srv_conf->header_timeout ? */
                 ngx_add_timer(ev, r->server->header_timeout);
             }
             return NGX_AGAIN;
@@ -224,9 +235,8 @@ static int ngx_http_process_request(ngx_event_t *ev)
         ngx_log_debug(ev->log, "http read %d" _ n);
 
         if (n == 0) {
-            if (c->unexpected_eof)
-                ngx_log_error(NGX_LOG_INFO, c->log, 0,
-                              "client prematurely closed connection");
+            ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                          "client has prematurely closed connection");
             return ngx_http_close_request(r);
         }
 
@@ -235,7 +245,7 @@ static int ngx_http_process_request(ngx_event_t *ev)
 
     /* state_handlers are called in following order:
         ngx_http_process_request_line(r)
-        ngx_http_process_request_header(r) */
+        ngx_http_process_request_headers(r) */
 
     do {
         rc = (r->state_handler)(r);
@@ -243,10 +253,7 @@ static int ngx_http_process_request(ngx_event_t *ev)
         if (rc == NGX_ERROR)
             return rc;
 
-        /* rc == NGX_OK || rc == NGX_AGAIN */
-
-    } while (r->process_header
-             && r->header_in->pos.mem < r->header_in->last.mem);
+    } while (rc == NGX_AGAIN && r->header_in->pos.mem < r->header_in->last.mem);
 
     if (r->header_timeout) {
         r->header_timeout = 0;
@@ -254,7 +261,10 @@ static int ngx_http_process_request(ngx_event_t *ev)
         ngx_add_timer(ev, r->server->header_timeout);
     }
 
-    return rc;
+    if (rc == NGX_OK)
+        return ngx_http_event_handler(r);
+    else
+        return rc;
 }
 
 
@@ -270,10 +280,10 @@ static int ngx_http_process_request_line(ngx_http_request_t *r)
     c = r->connection;
 
     if (rc == NGX_OK) {
-        len = r->uri_end - r->uri_start + 1;
-        ngx_test_null(r->uri, ngx_palloc(r->pool, len),
+        r->uri.len = r->uri_end - r->uri_start;
+        ngx_test_null(r->uri.data, ngx_palloc(r->pool, r->uri.len + 1),
                       ngx_http_close_request(r));
-        ngx_cpystrn(r->uri, r->uri_start, len);
+        ngx_cpystrn(r->uri.data, r->uri_start, r->uri.len + 1);
 
         r->request_line.len = r->request_end - r->header_in->start;
         ngx_test_null(r->request_line.data,
@@ -299,27 +309,31 @@ static int ngx_http_process_request_line(ngx_http_request_t *r)
         /* */
 
         if (r->uri_ext) {
-            ngx_test_null(r->exten,
-                          ngx_palloc(r->pool, r->uri_end - r->uri_ext + 1), 
+            r->exten.len = r->uri_end - r->uri_ext;
+            ngx_test_null(r->exten.data,
+                          ngx_palloc(r->pool, r->exten.len + 1), 
                           ngx_http_close_request(r));
-            ngx_cpystrn(r->exten, r->uri_ext, r->uri_end - r->uri_ext + 1);
+            ngx_cpystrn(r->exten.data, r->uri_ext, r->exten.len + 1);
         }
 
         ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s %s" _
-                      r->method _ r->http_version _ r->uri _ r->exten);
+                      r->method _ r->http_version _
+                      r->uri.data _ r->exten.data);
 
         if (r->http_version == 9)
-            return ngx_http_event_handler(r);
+            return NGX_OK;
 
         /* TODO: check too long URI - no space for header, compact buffer */
 
         r->headers_in.headers = ngx_create_table(r->pool, 10);
+        /* THINK: when to create out.headers ? */
+        r->headers_out.headers = ngx_create_table(r->pool, 10);
 
-        r->state_handler = ngx_http_process_request_header;
+        r->state_handler = ngx_http_process_request_headers;
         ctx = r->connection->log->data;
         ctx->action = "reading client request headers";
 
-        return NGX_OK;
+        return NGX_AGAIN;
     }
 
     if (r->header_in->last.mem >= r->header_in->end) {
@@ -342,13 +356,13 @@ static int ngx_http_process_request_line(ngx_http_request_t *r)
 }
 
 
-static int ngx_http_process_request_header(ngx_http_request_t *r)
+static int ngx_http_process_request_headers(ngx_http_request_t *r)
 {
     int rc;
     ngx_http_log_ctx_t  *ctx;
 
     for ( ;; ) {
-        rc = ngx_read_http_header_line(r);
+        rc = ngx_read_http_header_line(r, r->header_in);
 
         /* TODO: check too long header, compact buffer */
 
@@ -358,7 +372,7 @@ static int ngx_http_process_request_header(ngx_http_request_t *r)
 
         } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
             ngx_log_debug(r->connection->log, "HTTP header done");
-            return ngx_http_event_handler(r);
+            return NGX_OK;
 
         } else if (rc == NGX_AGAIN) {
             return NGX_AGAIN;
@@ -408,7 +422,89 @@ static int ngx_http_process_request_header_line(ngx_http_request_t *r)
 }
 
 
-/* ******************** */
+static int ngx_http_event_handler(ngx_http_request_t *r)
+{
+    int rc;
+    ngx_msec_t  timeout;
+
+    ngx_del_timer(r->connection->read);
+    r->header_timeout = 0;
+
+    r->state_handler = NULL;
+    r->connection->read->event_handler = ngx_http_block_read;
+
+    rc = ngx_http_handler(r);
+
+    /* handler is still busy */
+    if (rc == NGX_WAITING)
+        return rc;
+
+    /* handler has done its work but transfer is not completed */
+    if (rc == NGX_AGAIN) {
+#if (HAVE_CLEAR_EVENT)
+        if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
+                          NGX_CLEAR_EVENT) == NGX_ERROR) {
+#else
+        if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
+                          NGX_ONESHOT_EVENT) == NGX_ERROR) {
+#endif
+            return ngx_http_close_request(r);
+        }
+
+        if (r->connection->sent > 0) {
+            ngx_log_debug(r->connection->log, "sent: " QD_FMT _
+                          r->connection->sent);
+            timeout = (ngx_msec_t) (r->connection->sent * 10);
+            ngx_log_debug(r->connection->log, "timeout: %d" _ timeout);
+            ngx_add_timer(r->connection->write, timeout);
+
+        } else {
+            ngx_add_timer(r->connection->write, 10000);
+        }
+
+        r->connection->write->event_handler = ngx_http_writer;
+        return rc;
+    }
+
+    if (rc == NGX_ERROR) {
+        /* log http request */
+        return ngx_http_close_request(r);
+    }
+
+    if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
+        return ngx_http_special_response(r, rc);
+
+    /* rc == NGX_OK */
+
+    if (!r->keepalive) {
+        if (r->lingering_close) {
+            return ngx_http_set_lingering_close(r);
+
+        } else {
+            return ngx_http_close_request(r);
+        }
+    }
+
+    /* keepalive */
+
+    ngx_http_close_request(r);
+    r->connection->buffer->pos.mem = r->connection->buffer->last.mem
+                                               = r->connection->buffer->start;
+    r->connection->read->event_handler = ngx_http_keepalive_handler;
+}
+
+
+static int ngx_http_block_read(ngx_event_t *ev)
+{
+    ngx_log_debug(ev->log, "http read blocked");
+
+    ev->blocked = 1;
+    return ngx_del_event(ev, NGX_READ_EVENT);
+}
+
+
+
+/* FIND PLACE ******************** */
 
 void ngx_http_discard_body(ngx_http_request_t *r)
 {
@@ -420,6 +516,7 @@ void ngx_http_discard_body(ngx_http_request_t *r)
         r->connection->read->event_handler = ngx_http_read_discarded_body;
 }
 
+
 static int ngx_http_read_discarded_body(ngx_event_t *ev)
 {
     size_t   size;
@@ -456,6 +553,7 @@ static int ngx_http_read_discarded_body(ngx_event_t *ev)
     return NGX_OK;
 }
 
+
 static int ngx_http_discarded_read(ngx_event_t *ev)
 {
     ssize_t n;
@@ -484,91 +582,16 @@ static int ngx_http_discarded_read(ngx_event_t *ev)
 /* ******************** */
 
 
-static int ngx_http_event_handler(ngx_http_request_t *r)
-{
-    int rc;
-    ngx_msec_t  timeout;
-
-    ngx_log_debug(r->connection->log, "UA: '%s: %s'" _
-                  r->headers_in.user_agent->key.data _
-                  r->headers_in.user_agent->value.data);
-
-    rc = ngx_http_handler(r);
-
-    /* handler is still busy */
-    if (rc == NGX_WAITING)
-        return rc;
-
-    /* handler has done its work but transfer is not completed */
-    if (rc == NGX_AGAIN) {
-#if (HAVE_CLEAR_EVENT)
-        if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
-                          NGX_CLEAR_EVENT) == NGX_ERROR) {
-#else
-        if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT,
-                          NGX_ONESHOT_EVENT) == NGX_ERROR) {
-#endif
-            return ngx_http_close_request(r);
-        }
-
-        if (r->connection->sent > 0) {
-            ngx_log_debug(r->connection->log, "sent: " QD_FMT _
-                          r->connection->sent);
-            timeout = (ngx_msec_t) (r->connection->sent * 10);
-            ngx_log_debug(r->connection->log, "timeout: %d" _ timeout);
-            ngx_add_timer(r->connection->write, timeout);
-
-        } else {
-            ngx_add_timer(r->connection->write, 10000);
-        }
-
-        r->connection->write->event_handler = ngx_http_writer;
-        return rc;
-    }
-
-    if (rc == NGX_ERROR) {
-        /* log http request */
-        return ngx_http_close_request(r);
-    }
-
-    if (rc >= NGX_HTTP_SPECIAL_RESPONSE)
-        return ngx_http_special_response(r, rc);
-
-    /* rc == NGX_OK */
-
-    if (!r->keepalive) {
-        if (r->lingering_close) {
-            return ngx_http_set_lingering_close(r);
-
-        } else {
-            return ngx_http_close_request(r);
-        }
-    }
-
-    /* keepalive */
-
-    ngx_http_close_request(r);
-    r->connection->buffer->pos.mem = r->connection->buffer->last.mem
-                                               = r->connection->buffer->start;
-    r->connection->read->event_handler = ngx_http_keepalive_handler;
-}
-
-static int ngx_http_handler(ngx_http_request_t *r)
+#if 0
+int ngx_http_handler(ngx_http_request_t *r)
 {
     int  rc;
 
-    ngx_del_timer(r->connection->read);
-    r->header_timeout = 0;
-
-    r->process_header = 0;
-    r->state_handler = NULL;
     r->connection->unexpected_eof = 0;
     r->lingering_close = 1;
 
-    r->connection->read->event_handler = ngx_http_block_read;
-
     /* STUB: should find handler */
-#if 0
+#if 1
     r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY;
 #endif
     rc = ngx_http_set_default_handler(r);
@@ -580,23 +603,16 @@ static int ngx_http_handler(ngx_http_request_t *r)
 
     return rc;
 }
+#endif
 
-int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri)
-{
-    ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri);
-
-    r->uri = uri;
-    r->uri_start = uri;
-    r->uri_end = uri + strlen(uri);
-    return ngx_http_handler(r);
-}
 
+#if 0
 static int ngx_http_set_default_handler(ngx_http_request_t *r)
 {
-    int   err, rc;
-    char *name, *loc, *file;
+    ngx_err_t  err;
+    char      *name, *loc, *file;
 
-#if 1
+#if 0
     /* STUB */
     r->handler = ngx_http_proxy_handler;
     return NGX_OK;
@@ -650,15 +666,7 @@ static int ngx_http_set_default_handler(ngx_http_request_t *r)
 
     return NGX_OK;
 }
-
-
-static int ngx_http_block_read(ngx_event_t *ev)
-{
-    ngx_log_debug(ev->log, "http read blocked");
-
-    ev->blocked = 1;
-    return ngx_del_event(ev, NGX_READ_EVENT);
-}
+#endif
 
 
 static int ngx_http_writer(ngx_event_t *ev)
@@ -726,6 +734,7 @@ static int ngx_http_writer(ngx_event_t *ev)
     c->read->event_handler = ngx_http_keepalive_handler;
 }
 
+
 static int ngx_http_set_lingering_close(ngx_http_request_t *r)
 {
     r->lingering_time = ngx_time() + r->server->lingering_time;
@@ -842,111 +851,6 @@ static int ngx_http_lingering_close(ngx_event_t *ev)
 }
 
 
-static int ngx_http_special_response(ngx_http_request_t *r, int error)
-{
-    return ngx_http_error(r, error);
-}
-
-
-static int ngx_http_redirect(ngx_http_request_t *r, int redirect)
-{
-    /* STUB */
-
-    /* log request */
-
-    return ngx_http_close_request(r);
-}
-
-
-static int ngx_http_error(ngx_http_request_t *r, int error)
-{
-    /* STUB */
-    ngx_log_debug(r->connection->log, "http error: %d" _ error);
-
-    /* log request */
-
-    return ngx_http_close_request(r);
-}
-
-#if 0
-
-static int ngx_process_http_request(ngx_http_request_t *r)
-{
-    int fd;
-    struct stat sb;
-    ngx_http_header_out_t  *header_out;
-    ngx_chunk_t            *header, *ch;
-
-    int index = (*(r->uri_end - 1) == '/') ? sizeof(NGX_INDEX) : 1;
-    char *name = ngx_palloc(r->pool,
-                           r->uri_end - r->uri_start + strlen(ngx_root) + index);
-    strcpy(name, ngx_root);
-    strcat(name, r->uri_start);
-    if (*(r->uri_end - 1) == '/')
-        strcat(name, NGX_INDEX);
-
-    ngx_log_debug(r->connection->log, "HTTP URI: '%s'", name);
-
-    if ((fd = open(name, O_RDONLY)) == -1) {
-        ngx_log_error(NGX_LOG_ERR, r->connection->log, errno,
-                     "open %s failed", name);
-        return -1;
-    }
-
-    if (fstat(fd, &sb) == -1) {
-        ngx_log_error(NGX_LOG_ERR, r->connection->log, errno,
-                     "fstat %s failed", name);
-        return -1;
-    }
-
-    header_out = ngx_palloc(r->pool, sizeof(ngx_http_header_out_t));
-
-    header_out->status = NGX_HTTP_OK;
-    header_out->content_length = sb.st_size;
-    header_out->last_modified = sb.st_mtime;
-    header_out->content_type = "text/html";
-    header_out->charset = "koi8-r";
-    header_out->date = time(NULL);
-    header_out->connection = NGX_HTTP_CONN_CLOSE;
-
-/*
-    header_out->connection = NGX_HTTP_CONN_KEEP_ALIVE;
-    r->connection->read->event_handler = ngx_http_init_request;
-*/
-
-    header = ngx_http_header(r, header_out);
-    ch = ngx_palloc(r->pool, sizeof(ngx_chunk_t));
-    ch->ident = fd;
-    ch->offset = 0;
-    ch->size = sb.st_size;
-    ch->next = NULL;
-    header->next = ch;
-
-    ngx_event_write(r->connection, header);
-
-    return 0;
-}
-
-#endif
-
-static int ngx_http_close_request(ngx_http_request_t *r)
-{
-/*
-    if (r->logging)
-        ngx_http_log_request(r);
-*/
-
-    ngx_destroy_pool(r->pool);
-
-    ngx_log_debug(r->connection->log, "http close");
-
-    ngx_del_timer(r->connection->read);
-    ngx_del_timer(r->connection->write);
-
-    return NGX_DONE;
-}
-
-
 static int ngx_http_close_connection(ngx_event_t *ev)
 {
     int    i, len;
index 5885df00b69d0d36e39941aea0dc4ec2b1cb0e52..33b14c38c010b29ffdfec2dcbf599674e16819c1 100644 (file)
@@ -9,5 +9,5 @@ ngx_http_get_time(char *buf, time_t t)
     struct tm *tp;
 
     tp = gmtime(&t);
-    return strftime(buf, 31, "%a, %d %b %Y %H:%M:%S GMT", tp);
+    return strftime(buf, 30, "%a, %d %b %Y %H:%M:%S GMT", tp);
 }
index 3c3ab91b7da2c5ff51ffc891a790caec424c8912..e8259a38653b35bf375e0ba6eda4a9ba685bf80a 100644 (file)
 #include <ngx_config.h>
 #include <ngx_core.h>
 #include <ngx_string.h>
+#include <ngx_table.h>
 #include <ngx_hunk.h>
 #include <ngx_http.h>
 
 
-typedef struct {
-    int    len;
-    char  *line;
-} line;
+#if 0
 
+ngx_http_module_t  ngx_http_header_filter_module = {
+    NGX_HTTP_MODULE,
 
-static line http_codes[] = {
-    { 6, "200 OK" }
+    NULL,                                  /* create server config */
+    NULL,                                  /* create location config */
+    NULL,                                  /* module directives */
+
+    NULL,                                  /* init module */
+    NULL,                                  /* translate handler */
+
+    ngx_http_header_filter_init            /* init output header filter */
+    NULL                                   /* init output body filter */
+};
+
+#endif
+
+
+static char server_string[] = "Server: " NGINX_VER CRLF;
+
+
+static ngx_str_t http_codes[] = {
+    { 6,  "200 OK" },
+
+    { 21, "301 Moved Permanently" },
+
+    { 15, "400 Bad Request" },
+    { 0,  NULL },
+    { 0,  NULL },
+    { 13, "403 Forbidden" },
+    { 13, "404 Not Found" }
 };
 
 
 
 int ngx_http_header_filter(ngx_http_request_t *r)
 {
-    int  status;
-    ngx_hunk_t   *h;
-    ngx_chain_t  *ch;
+    int  len, status, i;
+    ngx_hunk_t       *h;
+    ngx_chain_t      *ch;
+    ngx_table_elt_t  *header;
+
+    if (r->http_version < NGX_HTTP_VERSION_10)
+        return NGX_OK;
 
-    ngx_test_null(h, ngx_create_temp_hunk(r->pool, 1024, 0, 64),
-                  NGX_ERROR);
+    /* 9 is for "HTTP/1.1 ", 2 is for trailing "\r\n"
+       and 2 is for end of header */
+    len = 9 + 2 + 2;
+
+    /* status line */
+    if (r->headers_out.status_line.len) {
+        len += r->headers_out.status_line.len;
+    } else {
+        if (r->headers_out.status < NGX_HTTP_MOVED_PERMANENTLY)
+            status = r->headers_out.status - NGX_HTTP_OK;
+
+        else if (r->headers_out.status < NGX_HTTP_BAD_REQUEST)
+            status = r->headers_out.status - NGX_HTTP_MOVED_PERMANENTLY + 1;
+
+        else
+            status = r->headers_out.status - NGX_HTTP_BAD_REQUEST + 1 + 1;
+
+        len += http_codes[status].len;
+    }
+
+    if (r->headers_out.server && r->headers_out.server->key.len) {
+        len += r->headers_out.server->key.len
+               + r->headers_out.server->value.len + 2;
+    } else {
+        len += sizeof(server_string) - 1;
+    }
+
+    if (r->headers_out.date && r->headers_out.date->key.len) {
+        len += r->headers_out.date->key.len
+               + r->headers_out.date->value.len + 2;
+    } else {
+        /* "Date: ... \r\n"; */
+        len += 37;
+    }
 
-    status = r->headers_out.status - NGX_HTTP_OK;
+    /* 2^64 is 20 characters */
+    if (r->headers_out.content_length >= 0)
+        len += 48;
 
+#if 0
+    if (r->headers_out.content_type.len)
+        len += r->headers_out.content_type.len + 16;
+#endif
+
+    if (r->keepalive)
+        len += 24;
+    else
+        len += 19;
+
+    header = (ngx_table_elt_t *) r->headers_out.headers->elts;
+    for (i = 0; i < r->headers_out.headers->nelts; i++) {
+        if (header[i].key.len == 0)
+            continue;
+
+        len += header[i].key.len + 2 + header[i].value.len + 2;
+    }
+
+    ngx_test_null(h, ngx_create_temp_hunk(r->pool, len, 0, 64), NGX_ERROR);
+
+    /* "HTTP/1.1 " */
     ngx_memcpy(h->last.mem, "HTTP/1.1 ", 9);
     h->last.mem += 9;
-    ngx_memcpy(h->last.mem, http_codes[status].line, http_codes[status].len);
-    h->last.mem += http_codes[status].len;
-    *(h->last.mem++) = CR; *(h->last.mem++) = LF;
 
-#if 1
-    r->keepalive = 1;
-    ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24);
-    h->last.mem += 24;
-#endif
+    /* status line */
+    if (r->headers_out.status_line.len) {
+        ngx_memcpy(h->last.mem, r->headers_out.status_line.data,
+                   r->headers_out.status_line.len);
+        h->last.mem += r->headers_out.status_line.len;
 
-    ngx_memcpy(h->last.mem, "Date: ", 6);
-    h->last.mem += 6;
-    h->last.mem += ngx_http_get_time(h->last.mem, time(NULL));
+    } else {
+        ngx_memcpy(h->last.mem, http_codes[status].data,
+                   http_codes[status].len);
+        h->last.mem += http_codes[status].len;
+    }
     *(h->last.mem++) = CR; *(h->last.mem++) = LF;
 
+    if (!(r->headers_out.server && r->headers_out.server->key.len)) {
+        ngx_memcpy(h->last.mem, server_string, sizeof(server_string) - 1);
+        h->last.mem += sizeof(server_string) - 1;
+    }
+
+    if (!(r->headers_out.date && r->headers_out.date->key.len)) {
+        ngx_memcpy(h->last.mem, "Date: ", 6);
+        h->last.mem += 6;
+        h->last.mem += ngx_http_get_time(h->last.mem, time(NULL));
+        *(h->last.mem++) = CR; *(h->last.mem++) = LF;
+    }
+
     /* 2^64 is 20 characters  */
-    if (r->headers_out.content_length)
-        h->last.mem += ngx_snprintf(h->last.mem, 49, "Content-Length: %d" CRLF,
+    if (r->headers_out.content_length >= 0)
+        h->last.mem += ngx_snprintf(h->last.mem, 49, "Content-Length: %u" CRLF,
                                     r->headers_out.content_length);
 
-    /* check */
-
-    if (r->headers_out.content_type)
-        h->last.mem += ngx_snprintf(h->last.mem, 100, "Content-Type: %s" CRLF,
-                                    r->headers_out.content_type);
+#if 0
+    if (r->headers_out.content_type.len) {
+        ngx_memcpy(h->last.mem, "Content-Type: ", 14);
+        h->last.mem += 14;
+        ngx_memcpy(h->last.mem, r->headers_out.content_type.data,
+                   r->headers_out.content_type.len);
+        h->last.mem += r->headers_out.content_type.len;
+        *(h->last.mem++) = CR; *(h->last.mem++) = LF;
+    }
+#endif
 
-    ngx_memcpy(h->last.mem, "Server: ", 8);
-    h->last.mem += 8;
-    if (r->headers_out.server) {
-        h->last.mem = ngx_cpystrn(h->last.mem, r->headers_out.server,
-                                  h->end - h->last.mem);
-        /* check space */
+    if (r->keepalive) {
+        ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24);
+        h->last.mem += 24;
 
     } else {
-        ngx_memcpy(h->last.mem, NGINX_VER, sizeof(NGINX_VER) - 1);
-        h->last.mem += sizeof(NGINX_VER) - 1;
+        ngx_memcpy(h->last.mem, "Connection: close" CRLF, 19);
+        h->last.mem += 19;
+    }
+
+    for (i = 0; i < r->headers_out.headers->nelts; i++) {
+        if (header[i].key.len == 0)
+            continue;
+
+        ngx_memcpy(h->last.mem, header[i].key.data, header[i].key.len);
+        h->last.mem += header[i].key.len;
+        *(h->last.mem++) = ':' ; *(h->last.mem++) = ' ' ;
+
+        ngx_memcpy(h->last.mem, header[i].value.data, header[i].value.len);
+        h->last.mem += header[i].value.len;
+        *(h->last.mem++) = CR; *(h->last.mem++) = LF;
     }
-    *(h->last.mem++) = CR; *(h->last.mem++) = LF;
 
     /* end of HTTP header */
     *(h->last.mem++) = CR; *(h->last.mem++) = LF;
 
-    ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)),
-                  /* STUB */
-                  -1);
-/*
-                  NGX_HTTP_FILTER_ERROR);
-*/
+    ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR);
 
     ch->hunk = h;
     ch->next = NULL;
index 9676a0ffb7e68fb51b18c8d985130fe7c294552a..d8977ef3e6f67be1546b0a9b4daf0cc117432037 100644 (file)
@@ -9,7 +9,9 @@ extern ngx_http_module_t ngx_http_index_module;
 ngx_http_module_t *ngx_http_modules[] = {
     &ngx_http_write_filter_module,
     &ngx_http_output_filter_module,
-    &ngx_http_core_module,
+
     &ngx_http_index_module,
+    &ngx_http_core_module,
+
     NULL
 };
index be5c6d8cad260a4e80b4cb123fd5cde76538fa75..91c627524f575aaca87e2e6d1383f59be3df250b 100644 (file)
@@ -20,10 +20,14 @@ static ngx_command_t ngx_http_output_filter_commands[];
 
 ngx_http_module_t  ngx_http_output_filter_module = {
     NGX_HTTP_MODULE,
+
     NULL,                                  /* create server config */
     ngx_http_output_filter_create_conf,    /* create location config */
     ngx_http_output_filter_commands,       /* module directives */
+
     NULL,                                  /* init module */
+    NULL,                                  /* translate handler */
+
     ngx_http_output_filter_init            /* init output body filter */
 };
 
index 8d514db69205b4e9a1fdbb2d975377671d23b696..2b4cc72e365ebe2226ada47d5c5e27c031fb9c76 100644 (file)
@@ -312,7 +312,7 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
     }
 }
 
-int ngx_read_http_header_line(ngx_http_request_t *r)
+int ngx_read_http_header_line(ngx_http_request_t *r, ngx_hunk_t *h)
 {
     char   c, ch;
     char  *p;
@@ -329,14 +329,14 @@ int ngx_read_http_header_line(ngx_http_request_t *r)
     } state;
 
     state = r->state;
-    p = r->header_in->pos.mem;
+    p = h->pos.mem;
 
-    while (p < r->header_in->last.mem && state < sw_done) {
+    while (p < h->last.mem && state < sw_done) {
         ch = *p++;
 
 /*
 printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
-       state, p, r->header_in->last.mem, ch, p);
+       state, p, h->last.mem, ch, p);
 */
 
         switch (state) {
@@ -470,7 +470,7 @@ printf("\nstate: %d, pos: %x, end: %x, char: '%c' buf: %s",
         }
     }
 
-    r->header_in->pos.mem = p;
+    h->pos.mem = p;
 
     if (state == sw_done) {
         r->state = sw_start;
diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c
new file mode 100644 (file)
index 0000000..3e730a6
--- /dev/null
@@ -0,0 +1,64 @@
+
+time_t ngx_http_parse_time()
+{
+    enum {
+        sw_start = 0,
+    } state;
+
+    state = sw_start;
+
+    while () {
+        switch (state) {
+
+        case sw_start:
+            if (ch == ' ') {
+                ansi = 1;
+                state = sw_month;
+
+            } else if (ch == ',')
+                state = sw_day_first_digit;
+
+            break;
+
+        case sw_day_first_digit:
+            if (ch == ' ')
+                break;
+
+            if (ch >= '0' && ch <= '9') {
+                day = ch - '0';
+                state = sw_day;
+                break;
+
+            }
+
+            return NGX_ERROR;
+
+        case sw_day:
+            if (ansi && ch == ' ') {
+                state = sw_hour_first_digit;
+                break;
+            }
+
+            if (ch >= '0' && ch <= '9') {
+                day = ch - '0';
+                state = ansi ? sw_space_before_hour : sw_before_month;
+                break;
+            }
+
+            return NGX_ERROR;
+
+        case sw_before_month:
+            if (ch == ' ') {
+                rfc822 = 1;
+            }
+
+            if (ch == '-') {
+                rfc850 = 1;
+            }
+
+        case sw_space_before_hour:
+
+
+        }
+    }
+}
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
new file mode 100644 (file)
index 0000000..8ca49eb
--- /dev/null
@@ -0,0 +1,21 @@
+
+
+#include <ngx_config.h>
+#if 0
+#include <ngx_core.h>
+#endif
+#include <ngx_http.h>
+
+
+int ngx_http_special_response(ngx_http_request_t *r, int error)
+{
+    switch (error) {
+
+    default:
+        r->headers_out.status = error;
+        return ngx_http_header_filter(r);
+
+    }
+
+    return ngx_http_error(r, error);
+}
index edd41b0ce0c2e51698a1f6bc1a9deed5048c437b..9914f0b4e14354e41c7aa73037ee52ec7d6ed51b 100644 (file)
@@ -15,10 +15,14 @@ static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool);
 
 ngx_http_module_t  ngx_http_write_filter_module = {
     NGX_HTTP_MODULE,
+
     NULL,                                  /* create server config */
     ngx_http_write_filter_create_conf,     /* create location config */
     ngx_http_write_filter_commands,        /* module directives */
+
     NULL,                                  /* init module */
+    NULL,                                  /* translate handler */
+
     NULL                                   /* init output body filter */
 };
 
index 9369db05509272b0cca643ffb1260280ae409dff..90d6dd6c8f84dc8c62114e1d3ea04b904609a072 100644 (file)
@@ -12,6 +12,9 @@ typedef struct stat              ngx_file_info_t;
 #define ngx_open_file            open
 #define ngx_open_file_n          "open()"
 
+#define ngx_close_file           close
+#define ngx_close_file_n         "close()"
+
 #define ngx_read_file_n          "read()"
 
 #define NGX_FILE_RDONLY          O_RDONLY