Mercurial > hg > nginx
diff src/http/ngx_http_event.c @ 13:2aba961a1d34
nginx-0.0.1-2002-09-16-19:01:44 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 16 Sep 2002 15:01:44 +0000 |
parents | 055ed05235ae |
children | 8dd06e2844f5 |
line wrap: on
line diff
--- a/src/http/ngx_http_event.c Fri Sep 13 14:47:42 2002 +0000 +++ b/src/http/ngx_http_event.c Mon Sep 16 15:01:44 2002 +0000 @@ -1,6 +1,6 @@ /* - TODO Win32 inet_ntoa - ngx_inet_ntop + TODO: Win32 inet_ntoa + ngx_inet_ntop */ #include <ngx_config.h> @@ -13,6 +13,7 @@ #include <ngx_connection.h> #include <ngx_http.h> #include <ngx_http_config.h> +#include <ngx_http_core.h> /* STUB */ #include <ngx_http_output_filter.h> @@ -20,10 +21,6 @@ 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_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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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_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 @@ 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 @@ { 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ return ngx_http_error(r, error); } + static int ngx_http_redirect(ngx_http_request_t *r, int redirect) { /* STUB */ @@ -709,6 +772,7 @@ return ngx_http_close_request(r); } + static int ngx_http_error(ngx_http_request_t *r, int error) { /* STUB */