diff options
Diffstat (limited to 'src/http/ngx_http_event.c')
| -rw-r--r-- | src/http/ngx_http_event.c | 342 |
1 files changed, 130 insertions, 212 deletions
diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c index 905af4736..cbea0c682 100644 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -13,6 +13,7 @@ #include <ngx_table.h> #include <ngx_hunk.h> #include <ngx_connection.h> +#include <ngx_inet.h> #include <ngx_http.h> #include <ngx_http_config.h> #include <ngx_http_core.h> @@ -33,19 +34,14 @@ static int ngx_http_process_request_line(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); - -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_event_request_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_block_read(ngx_event_t *ev); +static int ngx_http_read_discarded_body(ngx_event_t *ev); static int ngx_http_keepalive_handler(ngx_event_t *ev); -static int ngx_http_lingering_close(ngx_event_t *ev); +static int ngx_http_set_lingering_close(ngx_http_request_t *r); +static int ngx_http_lingering_close_handler(ngx_event_t *ev); #if 0 int ngx_http_special_response(ngx_http_request_t *r, int error); @@ -70,6 +66,8 @@ static char *header_errors[] = { static ngx_http_header_t headers_in[] = { { 4, "Host", offsetof(ngx_http_headers_in_t, host) }, { 10, "Connection", offsetof(ngx_http_headers_in_t, connection) }, + { 17, "If-Modified-Since", + offsetof(ngx_http_headers_in_t,if_modified_since) }, { 10, "User-Agent", offsetof(ngx_http_headers_in_t, user_agent) }, @@ -106,15 +104,11 @@ int ngx_http_init_connection(ngx_connection_t *c) 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.data = inet_ntoa((struct in_addr *) - ((char *)c->sockaddr + c->addr)); -#else - inet_ntop(c->family, (char *)c->sockaddr + c->addr, - c->addr_text.data, c->addr_text.len); -#endif - /**/ + ngx_test_null(c->addr_text.len, + ngx_inet_ntop(c->family, + (char *)c->sockaddr + c->addr, + c->addr_text.data, c->addr_text.len), + NGX_ERROR); ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)), NGX_ERROR); @@ -166,6 +160,7 @@ static int ngx_http_init_request(ngx_event_t *ev) c->data = r; r->connection = c; r->server = srv; + r->file.fd = NGX_INVALID_FILE; /* STUB */ r->srv_conf = ngx_srv_conf; @@ -189,6 +184,10 @@ static int ngx_http_init_request(ngx_event_t *ev) ngx_test_null(r->ctx, ngx_pcalloc(r->pool, sizeof(void *) * ngx_max_module), ngx_http_close_request(r)); + r->headers_out.headers = ngx_create_table(r->pool, 10); + r->headers_out.content_length = -1; + r->headers_out.last_modified_time = -1; + ev->event_handler = ngx_http_process_request_header; r->state_handler = ngx_http_process_request_line; r->header_timeout = 1; @@ -262,7 +261,7 @@ static int ngx_http_process_request_header(ngx_event_t *ev) } if (rc == NGX_OK) - return ngx_http_event_handler(r); + return ngx_http_event_request_handler(r); else return rc; } @@ -280,7 +279,8 @@ static int ngx_http_process_request_line(ngx_http_request_t *r) c = r->connection; if (rc == NGX_OK) { - r->uri.len = r->uri_end - r->uri_start; + r->uri.len = (r->args_start ? r->args_start - 1 : 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.data, r->uri_start, r->uri.len + 1); @@ -309,7 +309,8 @@ static int ngx_http_process_request_line(ngx_http_request_t *r) /* */ if (r->uri_ext) { - r->exten.len = r->uri_end - r->uri_ext; + r->exten.len = (r->args_start ? r->args_start - 1 : 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)); @@ -326,8 +327,6 @@ static int ngx_http_process_request_line(ngx_http_request_t *r) /* 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_headers; ctx = r->connection->log->data; @@ -372,7 +371,14 @@ static int ngx_http_process_request_headers(ngx_http_request_t *r) } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) { ngx_log_debug(r->connection->log, "HTTP header done"); - return NGX_OK; + + if (r->http_version > NGX_HTTP_VERSION_10 + && r->headers_in.host == NULL) + { + return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); + } else { + return NGX_OK; + } } else if (rc == NGX_AGAIN) { return NGX_AGAIN; @@ -422,7 +428,7 @@ 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_event_request_handler(ngx_http_request_t *r) { int rc; ngx_msec_t timeout; @@ -494,19 +500,82 @@ static int ngx_http_event_handler(ngx_http_request_t *r) } +static int ngx_http_writer(ngx_event_t *ev) +{ + int rc; + ngx_msec_t timeout; + ngx_connection_t *c; + ngx_http_request_t *r; + ngx_http_core_loc_conf_t *conf; + + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; + + c->sent = 0; + + rc = ngx_http_output_filter(r, NULL); + + ngx_log_debug(ev->log, "output filter in writer: %d" _ rc); + + if (rc == NGX_AGAIN) { + + if (c->sent > 0) { + conf = (ngx_http_core_loc_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); + ngx_log_debug(ev->log, "timeout: %d" _ timeout); + + ngx_del_timer(ev); + ngx_add_timer(ev, timeout); + } + + if (ev->oneshot) + if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, + NGX_ONESHOT_EVENT) == NGX_ERROR) { + return ngx_http_close_request(r); + } + + return rc; + } + + if (rc == NGX_ERROR) + return rc; + + /* rc == NGX_OK */ + + ngx_log_debug(ev->log, "http writer done"); + + if (!r->keepalive) { + if (r->lingering_close) { + ngx_http_set_lingering_close(r); + + } else { + return ngx_http_close_request(r); + } + } + + /* keepalive */ + + ngx_http_close_request(r); + c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; + c->read->event_handler = ngx_http_keepalive_handler; +} + + static int ngx_http_block_read(ngx_event_t *ev) { ngx_log_debug(ev->log, "http read blocked"); ev->blocked = 1; - return ngx_del_event(ev, NGX_READ_EVENT); + return ngx_del_event(ev, NGX_READ_EVENT, 0); } - -/* FIND PLACE ******************** */ - -void ngx_http_discard_body(ngx_http_request_t *r) +int ngx_http_discard_body(ngx_http_request_t *r) { ngx_log_debug(r->connection->log, "set discard body"); @@ -514,6 +583,8 @@ void ngx_http_discard_body(ngx_http_request_t *r) if (r->client_content_length) r->connection->read->event_handler = ngx_http_read_discarded_body; + + return NGX_OK; } @@ -554,6 +625,7 @@ static int ngx_http_read_discarded_body(ngx_event_t *ev) } +#if 0 static int ngx_http_discarded_read(ngx_event_t *ev) { ssize_t n; @@ -578,167 +650,49 @@ static int ngx_http_discarded_read(ngx_event_t *ev) return n; } - -/* ******************** */ - - -#if 0 -int ngx_http_handler(ngx_http_request_t *r) -{ - int rc; - - r->connection->unexpected_eof = 0; - r->lingering_close = 1; - - /* STUB: should find handler */ -#if 1 - 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; -} -#endif - - -#if 0 -static int ngx_http_set_default_handler(ngx_http_request_t *r) -{ - ngx_err_t err; - char *name, *loc, *file; - -#if 0 - /* STUB */ - r->handler = ngx_http_proxy_handler; - return NGX_OK; #endif -/* NO NEEDED - ngx_test_null(r->headers_out, - ngx_pcalloc(r->pool, sizeof(ngx_http_headers_out_t)), - NGX_HTTP_INTERNAL_SERVER_ERROR); -*/ - - if (*(r->uri_end - 1) == '/') { - r->handler = ngx_http_index_handler; - return NGX_OK; - } - - /* 20 bytes is spare space for some index name, i.e. index.html */ - r->filename_len = r->uri_end - r->uri_start + r->server->doc_root_len + 20; - - ngx_test_null(r->filename, - ngx_palloc(r->pool, r->filename_len), - NGX_HTTP_INTERNAL_SERVER_ERROR); - - r->location = ngx_cpystrn(r->filename, r->server->doc_root, - r->server->doc_root_len); - file = ngx_cpystrn(r->location, r->uri_start, - r->uri_end - r->uri_start + 1); - - ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename); - if (ngx_file_type(r->filename, &r->fileinfo) == -1) { - err = ngx_errno; - ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - ngx_file_type_n " %s failed", r->filename); - - 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); - *file++ = '/'; - *file = '\0'; - r->headers_out.location = r->location; - return NGX_HTTP_MOVED_PERMANENTLY; - } - - r->handler = ngx_http_static_handler; - - return NGX_OK; -} -#endif - - -static int ngx_http_writer(ngx_event_t *ev) +static int ngx_http_keepalive_handler(ngx_event_t *ev) { - int rc; - ngx_msec_t timeout; - ngx_connection_t *c; - ngx_http_request_t *r; - ngx_http_core_loc_conf_t *conf; + ssize_t n; + ngx_connection_t *c; + ngx_http_log_ctx_t *ctx; c = (ngx_connection_t *) ev->data; - r = (ngx_http_request_t *) c->data; - - c->sent = 0; - - rc = ngx_http_output_filter(r, NULL); - - ngx_log_debug(ev->log, "output filter in writer: %d" _ rc); - - if (rc == NGX_AGAIN) { - - if (c->sent > 0) { - conf = (ngx_http_core_loc_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); - ngx_log_debug(ev->log, "timeout: %d" _ timeout); - - ngx_del_timer(ev); - ngx_add_timer(ev, timeout); - } - if (ev->oneshot) - if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, - NGX_ONESHOT_EVENT) == NGX_ERROR) { - return ngx_http_close_request(r); - } - - return rc; - } + ngx_log_debug(ev->log, "http keepalive handler"); - if (rc == NGX_ERROR) - return rc; + if (ev->timedout) + return NGX_DONE; - /* rc == NGX_OK */ + n = ngx_event_recv(c, c->buffer->last.mem, + c->buffer->end - c->buffer->last.mem); - ngx_log_debug(ev->log, "http writer done"); + if (n == NGX_AGAIN || n == NGX_ERROR) + return n; - if (!r->keepalive) { - if (r->lingering_close) { - ngx_http_set_lingering_close(r); + ctx = (ngx_http_log_ctx_t *) ev->log->data; + ev->log->handler = NULL; - } else { - return ngx_http_close_request(r); - } + if (n == 0) { + ngx_log_error(NGX_LOG_INFO, ev->log, 0, + "client %s closed keepalive connection", ctx->client); + return NGX_DONE; } - /* keepalive */ + c->buffer->last.mem += n; + ev->log->handler = ngx_http_log_error; + ctx->action = "reading client request line"; - ngx_http_close_request(r); - c->buffer->pos.mem = c->buffer->last.mem = c->buffer->start; - c->read->event_handler = ngx_http_keepalive_handler; + return ngx_http_init_request(ev); } 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; + r->connection->read->event_handler = ngx_http_lingering_close_handler; ngx_del_timer(r->connection->read); ngx_add_timer(r->connection->read, r->server->lingering_timeout); @@ -753,7 +707,7 @@ static int ngx_http_set_lingering_close(ngx_http_request_t *r) return ngx_http_close_request(r); } - if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == NGX_ERROR) + if (ngx_shutdown_socket(r->connection->fd, NGX_WRITE_SHUTDOWN) == -1) { ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_socket_errno, ngx_shutdown_socket_n " failed"); @@ -764,53 +718,17 @@ 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_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; - - 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; - - 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"; - - return ngx_http_init_request(ev); -} - - -static int ngx_http_lingering_close(ngx_event_t *ev) -{ - ssize_t n; - ngx_msec_t timer; + ssize_t n; + ngx_msec_t timer; 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 lingering close"); + ngx_log_debug(ev->log, "http lingering close handler"); if (ev->timedout) return NGX_DONE; |
