aboutsummaryrefslogtreecommitdiff
path: root/src/http/ngx_http_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/ngx_http_event.c')
-rw-r--r--src/http/ngx_http_event.c296
1 files changed, 180 insertions, 116 deletions
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c
index 669f6d641..9c6a77b76 100644
--- 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 <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_static_handler(ngx_http_request_t *r);
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_header_line(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);
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_connection_t *c)
{
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_connection_t *c)
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_event_t *ev)
c = (ngx_connection_t *) ev->data;
srv = (ngx_http_server_t *) c->server;
- 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;
- }
-
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;
+ if (c->buffer == NULL) {
+ ngx_test_null(c->buffer,
+ ngx_create_temp_hunk(c->pool, srv->header_buffer_size,
+ 0, 0),
+ NGX_ERROR);
+ } else {
+ r->header_read = 1;
+ }
+
+ r->header_in = c->buffer;
+
ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log),
ngx_http_close_request(r));
@@ -177,31 +180,38 @@ static int ngx_http_process_request(ngx_event_t *ev)
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);
+ } else {
+ n = ngx_event_recv(c, r->header_in->last.mem,
+ r->header_in->end - r->header_in->last.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;
}
- return NGX_AGAIN;
- }
- if (n == NGX_ERROR)
- return ngx_http_close_request(r);
+ if (n == NGX_ERROR)
+ return ngx_http_close_request(r);
- ngx_log_debug(ev->log, "http read %d" _ n);
+ 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);
- }
+ 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)
@@ -241,11 +251,18 @@ static int ngx_http_process_request_line(ngx_http_request_t *r)
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_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_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_event_t *ev)
/* ******************** */
-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_request_t *r)
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_t *ev)
{
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 *ev)
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 *ev)
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 *ev)
/* 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;
+}
+
+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;
}
-#if 0
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);
- c = (ngx_connection_t *) ev->data;
+ if (n == NGX_AGAIN || n == NGX_ERROR)
+ return n;
- ctx = (ngx_http_log_ctx_t *) c->log->data;
+ ctx = (ngx_http_log_ctx_t *) ev->log->data;
+ ev->log->handler = NULL;
+
+ if (n == 0) {
+ ngx_log_error(NGX_LOG_INFO, ev->log, 0,
+ "client %s closed keepalive connection", ctx->client);
+ return NGX_DONE;
+ }
+
+ 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_event_t *ev)
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_event_t *ev)
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_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 */
@@ -709,6 +772,7 @@ static int ngx_http_redirect(ngx_http_request_t *r, int redirect)
return ngx_http_close_request(r);
}
+
static int ngx_http_error(ngx_http_request_t *r, int error)
{
/* STUB */