# HG changeset patch # User Igor Sysoev # Date 1039543512 0 # Node ID 77c7629a262765d7d567c477c67e1a2aca0e6ad2 # Parent f540a63026c94bbbdc9fc9d01b36d909d4b86b07 nginx-0.0.1-2002-12-10-21:05:12 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -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; diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -5,6 +5,7 @@ #include #include #include +#include #include 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; diff --git a/src/core/ngx_listen.h b/src/core/ngx_listen.h --- a/src/core/ngx_listen.h +++ b/src/core/ngx_listen.h @@ -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; diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -74,7 +74,6 @@ void ngx_pre_thread(ngx_array_t *ls, ngx 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; diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -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 diff --git a/src/http/modules/ngx_http_event_proxy_handler.c b/src/http/modules/ngx_http_event_proxy_handler.c --- a/src/http/modules/ngx_http_event_proxy_handler.c +++ b/src/http/modules/ngx_http_event_proxy_handler.c @@ -65,8 +65,9 @@ static ngx_chain_t *ngx_http_proxy_creat 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_creat 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_ 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_ /* 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 { 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 /* 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 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 case sw_space_after_status: switch (ch) { case ' ': - ctx->status_text = p - 1; state = sw_status_text; break; case CR: diff --git a/src/http/modules/ngx_http_event_proxy_handler.h b/src/http/modules/ngx_http_event_proxy_handler.h --- a/src/http/modules/ngx_http_event_proxy_handler.h +++ b/src/http/modules/ngx_http_event_proxy_handler.h @@ -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); }; diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -11,17 +11,24 @@ 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_comm }; + 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_requ 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_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; diff --git a/src/http/modules/ngx_http_index_handler.h b/src/http/modules/ngx_http_index_handler.h --- a/src/http/modules/ngx_http_index_handler.h +++ b/src/http/modules/ngx_http_index_handler.h @@ -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; diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -40,11 +40,13 @@ int ngx_http_static_handler(ngx_http_req 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_req 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_req 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; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -66,8 +66,8 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ 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; diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -12,6 +12,8 @@ #include +#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; diff --git a/src/http/ngx_http_config.c b/src/http/ngx_http_config.c --- a/src/http/ngx_http_config.c +++ b/src/http/ngx_http_config.c @@ -100,13 +100,16 @@ ngx_http_write_filter_set_stub(ngx_pool_ 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); } } } diff --git a/src/http/ngx_http_core.c b/src/http/ngx_http_core.c --- a/src/http/ngx_http_core.c +++ b/src/http/ngx_http_core.c @@ -1,13 +1,21 @@ #include +#include #include #include #include #include +/* STUB */ +#include +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_comma 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_comma }; +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; diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -22,22 +22,24 @@ 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( 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_connect 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_connect 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_eve 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_eve 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_ 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_ 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_ /* 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_ 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_ 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 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 /* */ 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 } -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_head } 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,90 +422,16 @@ static int ngx_http_process_request_head } -/* ******************** */ - -void ngx_http_discard_body(ngx_http_request_t *r) -{ - ngx_log_debug(r->connection->log, "set discard body"); - - ngx_del_timer(r->connection->read); - - if (r->client_content_length) - r->connection->read->event_handler = ngx_http_read_discarded_body; -} - -static int ngx_http_read_discarded_body(ngx_event_t *ev) -{ - size_t size; - ssize_t n; - ngx_connection_t *c; - ngx_http_request_t *r; - - c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; - - ngx_log_debug(ev->log, "http read discarded body"); - - if (ev->timedout) - return NGX_ERROR; - - if (r->discarded_buffer == NULL) - ngx_test_null(r->discarded_buffer, - ngx_palloc(r->pool, r->server->discarded_buffer_size), - NGX_ERROR); - - size = r->client_content_length; - if (size > r->server->discarded_buffer_size) - size = r->server->discarded_buffer_size; - - n = ngx_event_recv(c, r->discarded_buffer, size); - if (n == NGX_ERROR) - return NGX_ERROR; - - if (n == NGX_AGAIN) - return NGX_OK; - - r->client_content_length -= n; - /* XXX: what if r->client_content_length == 0 ? */ - return NGX_OK; -} - -static int ngx_http_discarded_read(ngx_event_t *ev) -{ - ssize_t n; - ngx_connection_t *c; - ngx_http_request_t *r; - - c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; - - ngx_log_debug(ev->log, "http discarded read"); - - if (ev->timedout) - return NGX_ERROR; - - if (r->discarded_buffer == NULL) - ngx_test_null(r->discarded_buffer, - ngx_palloc(r->pool, r->server->discarded_buffer_size), - NGX_ERROR); - - n = ngx_event_recv(c, r->discarded_buffer, - r->server->discarded_buffer_size); - - return n; -} - -/* ******************** */ - - 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); + 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); @@ -553,22 +493,105 @@ static int ngx_http_event_handler(ngx_ht r->connection->read->event_handler = ngx_http_keepalive_handler; } -static int ngx_http_handler(ngx_http_request_t *r) + +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) +{ + ngx_log_debug(r->connection->log, "set discard body"); + + ngx_del_timer(r->connection->read); + + if (r->client_content_length) + r->connection->read->event_handler = ngx_http_read_discarded_body; +} + + +static int ngx_http_read_discarded_body(ngx_event_t *ev) +{ + size_t size; + ssize_t n; + ngx_connection_t *c; + ngx_http_request_t *r; + + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; + + ngx_log_debug(ev->log, "http read discarded body"); + + if (ev->timedout) + return NGX_ERROR; + + if (r->discarded_buffer == NULL) + ngx_test_null(r->discarded_buffer, + ngx_palloc(r->pool, r->server->discarded_buffer_size), + NGX_ERROR); + + size = r->client_content_length; + if (size > r->server->discarded_buffer_size) + size = r->server->discarded_buffer_size; + + n = ngx_event_recv(c, r->discarded_buffer, size); + if (n == NGX_ERROR) + return NGX_ERROR; + + if (n == NGX_AGAIN) + return NGX_OK; + + r->client_content_length -= n; + /* XXX: what if r->client_content_length == 0 ? */ + return NGX_OK; +} + + +static int ngx_http_discarded_read(ngx_event_t *ev) +{ + ssize_t n; + ngx_connection_t *c; + ngx_http_request_t *r; + + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; + + ngx_log_debug(ev->log, "http discarded read"); + + if (ev->timedout) + return NGX_ERROR; + + if (r->discarded_buffer == NULL) + ngx_test_null(r->discarded_buffer, + ngx_palloc(r->pool, r->server->discarded_buffer_size), + NGX_ERROR); + + n = ngx_event_recv(c, r->discarded_buffer, + r->server->discarded_buffer_size); + + return n; +} + +/* ******************** */ + + +#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_req return rc; } - -int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri) -{ - ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri); +#endif - 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( 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 * 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_ } -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; diff --git a/src/http/ngx_http_get_time.c b/src/http/ngx_http_get_time.c --- a/src/http/ngx_http_get_time.c +++ b/src/http/ngx_http_get_time.c @@ -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); } diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -4,83 +4,187 @@ #include #include #include +#include #include #include -typedef struct { - int len; - char *line; -} line; +#if 0 + +ngx_http_module_t ngx_http_header_filter_module = { + NGX_HTTP_MODULE, + + 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 line http_codes[] = { - { 6, "200 OK" } +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; + + /* 9 is for "HTTP/1.1 ", 2 is for trailing "\r\n" + and 2 is for end of header */ + len = 9 + 2 + 2; - ngx_test_null(h, ngx_create_temp_hunk(r->pool, 1024, 0, 64), - NGX_ERROR); + /* 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; - 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; - 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; + 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 1 - r->keepalive = 1; - ngx_memcpy(h->last.mem, "Connection: keep-alive" CRLF, 24); - h->last.mem += 24; + 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; + } + + /* 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 - ngx_memcpy(h->last.mem, "Date: ", 6); - h->last.mem += 6; - h->last.mem += ngx_http_get_time(h->last.mem, time(NULL)); + 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; + + /* 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; + + } 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; } - *(h->last.mem++) = CR; *(h->last.mem++) = LF; + + 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; + } /* 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; diff --git a/src/http/ngx_http_modules.c b/src/http/ngx_http_modules.c --- a/src/http/ngx_http_modules.c +++ b/src/http/ngx_http_modules.c @@ -9,7 +9,9 @@ extern ngx_http_module_t ngx_http_index_ ngx_http_module_t *ngx_http_modules[] = { &ngx_http_write_filter_module, &ngx_http_output_filter_module, + + &ngx_http_index_module, &ngx_http_core_module, - &ngx_http_index_module, + NULL }; diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -20,10 +20,14 @@ static ngx_command_t ngx_http_output_fil 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 */ }; diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -312,7 +312,7 @@ printf("\nstate: %d, pos: %x, end: %x, c } } -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_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, c } } - 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 --- /dev/null +++ b/src/http/ngx_http_parse_time.c @@ -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 --- /dev/null +++ b/src/http/ngx_http_special_response.c @@ -0,0 +1,21 @@ + + +#include +#if 0 +#include +#endif +#include + + +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); +} diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -15,10 +15,14 @@ static void *ngx_http_write_filter_creat 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 */ }; diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -12,6 +12,9 @@ typedef struct stat ngx_fil #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