# HG changeset patch # User Igor Sysoev # Date 1032188504 0 # Node ID 2aba961a1d3439fb8228abbf54851183f0a35715 # Parent 055ed05235ae2cf5e88bac13d2e15124620f07df nginx-0.0.1-2002-09-16-19:01:44 import diff --git a/src/core/ngx_config_command.c b/src/core/ngx_config_command.c --- a/src/core/ngx_config_command.c +++ b/src/core/ngx_config_command.c @@ -12,3 +12,15 @@ char *ngx_conf_set_size_slot(char *conf, *(int *) (conf + offset) = size; return NULL; } + +char *ngx_conf_set_time_slot(char *conf, int offset, char *value) +{ + int size; + + size = atoi(value); + if (size < 0) + return "value must be greater or equal to zero"; + + *(int *) (conf + offset) = size; + return NULL; +} diff --git a/src/core/ngx_config_command.h b/src/core/ngx_config_command.h --- a/src/core/ngx_config_command.h +++ b/src/core/ngx_config_command.h @@ -17,6 +17,7 @@ typedef struct { } ngx_command_t; char *ngx_conf_set_size_slot(char *conf, int offset, char *value); +char *ngx_conf_set_time_slot(char *conf, int offset, char *value); #endif _NGX_HTTP_CONFIG_COMMAND_H_INCLUDED_ 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 @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ struct ngx_connection_s { char *addr_text; size_t addr_textlen; + ngx_hunk_t *buffer; unsigned int post_accept_timeout; unsigned unexpected_eof:1; diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -186,7 +186,7 @@ int ngx_select_process_events(ngx_log_t } #endif - ngx_log_debug(log, "ngx_select_process_events: timer: %d" _ timer); + ngx_log_debug(log, "select timer: %d" _ timer); #if (WIN32) if ((ready = select(0, &work_read_fd_set, &work_write_fd_set, NULL, tp)) @@ -195,24 +195,21 @@ int ngx_select_process_events(ngx_log_t NULL, tp)) #endif == -1) { - ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, - "ngx_select_process_events: select failed"); + ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, "select() failed"); return NGX_ERROR; } - ngx_log_debug(log, "ngx_select_process_events: ready %d" _ ready); + ngx_log_debug(log, "select ready %d" _ ready); if (timer) { delta = ngx_msec() - delta; } else { ngx_assert((ready != 0), return NGX_ERROR, log, - "ngx_select_process_events: " - "select returns no events without timeout"); + "select() returns no events without timeout"); } - ngx_log_debug(log, "ngx_select_process_events: " - "timer: %d, delta: %d" _ timer _ delta); + ngx_log_debug(log, "select timer: %d, delta: %d" _ timer _ delta); if (timer) { if (delta >= timer) { @@ -234,25 +231,27 @@ int ngx_select_process_events(ngx_log_t } } - for (ev = event_queue.next; ev != &event_queue; ev = ev->next) { + for (ev = event_queue.next; ev != &event_queue; /* void */) { c = (ngx_connection_t *) ev->data; found = 0; if (ev->write) { if (FD_ISSET(c->fd, &work_write_fd_set)) { - ngx_log_debug(log, "ngx_select_process_events: write %d" _ + ngx_log_debug(log, "select write %d" _ c->fd); found = 1; } } else { if (FD_ISSET(c->fd, &work_read_fd_set)) { - ngx_log_debug(log, "ngx_select_process_events: read %d" _ + ngx_log_debug(log, "select read %d" _ c->fd); found = 1; } } + nx = ev->next; + if (found) { ev->ready = 1; @@ -270,10 +269,10 @@ int ngx_select_process_events(ngx_log_t ready--; } + ev = nx; } - ngx_assert((ready == 0), /* void */ ; , log, - "ngx_select_process_events: ready != events"); + ngx_assert((ready == 0), /* void */ ; , log, "select ready != events"); return NGX_OK; } 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 @@ -65,7 +65,19 @@ int ngx_http_static_handler(ngx_http_req */ /* STUB */ - r->headers_out->content_type = "text/html"; + 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"; + + } else { + r->headers_out->content_type = "text/html; charset=koi8-r"; + } /* STUB */ rc = ngx_http_header_filter(r); 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 @@ -19,15 +19,20 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ { ngx_listen_t *ls; + ngx_http_server.connection_pool_size = 16384; ngx_http_server.request_pool_size = 16384; ngx_http_server.header_timeout = 20000; ngx_http_server.header_buffer_size = 1024; ngx_http_server.discarded_buffer_size = 1500; + ngx_http_server.lingering_timeout = 5000; + ngx_http_server.lingering_time = 30; + #if (WIN32) ngx_http_server.doc_root = "html"; #else ngx_http_server.doc_root = "/home/is/work/xml/site-1.0.0/html"; + ngx_http_server.doc_root = "/home/is/dox/"; #endif ngx_http_server.doc_root_len = strlen(ngx_http_server.doc_root) + 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 @@ -44,22 +44,18 @@ typedef struct { char *doc_root; size_t doc_root_len; + size_t connection_pool_size; size_t request_pool_size; size_t header_buffer_size; size_t discarded_buffer_size; - unsigned int header_timeout; + ngx_msec_t header_timeout; + ngx_msec_t lingering_timeout; + time_t lingering_time; } ngx_http_server_t; typedef struct { - char *buff; - char *pos; - char *last; - char *end; -} ngx_buff_t; - -typedef struct { int status; int connection; off_t content_length; @@ -105,6 +101,7 @@ struct ngx_http_request_s { int http_minor; char *uri; + char *exten; ngx_http_request_t *main; ngx_connection_t *connection; @@ -118,6 +115,7 @@ struct ngx_http_request_s { unsigned keepalive:1; unsigned lingering_close:1; + unsigned header_read:1; unsigned process_header:1; unsigned header_timeout:1; diff --git a/src/http/ngx_http_core.c b/src/http/ngx_http_core.c new file mode 100644 --- /dev/null +++ b/src/http/ngx_http_core.c @@ -0,0 +1,49 @@ + +#include +#include +#include +#include +#include + + +static void *ngx_http_core_create_conf(ngx_pool_t *pool); + + +static ngx_command_t ngx_http_core_commands[]; + + +ngx_http_module_t ngx_http_core_module = { + NGX_HTTP_MODULE, + NULL, /* create server config */ + ngx_http_core_create_conf, /* create location config */ + ngx_http_core_commands, /* module directives */ + NULL, /* init module */ + NULL /* init output body filter */ +}; + + +static ngx_command_t ngx_http_core_commands[] = { + + {"send_timeout", ngx_conf_set_time_slot, + offsetof(ngx_http_core_conf_t, send_timeout), + NGX_HTTP_LOC_CONF, NGX_CONF_TAKE1, + "set timeout for sending response"}, + + {NULL} + +}; + + +static void *ngx_http_core_create_conf(ngx_pool_t *pool) +{ + ngx_http_core_conf_t *conf; + + ngx_test_null(conf, + ngx_pcalloc(pool, sizeof(ngx_http_core_conf_t)), + NULL); + + conf->send_timeout = NGX_CONF_UNSET; + + return conf; +} + diff --git a/src/http/ngx_http_core.h b/src/http/ngx_http_core.h new file mode 100644 --- /dev/null +++ b/src/http/ngx_http_core.h @@ -0,0 +1,16 @@ +#ifndef _NGX_HTTP_CORE_H_INCLUDED_ +#define _NGX_HTTP_CORE_H_INCLUDED_ + + +#include + + +typedef struct { + time_t send_timeout; +} ngx_http_core_conf_t; + + +extern ngx_http_module_t ngx_http_core_module; + + +#endif /* _NGX_HTTP_CORE_H_INCLUDED_ */ 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 @@ -1,6 +1,6 @@ /* - TODO Win32 inet_ntoa - ngx_inet_ntop + TODO: Win32 inet_ntoa + ngx_inet_ntop */ #include @@ -13,6 +13,7 @@ #include #include #include +#include /* STUB */ #include @@ -20,10 +21,6 @@ int ngx_http_static_handler(ngx_http_req int ngx_http_index_handler(ngx_http_request_t *r); /* */ -/* STUB */ -#define LINGERING_TIMEOUT 2 -#define SOME_LINGERING_TIME 30 - int ngx_http_init_connection(ngx_connection_t *c); static int ngx_http_init_request(ngx_event_t *ev); @@ -36,10 +33,12 @@ static int ngx_http_process_request_head 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); static int ngx_http_set_default_handler(ngx_http_request_t *r); static int ngx_http_writer(ngx_event_t *ev); +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); @@ -65,10 +64,12 @@ int ngx_http_init_connection(ngx_connect { ngx_event_t *ev; struct sockaddr *addr; + ngx_http_server_t *srv; ngx_http_log_ctx_t *ctx; ev = c->read; ev->event_handler = ngx_http_init_request; + srv = (ngx_http_server_t *) c->server; ngx_test_null(c->pool, ngx_create_pool(srv->connection_pool_size, ev->log), @@ -81,7 +82,8 @@ int ngx_http_init_connection(ngx_connect ngx_test_null(c->addr_text, ngx_palloc(c->pool, c->addr_textlen), NGX_ERROR); #if (WIN32) - c->addr_text = inet_ntoa((struct in_addr) ((char *)c->sockaddr + c->addr)); + c->addr_text = 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); @@ -130,26 +132,27 @@ static int ngx_http_init_request(ngx_eve c = (ngx_connection_t *) ev->data; srv = (ngx_http_server_t *) c->server; + ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), + NGX_ERROR); + + c->data = r; + r->connection = c; + r->server = srv; + + r->srv_conf = ngx_srv_conf; + r->loc_conf = ngx_loc_conf; + if (c->buffer == NULL) { ngx_test_null(c->buffer, ngx_create_temp_hunk(c->pool, srv->header_buffer_size, 0, 0), NGX_ERROR); } else { - c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; + r->header_read = 1; } - ngx_test_null(r, ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)), - NGX_ERROR); - - c->data = r; - r->connection = c; - r->server = srv; r->header_in = c->buffer; - r->srv_conf = ngx_srv_conf; - r->loc_conf = ngx_loc_conf; - ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), ngx_http_close_request(r)); @@ -177,32 +180,39 @@ static int ngx_http_process_request(ngx_ ngx_log_debug(ev->log, "http process request"); - n = ngx_event_recv(c, r->header_in->last.mem, - r->header_in->end - r->header_in->last.mem); + if (r->header_read) { + r->header_read = 0; + ngx_log_debug(ev->log, "http preread %d" _ + r->header_in->last.mem - r->header_in->pos.mem); - if (n == NGX_AGAIN) { - if (r->header_timeout) { - r->header_timeout = 0; - ngx_del_timer(ev); - ngx_add_timer(ev, r->server->header_timeout); - } - return NGX_AGAIN; - } + } else { + n = ngx_event_recv(c, r->header_in->last.mem, + r->header_in->end - r->header_in->last.mem); - if (n == NGX_ERROR) - return ngx_http_close_request(r); + if (n == NGX_AGAIN) { + if (r->header_timeout) { + r->header_timeout = 0; + ngx_del_timer(ev); + ngx_add_timer(ev, r->server->header_timeout); + } + return NGX_AGAIN; + } - ngx_log_debug(ev->log, "http read %d" _ n); + if (n == NGX_ERROR) + return ngx_http_close_request(r); - if (n == 0) { - if (c->unexpected_eof) - ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client prematurely closed connection"); - return ngx_http_close_request(r); + 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"); + return ngx_http_close_request(r); + } + + r->header_in->last.mem += n; } - r->header_in->last.mem += n; - /* state_handlers are called in following order: ngx_http_process_request_line(r) ngx_http_process_request_header(r) */ @@ -241,11 +251,18 @@ static int ngx_http_process_request_line ngx_http_close_request(r)); ngx_cpystrn(r->uri, r->uri_start, r->uri_end - r->uri_start + 1); - ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _ - r->method _ r->http_version _ r->uri); + if (r->uri_ext) { + ngx_test_null(r->exten, + ngx_palloc(r->pool, r->uri_end - r->uri_ext + 1), + ngx_http_close_request(r)); + ngx_cpystrn(r->exten, r->uri_ext, r->uri_end - r->uri_ext + 1); + } + + ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s %s" _ + r->method _ r->http_version _ r->uri _ r->exten); if (r->http_version == 9) - return ngx_http_handler(r); + return ngx_http_event_handler(r); /* TODO: check too long URI - no space for header, compact buffer */ @@ -292,7 +309,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_handler(r); + return ngx_http_event_handler(r); } else if (rc == NGX_AGAIN) { return NGX_AGAIN; @@ -397,29 +414,13 @@ static int ngx_http_discarded_read(ngx_e /* ******************** */ -static int ngx_http_handler(ngx_http_request_t *r) + +static int ngx_http_event_handler(ngx_http_request_t *r) { - int rc; + int rc; ngx_msec_t timeout; - 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 */ - r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; - rc = ngx_http_set_default_handler(r); - - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) - return ngx_http_special_response(r, rc); - - rc = r->handler(r); + rc = ngx_http_handler(r); /* transfer not completed */ if (rc == NGX_AGAIN) { @@ -460,25 +461,47 @@ static int ngx_http_handler(ngx_http_req if (!r->keepalive) { if (r->lingering_close) { - r->lingering_time = ngx_time() + SOME_LINGERING_TIME; - r->connection->read->event_handler = ngx_http_lingering_close; - ngx_del_timer(r->connection->read); - ngx_add_timer(r->connection->read, LINGERING_TIMEOUT * 1000); - if (ngx_add_event(r->connection->read, NGX_READ_EVENT, - NGX_ONESHOT_EVENT) == NGX_ERROR) { - return ngx_http_close_request(r); - } - if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) - == NGX_ERROR) - { - ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, - ngx_shutdown_socket_n " failed"); - return ngx_http_close_request(r); - } + 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) +{ + 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 + r->filter = NGX_HTTP_FILTER_NEED_IN_MEMORY; +#endif + rc = ngx_http_set_default_handler(r); + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) + return ngx_http_special_response(r, rc); + + rc = r->handler(r); + + return rc; } int ngx_http_internal_redirect(ngx_http_request_t *r, char *uri) @@ -548,17 +571,18 @@ static int ngx_http_block_read(ngx_event { ngx_log_debug(ev->log, "http read blocked"); - ngx_del_event(ev, NGX_READ_EVENT); ev->blocked = 1; + return ngx_del_event(ev, NGX_READ_EVENT); } static int ngx_http_writer(ngx_event_t *ev) { int rc; - unsigned int timeout; - ngx_connection_t *c; - ngx_http_request_t *r; + ngx_msec_t timeout; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_core_conf_t *conf; c = (ngx_connection_t *) ev->data; r = (ngx_http_request_t *) c->data; @@ -567,14 +591,20 @@ static int ngx_http_writer(ngx_event_t * rc = ngx_http_output_filter(r, NULL); - ngx_log_debug(ev->log, "output_filter: %d" _ rc); + ngx_log_debug(ev->log, "output filter in writer: %d" _ rc); if (rc == NGX_AGAIN) { if (c->sent > 0) { + conf = (ngx_http_core_conf_t *) + ngx_get_module_loc_conf(r->main ? r->main : r, + ngx_http_core_module); + + timeout = (ngx_msec_t) (c->sent * conf->send_timeout); + ngx_log_debug(ev->log, "sent: " QD_FMT _ c->sent); - timeout = (ngx_msec_t) (c->sent * 10); ngx_log_debug(ev->log, "timeout: %d" _ timeout); + ngx_del_timer(ev); ngx_add_timer(ev, timeout); } @@ -582,7 +612,6 @@ static int ngx_http_writer(ngx_event_t * if (ev->oneshot) if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, NGX_ONESHOT_EVENT) == NGX_ERROR) { - /* log http request */ return ngx_http_close_request(r); } @@ -594,62 +623,88 @@ static int ngx_http_writer(ngx_event_t * /* rc == NGX_OK */ - ngx_log_debug(ev->log, "ngx_http_writer done"); + ngx_log_debug(ev->log, "http writer done"); if (!r->keepalive) { if (r->lingering_close) { - r->lingering_time = ngx_time() + SOME_LINGERING_TIME; - r->connection->read->event_handler = ngx_http_lingering_close; - ngx_del_timer(r->connection->read); - ngx_add_timer(r->connection->read, LINGERING_TIMEOUT * 1000); - if (ngx_add_event(r->connection->read, NGX_READ_EVENT, - NGX_ONESHOT_EVENT) == NGX_ERROR) { - return ngx_http_close_request(r); - } - if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) - == NGX_ERROR) - { - ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, - ngx_shutdown_socket_n " failed"); - return ngx_http_close_request(r); - } + ngx_http_set_lingering_close(r); + } else { return ngx_http_close_request(r); } } /* keepalive */ - ev = r->connection->read; + ngx_http_close_request(r); - ev->event_handler = ngx_http_init_request; + c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; + c->read->event_handler = ngx_http_keepalive_handler; } -#if 0 +static int ngx_http_set_lingering_close(ngx_http_request_t *r) +{ + r->lingering_time = ngx_time() + r->server->lingering_time; + r->connection->read->event_handler = ngx_http_lingering_close; + + ngx_del_timer(r->connection->read); + ngx_add_timer(r->connection->read, r->server->lingering_timeout); + +#if (HAVE_CLEAR_EVENT) + if (ngx_add_event(r->connection->read, NGX_READ_EVENT, + NGX_CLEAR_EVENT) == NGX_ERROR) { +#else + if (ngx_add_event(r->connection->read, NGX_READ_EVENT, + NGX_ONESHOT_EVENT) == NGX_ERROR) { +#endif + return ngx_http_close_request(r); + } + + if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == NGX_ERROR) + { + ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, + ngx_shutdown_socket_n " failed"); + return ngx_http_close_request(r); + } + + return NGX_OK; +} + static int ngx_http_keepalive_handler(ngx_event_t *ev) { + ssize_t n; ngx_connection_t *c; ngx_http_log_ctx_t *ctx; + c = (ngx_connection_t *) ev->data; + ngx_log_debug(ev->log, "http keepalive"); if (ev->timedout) return NGX_DONE; - if (closed) - /* NGX_LOG_INFO or even silent */ - return NGX_ERROR; + n = ngx_event_recv(c, c->buffer->last.mem, + c->buffer->end - c->buffer->last.mem); + + if (n == NGX_AGAIN || n == NGX_ERROR) + return n; + + ctx = (ngx_http_log_ctx_t *) ev->log->data; + ev->log->handler = NULL; - c = (ngx_connection_t *) ev->data; + if (n == 0) { + ngx_log_error(NGX_LOG_INFO, ev->log, 0, + "client %s closed keepalive connection", ctx->client); + return NGX_DONE; + } - ctx = (ngx_http_log_ctx_t *) c->log->data; + c->buffer->last.mem += n; + ev->log->handler = ngx_http_log_error; ctx->action = "reading client request line"; - c->log->handler = ngx_http_log_error; return ngx_http_init_request(ev); } -#endif static int ngx_http_lingering_close(ngx_event_t *ev) { @@ -666,15 +721,21 @@ static int ngx_http_lingering_close(ngx_ if (ev->timedout) return NGX_DONE; - /* STUB */ timer = r->lingering_time - ngx_time(); if (timer <= 0) return NGX_DONE; - if (r->discarded_buffer == NULL) - ngx_test_null(r->discarded_buffer, - ngx_palloc(r->pool, r->server->discarded_buffer_size), - NGX_ERROR); + if (r->discarded_buffer == NULL) { + if (r->header_in->end - r->header_in->last.mem + >= r->server->discarded_buffer_size) { + r->discarded_buffer = r->header_in->last.mem; + + } else { + ngx_test_null(r->discarded_buffer, + ngx_palloc(c->pool, r->server->discarded_buffer_size), + NGX_ERROR); + } + } n = ngx_event_recv(c, r->discarded_buffer, r->server->discarded_buffer_size); @@ -685,11 +746,12 @@ static int ngx_http_lingering_close(ngx_ if (n == 0) return NGX_DONE; - if (timer > LINGERING_TIMEOUT) - timer = LINGERING_TIMEOUT; + timer *= 1000; + if (timer > r->server->lingering_timeout) + timer = r->server->lingering_timeout; ngx_del_timer(ev); - ngx_add_timer(ev, timer * 1000); + ngx_add_timer(ev, timer); return NGX_OK; } @@ -700,6 +762,7 @@ static int ngx_http_special_response(ngx return ngx_http_error(r, error); } + static int ngx_http_redirect(ngx_http_request_t *r, int redirect) { /* STUB */ @@ -709,6 +772,7 @@ static int ngx_http_redirect(ngx_http_re return ngx_http_close_request(r); } + static int ngx_http_error(ngx_http_request_t *r, int error) { /* STUB */ 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 @@ -31,14 +31,20 @@ int ngx_http_header_filter(ngx_http_requ status = r->headers_out->status - NGX_HTTP_OK; - ngx_memcpy(h->last.mem, "HTTP/1.0 ", 9); + 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 + /* - memcpy(h->last.mem, "Date: ", 6); + 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; @@ -51,17 +57,20 @@ int ngx_http_header_filter(ngx_http_requ /* check */ - memcpy(h->last.mem, "Server: ", 8); + if (r->headers_out->content_type) + h->last.mem += ngx_snprintf(h->last.mem, 100, "Content-Type: %s" CRLF, + r->headers_out->content_type); + + 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 */ } else { - ngx_memcpy(h->last.mem, NGINX_VER, sizeof(NGINX_VER)); - h->last.mem += sizeof(NGINX_VER); + ngx_memcpy(h->last.mem, NGINX_VER, sizeof(NGINX_VER) - 1); + h->last.mem += sizeof(NGINX_VER) - 1; } *(h->last.mem++) = CR; *(h->last.mem++) = LF; 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 @@ -1,13 +1,15 @@ #include +extern ngx_http_module_t ngx_http_write_filter_module; extern ngx_http_module_t ngx_http_output_filter_module; -extern ngx_http_module_t ngx_http_write_filter_module; +extern ngx_http_module_t ngx_http_core_module; 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, NULL }; diff --git a/src/os/win32/ngx_socket.h b/src/os/win32/ngx_socket.h --- a/src/os/win32/ngx_socket.h +++ b/src/os/win32/ngx_socket.h @@ -5,6 +5,8 @@ #include #include +#define NGX_WRITE_SHUTDOWN SD_SEND + #define INET_ADDRSTRLEN 16 typedef SOCKET ngx_socket_t; @@ -19,6 +21,9 @@ void ngx_init_sockets(ngx_log_t *log); int ngx_nonblocking(ngx_socket_t s); #define ngx_nonblocking_n "ioctlsocket(FIONBIO)" +#define ngx_shutdown_socket shutdown +#define ngx_shutdown_socket_n "shutdown()" + #define ngx_close_socket closesocket #define ngx_close_socket_n "closesocket()"