diff options
author | Igor Sysoev <igor@sysoev.ru> | 2002-09-02 14:48:24 +0000 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2002-09-02 14:48:24 +0000 |
commit | a58e3ca14300fce97b2124233afe140c8d59199f (patch) | |
tree | d24eff379cc7dfb5c6952f1bb15735cd63ba2179 /src/http | |
parent | 016b85270268989d769bade2004a7c628a47d726 (diff) | |
download | nginx-a58e3ca14300fce97b2124233afe140c8d59199f.tar.gz nginx-a58e3ca14300fce97b2124233afe140c8d59199f.zip |
nginx-0.0.1-2002-09-02-18:48:24 import
Diffstat (limited to 'src/http')
-rw-r--r-- | src/http/modules/ngx_http_header_filter.c | 9 | ||||
-rw-r--r-- | src/http/modules/ngx_http_static_handler.c | 47 | ||||
-rw-r--r-- | src/http/ngx_http.c | 10 | ||||
-rw-r--r-- | src/http/ngx_http.h | 18 | ||||
-rw-r--r-- | src/http/ngx_http_event.c | 384 | ||||
-rw-r--r-- | src/http/ngx_http_filter.c | 236 | ||||
-rw-r--r-- | src/http/ngx_http_output_filter.c | 253 | ||||
-rw-r--r-- | src/http/ngx_http_output_filter.h (renamed from src/http/ngx_http_filter.h) | 8 | ||||
-rw-r--r-- | src/http/ngx_http_write_filter.c | 10 | ||||
-rw-r--r-- | src/http/ngx_http_write_filter.h | 2 |
10 files changed, 552 insertions, 425 deletions
diff --git a/src/http/modules/ngx_http_header_filter.c b/src/http/modules/ngx_http_header_filter.c index efe0744b5..9cb1f4c30 100644 --- a/src/http/modules/ngx_http_header_filter.c +++ b/src/http/modules/ngx_http_header_filter.c @@ -2,6 +2,7 @@ #include <nginx.h> #include <ngx_config.h> +#include <ngx_core.h> #include <ngx_string.h> #include <ngx_hunk.h> #include <ngx_http.h> @@ -25,12 +26,8 @@ int ngx_http_header_filter(ngx_http_request_t *r) ngx_hunk_t *h; ngx_chain_t *ch; - ngx_test_null(h, ngx_get_hunk(r->pool, 1024, 0, 64), - /* STUB */ - -1); -/* - NGX_HTTP_FILTER_ERROR); -*/ + ngx_test_null(h, ngx_create_temp_hunk(r->pool, 1024, 0, 64), + NGX_ERROR); status = r->headers_out->status - NGX_HTTP_OK; diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c index 20d0b9e5f..0900a42cf 100644 --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -26,7 +26,7 @@ int ngx_http_static_handler(ngx_http_request_t *r) { int rc; ngx_hunk_t *h; - ngx_chain_t *ch; + ngx_http_log_ctx_t *ctx; /* ngx_http_event_static_handler_loc_conf_t *cf; @@ -36,6 +36,10 @@ int ngx_http_static_handler(ngx_http_request_t *r) */ + ngx_http_discard_body(r); + ctx = r->connection->log->data; + ctx->action = "sending response"; + r->fd = ngx_open_file(r->filename, NGX_FILE_RDONLY); if (r->fd == -1) { ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, @@ -45,7 +49,7 @@ int ngx_http_static_handler(ngx_http_request_t *r) return -1; } - if (ngx_stat_fd(r->fd, &r->file_info) == -1) { + 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); @@ -54,9 +58,9 @@ int ngx_http_static_handler(ngx_http_request_t *r) } r->headers_out->status = NGX_HTTP_OK; - r->headers_out->content_length = ngx_file_size(r->file_info); + r->headers_out->content_length = ngx_file_size(r->fileinfo); /* - r->headers_out->last_modified = ngx_file_mtime(r->file_info); + r->headers_out->last_modified = ngx_file_mtime(r->fileinfo); */ /* STUB */ @@ -73,39 +77,22 @@ int ngx_http_static_handler(ngx_http_request_t *r) /* TODO: NGX_HTTP_INTERNAL_SERVER_ERROR is too late */ /* STUB */ - ngx_test_null(h, ngx_get_hunk(r->pool, 1024, 0, 64), - /* STUB */ - -1); -/* - ngx_test_null(h, ngx_create_hunk(r->pool), NGX_HTTP_INTERNAL_SERVER_ERROR); -*/ + ngx_test_null(h, ngx_pcalloc(r->pool, sizeof(ngx_hunk_t)), + NGX_HTTP_INTERNAL_SERVER_ERROR); + h->type = NGX_HUNK_FILE|NGX_HUNK_LAST; - h->fd = r->fd; h->pos.file = 0; - h->last.file = ngx_file_size(r->file_info); + h->last.file = ngx_file_size(r->fileinfo); /* STUB */ - ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), - /* STUB */ - -1); -/* - NGX_HTTP_FILTER_ERROR); -*/ - -/* - ngx_test_null(ch, ngx_create_chain(r->pool), + ngx_test_null(h->file, ngx_pcalloc(r->pool, sizeof(ngx_file_t)), NGX_HTTP_INTERNAL_SERVER_ERROR); -*/ - ch->hunk = h; - ch->next = NULL; + h->file->fd = r->fd; + h->file->log = r->connection->log; - /* STUB */ - rc = ngx_http_write_filter(r, ch); - ngx_log_debug(r->connection->log, "write_filter: %d" _ rc); + rc = ngx_http_output_filter(r, h); + ngx_log_debug(r->connection->log, "0 output_filter: %d" _ rc); return rc; -/* - return ngx_http_filter(r, ch); -*/ } #if 0 diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 5410d314b..7e8cad59a 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -1,6 +1,7 @@ #include <ngx_config.h> #include <ngx_string.h> +#include <ngx_socket.h> #include <ngx_listen.h> #include <ngx_http.h> @@ -17,8 +18,11 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log) { ngx_listen_t *ls; + ngx_http_server.request_pool_size = 16384; ngx_http_server.header_timeout = 20000; - ngx_http_server.buff_size = 1024; + ngx_http_server.header_buffer_size = 1024; + ngx_http_server.discarded_buffer_size = 1500; + #if (WIN32) ngx_http_server.doc_root = "html"; #else @@ -26,8 +30,11 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log) #endif ngx_http_server.doc_root_len = strlen(ngx_http_server.doc_root) + 1; + + ngx_http_output_filter_init(); ngx_http_write_filter_init(); + ls = ngx_push_array(ngx_listening_sockets); ngx_memzero(ls, sizeof(ngx_listen_t)); @@ -57,6 +64,7 @@ int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log) ls->server = &ngx_http_server; ls->log = log; + return 1; } diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index fe89874dd..3b943d656 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -5,7 +5,7 @@ #include <ngx_config.h> #include <ngx_types.h> #include <ngx_hunk.h> -#include <ngx_file.h> +#include <ngx_files.h> #include <ngx_connection.h> @@ -25,6 +25,7 @@ #define NGX_HTTP_OK 200 +#define NGX_HTTP_SPECIAL_RESPONSE 300 #define NGX_HTTP_MOVED_PERMANENTLY 302 #define NGX_HTTP_BAD_REQUEST 400 #define NGX_HTTP_NOT_FOUND 404 @@ -45,7 +46,11 @@ typedef struct { typedef struct { char *doc_root; size_t doc_root_len; - size_t buff_size; + + size_t request_pool_size; + + size_t header_buffer_size; + size_t discarded_buffer_size; unsigned int header_timeout; } ngx_http_server_t; @@ -88,7 +93,7 @@ struct ngx_http_request_s { int filename_len; int (*handler)(ngx_http_request_t *r); - ngx_file_info_t file_info; + ngx_file_info_t fileinfo; int method; @@ -104,7 +109,11 @@ struct ngx_http_request_s { int filter; + ssize_t client_content_length; + char *discarded_buffer; + unsigned header_timeout:1; + unsigned process_header:1; unsigned header_only:1; unsigned unusual_uri:1; @@ -134,6 +143,9 @@ typedef struct { #define NGX_INDEX "index.html" +/* STUB */ +int ngx_http_init(ngx_pool_t *pool, ngx_log_t *log); + int ngx_http_init_connection(ngx_connection_t *c); diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c index 63fc29a93..7783462f9 100644 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -2,7 +2,7 @@ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_string.h> -#include <ngx_file.h> +#include <ngx_files.h> #include <ngx_log.h> #include <ngx_alloc.h> #include <ngx_hunk.h> @@ -10,6 +10,12 @@ #include <ngx_http.h> +/* STUB */ +#include <ngx_http_output_filter.h> + +int ngx_http_static_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); @@ -17,8 +23,19 @@ static int ngx_http_process_request(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_header_line(ngx_http_request_t *r); -static int ngx_http_process_http_request(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_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_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); static int ngx_http_close_request(ngx_http_request_t *r); static size_t ngx_http_log_error(void *data, char *buf, size_t len); @@ -54,8 +71,15 @@ 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 = NULL; +#else inet_ntop(c->family, (char *)c->sockaddr + c->addr, c->addr_text, c->addr_textlen); +#endif ngx_test_null(ctx, ngx_pcalloc(c->pool, sizeof(ngx_http_log_ctx_t)), NGX_ERROR); @@ -107,22 +131,22 @@ int ngx_http_init_request(ngx_event_t *ev) r->connection = c; r->server = srv; - /* TODO: request's pool size */ - ngx_test_null(r->pool, ngx_create_pool(16384, ev->log), + ngx_test_null(r->pool, ngx_create_pool(srv->request_pool_size, ev->log), ngx_http_close_request(r)); ngx_test_null(r->header_in, - ngx_create_temp_hunk(r->pool, srv->buff_size, 0, 0), + ngx_create_temp_hunk(r->pool, srv->header_buffer_size, 0, 0), ngx_http_close_request(r)); ev->event_handler = ngx_http_process_request; r->state_handler = ngx_http_process_request_line; + r->process_header = 1; return ngx_http_process_request(ev); } -int ngx_http_process_request(ngx_event_t *ev) +static int ngx_http_process_request(ngx_event_t *ev) { int n, rc; ngx_connection_t *c ; @@ -151,11 +175,9 @@ int ngx_http_process_request(ngx_event_t *ev) ngx_log_debug(ev->log, "http read %d" _ n); if (n == 0) { - /* STUB: c-> */ - if (ev->unexpected_eof) + if (c->unexpected_eof) ngx_log_error(NGX_LOG_INFO, c->log, 0, "client prematurely closed connection"); - return ngx_http_close_request(r); } @@ -173,8 +195,9 @@ int ngx_http_process_request(ngx_event_t *ev) /* rc == NGX_OK || rc == NGX_AGAIN */ - } while (r->header_in->pos.mem < r->header_in->last.mem); - + } while (r->process_header + && r->header_in->pos.mem < r->header_in->last.mem); + if (!r->header_timeout) { r->header_timeout = 1; ngx_del_timer(ev); @@ -200,27 +223,23 @@ static int ngx_http_process_request_line(ngx_http_request_t *r) ngx_log_debug(r->connection->log, "HTTP: %d, %d, %s" _ r->method _ r->http_version _ r->uri); - if (r->http_version == 9) { - /* set lock event */ - return ngx_http_process_http_request(r); - } + if (r->http_version == 9) + return ngx_http_handler(r); r->state_handler = ngx_http_process_request_header; - r->connection->read->action = "reading client request headers"; + ctx = r->connection->log->data; + ctx->action = "reading client request headers"; return NGX_OK; } - r->connection->log->handler = NULL; ctx = r->connection->log->data; - + r->connection->log->handler = NULL; ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, header_errors[rc - NGX_HTTP_INVALID_METHOD], ctx->client); - r->connection->log->handler = ngx_http_log_error; - /* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST) */ - return ngx_http_close_request(r); + return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); } static int ngx_http_process_request_header(ngx_http_request_t *r) @@ -232,63 +251,192 @@ static int ngx_http_process_request_header(ngx_http_request_t *r) rc = ngx_read_http_header_line(r); if (rc == NGX_OK) { - *r->header_name_end = '\0'; - *r->header_end = '\0'; - ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _ - r->header_name_start _ r->header_start); + if (ngx_http_process_request_header_line(r) == NGX_ERROR) + return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); + + } else if (rc == NGX_HTTP_HEADER_DONE) { + ngx_log_debug(r->connection->log, "HTTP header done"); + return ngx_http_handler(r); } else if (rc == NGX_AGAIN) { return NGX_AGAIN; - } else if (rc == NGX_HTTP_HEADER_DONE) { - break; - } else if (rc == NGX_HTTP_INVALID_HEADER) { - r->connection->log->handler = NULL; ctx = r->connection->log->data; + r->connection->log->handler = NULL; ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client %s sent invalid header", ctx->client); r->connection->log->handler = ngx_http_log_error; - /* STUB return ngx_http_error(r, NGX_HTTP_BAD_REQUEST) */ - return ngx_http_close_request(r); + return ngx_http_error(r, NGX_HTTP_BAD_REQUEST); } } +} - r->state_handler = NULL; - r->connection->read->action = "reading client request body"; +static int ngx_http_process_request_header_line(ngx_http_request_t *r) +{ + /* STUB */ + *r->header_name_end = '\0'; + *r->header_end = '\0'; + ngx_log_debug(r->connection->log, "HTTP header: '%s: %s'" _ + r->header_name_start _ r->header_start); + + return NGX_OK; +} + +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; +} - r->connection->read->read_discarded = 1; - r->connection->read->unexpected_eof = 0; - ngx_log_debug(r->connection->log, "HTTP header done"); +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); - return ngx_http_process_http_request(r); + if (r->client_content_length) + r->connection->read->event_handler = ngx_http_read_discarded_body; } -#if 0 -static int ngx_http_lock_read(ngx_event_t *ev) +static int ngx_http_read_discarded_body(ngx_event_t *ev) { - ngx_del_event(ev, NGX_READ_EVENT); - ev->read_blocked = 1; + 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 > 0) + r->client_content_length -= n; + + return n; +} + +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_handler(ngx_http_request_t *r) +{ + int rc; + + ngx_del_timer(r->connection->read); + r->header_timeout = 1; + + r->process_header = 0; + r->state_handler = NULL; + r->connection->unexpected_eof = 0; + + 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); + + /* transfer not completed */ + if (rc == NGX_AGAIN) { +#if (HAVE_CLEAR_EVENT) + if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, + NGX_CLEAR_EVENT) == NGX_ERROR) { +#else + if (ngx_add_event(r->connection->write, NGX_WRITE_EVENT, + NGX_ONESHOT_EVENT) == NGX_ERROR) { #endif + /* log http request */ + return ngx_http_close_request(r); + } + + ngx_add_timer(r->connection->write, 5000); + + r->connection->write->event_handler = ngx_http_writer; + return rc; + } + + if (rc == NGX_ERROR) { + /* log http request */ + return ngx_http_close_request(r); + } -static int ngx_http_process_http_request(ngx_http_request_t *r) + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) + return ngx_http_special_response(r, rc); + + /* rc == NGX_OK */ + + /* STUB */ + return ngx_http_close_request(r); + +/* + if (!keepalive) + if (linger) + set linger timeout on read + shutdown socket + else + close socket +*/ +} + +static int ngx_http_set_default_handler(ngx_http_request_t *r) { int err, rc; char *name, *loc, *file; - ngx_log_debug(r->connection->log, "HTTP request"); - ngx_test_null(r->headers_out, ngx_pcalloc(r->pool, sizeof(ngx_http_headers_out_t)), - ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR)); + NGX_HTTP_INTERNAL_SERVER_ERROR); if (*(r->uri_end - 1) == '/') { - r->handler = NGX_HTTP_DIRECTORY_HANDLER; + return NGX_HTTP_INTERNAL_SERVER_ERROR; +#if 0 + r->handler = ngx_http_index_handler; return NGX_OK; +#endif } /* 20 bytes is spare space for some index name, i.e. index.html */ @@ -296,7 +444,7 @@ static int ngx_http_process_http_request(ngx_http_request_t *r) ngx_test_null(r->filename, ngx_palloc(r->pool, r->filename_len), - ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR)); + NGX_HTTP_INTERNAL_SERVER_ERROR); r->location = ngx_cpystrn(r->filename, r->server->doc_root, r->server->doc_root_len); @@ -305,99 +453,73 @@ static int ngx_http_process_http_request(ngx_http_request_t *r) ngx_log_debug(r->connection->log, "HTTP filename: '%s'" _ r->filename); - if (ngx_file_type(r->filename, &r->file_info) == -1) { + if (ngx_file_type(r->filename, &r->fileinfo) == -1) { err = ngx_errno; ngx_log_error(NGX_LOG_ERR, r->connection->log, err, - "ngx_process_http_request: " ngx_file_type_n " %s failed", r->filename); if (err == NGX_ENOENT) - return ngx_http_error(r, NGX_HTTP_NOT_FOUND); + return NGX_HTTP_NOT_FOUND; else - return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (ngx_is_dir(r->file_info)) { + 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_redirect(r, NGX_HTTP_MOVED_PERMANENTLY); + return NGX_HTTP_MOVED_PERMANENTLY; } - /* STUB */ - rc = ngx_http_static_handler(r); - if (rc == 0) { - r->connection->write->event_handler = ngx_http_writer; - ngx_add_event(r->connection->write, NGX_WRITE_EVENT, NGX_CLEAR_EVENT); - } - return rc; + r->handler = ngx_http_static_handler; - r->handler = NGX_HTTP_STATIC_HANDLER; return NGX_OK; } -#if 0 -static int ngx_http_handler(ngx_http_request_t *r) +static int ngx_http_writer(ngx_event_t *ev) { - find_http_handler(); - - if (r->discard_body && r->connection->read->ready) - ngx_http_discarad_body(); - - rc = http_handler(); - - /* transfer not completed */ - if (rc == NGX_AGAIN) - return rc; + int rc; + unsigned int timeout; + ngx_connection_t *c; + ngx_http_request_t *r; - if (rc == NGX_ERROR) { - log http request - close http request - return rc; - } + c = (ngx_connection_t *) ev->data; + r = (ngx_http_request_t *) c->data; - if (rc > 300) { - send special response - } + rc = ngx_http_output_filter(r, NULL); - /* rc == NGX_OK */ + ngx_log_debug(ev->log, "output_filter: %d" _ rc); - if (!keepalive) - if (linger) - set linger timeout on read - shutdown socket - else - close socket + if (rc == NGX_AGAIN) { - log http request - close http request - if (keepalive) - return NGX_OK; - else - close connection - return NGX_OK; -} - -static int ngx_http_writer(ngx_event_t *ev) -{ - int rc; - - ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_http_request_t *r = (ngx_http_request_t *) c->data; + if (c->sent > 0) { + 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); + } - rc = ngx_http_filter(r, NULL); + 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); + } - if (rc == NGX_AGAIN) return rc; + } if (rc == NGX_ERROR) return rc; /* rc == NGX_OK */ + return ngx_http_close_request(r); +/* if (!keepalive) if (linger) shutdown socket @@ -411,19 +533,10 @@ static int ngx_http_writer(ngx_event_t *ev) else close connection return NGX_OK; +*/ } -static int ngx_http_discarded_read(ngx_event_t *ev) -{ - if (ev->timedout) - return NGX_ERROR; - - while (full) { - recv(); - } - - return NGX_OK; -} +#if 0 static int ngx_http_keepalive_handler(ngx_event_t *ev) { @@ -446,40 +559,28 @@ static int ngx_http_keepalive_handler(ngx_event_t *ev) #endif -static int ngx_http_writer(ngx_event_t *ev) -{ - int rc; - ngx_connection_t *c = (ngx_connection_t *) ev->data; - ngx_http_request_t *r = (ngx_http_request_t *) c->data; - - rc = ngx_http_write_filter(r, NULL); - ngx_log_debug(r->connection->log, "write_filter: %d" _ rc); - return rc; -} - -static int ngx_http_handler(ngx_http_request_t *r, int handler) +static int ngx_http_special_response(ngx_http_request_t *r, int error) { - if (handler == NGX_HTTP_STATIC_HANDLER) - return ngx_http_static_handler(r); - -#if 0 - elsif (handler == NGX_HTTP_DIRECTORY_HANDLER) - return ngx_http_index_handler(r); -#endif - - return ngx_http_error(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return ngx_http_error(r, error); } static int ngx_http_redirect(ngx_http_request_t *r, int redirect) { /* STUB */ - return -1; + + /* log request */ + + return ngx_http_close_request(r); } static int ngx_http_error(ngx_http_request_t *r, int error) { /* STUB */ - return -1; + ngx_log_debug(r->connection->log, "http error: %d" _ error); + + /* log request */ + + return ngx_http_close_request(r); } #if 0 @@ -549,8 +650,8 @@ static int ngx_http_close_request(ngx_http_request_t *r) ngx_log_debug(r->connection->log, "http close"); - ngx_del_event(r->connection->read, NGX_TIMER_EVENT); - ngx_del_event(r->connection->write, NGX_TIMER_EVENT); + ngx_del_timer(r->connection->read); + ngx_del_timer(r->connection->write); return NGX_ERROR; } @@ -559,6 +660,7 @@ static int ngx_http_close_request(ngx_http_request_t *r) static size_t ngx_http_log_error(void *data, char *buf, size_t len) { ngx_http_log_ctx_t *ctx = (ngx_http_log_ctx_t *) data; + if (ctx->url) return ngx_snprintf(buf, len, " while %s, client: %s, URL: %s", ctx->action, ctx->client, ctx->url); diff --git a/src/http/ngx_http_filter.c b/src/http/ngx_http_filter.c deleted file mode 100644 index 6f39d9b8f..000000000 --- a/src/http/ngx_http_filter.c +++ /dev/null @@ -1,236 +0,0 @@ - - -#include <ngx_hunk.h> -#include <ngx_http.h> -#include <ngx_http_filter.h> - - -ngx_http_module_t ngx_http_filter_module; - - -/* STUB */ -static ngx_http_filter_ctx_t module_ctx; - -void ngx_http_filter_init() -{ - module_ctx.hunk_size = 32 * 1024; - module_ctx.out.hunk = NULL; - module_ctx.out.next = NULL; - module_ctx.next_filter = ngx_http_write_filter; - - ngx_http_filter_module.ctx = &module_ctx; -} -/* */ - - -/* -int ngx_http_filter(ngx_http_request_t *r, ngx_chain_t *in) -*/ - -/* - flags NGX_HUNK_RECYCLED, NGX_HUNK_FLUSH, NGX_HUNK_LAST -*/ - -int ngx_http_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) -{ - int rc; - size_t size; - ssize_t n; - ngx_chain_t *ce; - ngx_http_filter_ctx_t *ctx; - - ctx = (ngx_http_filter_ctx_t *) - ngx_get_module_ctx(r->main ? r->main : r, - &ngx_http_filter_module); - - if (hunk && (hunk->type & NGX_HUNK_LAST)) - ctx->last = 1; - - /* input chain is not empty */ - if (ctx->in) { - - while (ctx->in) { - - /* add hunk to input chain */ - if (hunk) { - for (ce = ctx->in; ce->next; ce = ce->next) - /* void */ ; - - ngx_add_hunk_to_chain(ce->next, hunk, r->pool, - NGX_ERROR); - } - - /* our hunk is still busy */ - if (ctx->hunk->pos.mem < ctx->hunk->last.mem) { - rc = ctx->next_filter(r, NULL); - - /* our hunk is free */ - } else { - ctx->out.hunk = ctx->hunk; - - rc = ngx_http_filter_copy_hunk(ctx->hunk, ctx->in->hunk); -#if (NGX_FILE_AIO) - if (rc == NGX_AGAIN) - return rc; -#endif - if (rc == NGX_ERROR) - return rc; - - /* whole hunk is copied so we send to next filter chain part - up to next hunk that need to be copied */ - if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) { - ctx->out.next = ctx->in->next; - - for (ce = ctx->in->next; ce; ce = ce->next) { - if (ce->type & NGX_HUNK_FILE) - break; - - if ((ce->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP) - && (r->filter & NGX_HTTP_FILTER_NEED_TEMP)) - break; - } - - ctx->out.next = ce; - - } else { - ctx->out.next = NULL; - } - - rc = ctx->next_filter(r, &ctx->out); - } - - if (rc == NGX_OK) - ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; - else - return rc; - } - - /* input chain is empty */ - } else { - - if (hunk == NULL) { - rc = ctx->next_filter(r, NULL); - - } else { - - /* we need to copy hunk to our hunk */ - if (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) - && (hunk->type & NGX_HUNK_FILE)) - || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP) - && (hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) - ) { - - /* out hunk is still busy */ - if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) { - ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, - NGX_ERROR); - - rc = ctx->next_filter(r, NULL); - - } else { - if (ctx->hunk == NULL) { - - if (hunk->type & NGX_HUNK_LAST) { - size = hunk->last.mem - hunk->pos.mem; - if (size > ctx->hunk_size) - size = ctx->hunk_size; - - } else { - size = ctx->hunk_size; - } - - ngx_test_null(ctx->hunk, - ngx_create_temp_hunk(r->pool, size, - 50, 50), - NGX_ERROR); - - rc = ngx_http_filter_copy_hunk(ctx->hunk, - ctx->in->hunk); -#if (NGX_FILE_AIO) - if (rc == NGX_AGAIN) { - /* add hunk to input chain */ - ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, - NGX_ERROR); - - return rc; - } -#endif - if (rc == NGX_ERROR) - return rc; - - if (ctx->in->hunk->pos.mem < ctx->in->hunk->last.mem) - ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, - NGX_ERROR); - - ctx->out.hunk = ctx->hunk; - ctx->out.next = NULL; - - rc = ctx->next_filter(r, &ctx->out); - } - } - - } else { - ctx->out.hunk = hunk; - ctx->out.next = NULL; - - rc = ctx->next_filter(r, &ctx->out); - - } - } - } - - if (rc == NGX_OK && ctx->last) { - /* STUB */ - return NGX_ERROR; - } - - if (rc == NGX_OK) { - ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; -#if level_event - ngx_del_event(r->connection->write, NGX_WRITE_EVENT); -#endif - } - - return rc; -} - - -int ngx_http_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src, ngx_log_t *log) -{ - size_t size; - - size = hunk->last.mem - hunk->pos.mem; - if (size > dst->end - dst->pos.mem) - size = dst->end - dst->pos.mem; - - if (src->type & NGX_HUNK_FILE) { - n = ngx_read_file(src->handle, dst->pos.mem, size); - - if (n == NGX_ERROR) { - ngx_log_error(NGX_LOG_ERR, log, ngx_errno, - ngx_read_file_n " failed for client"); - return n; - -#if (NGX_FILE_AIO) - } else if (n == NGX_AGAIN) { - return n; -#endif - - } else { - ngx_assert((n == size), /* void */ ; , log, - ngx_read_file_n " reads only %d of %d for client" _ - n _ size); - } - - src->pos.mem += n; - dst->last.mem += n; - - } else { - ngx_memcpy(src->pos.mem, dst->pos.mem, size); - - src->pos.mem += size; - dst->last.mem += size; - } - - return NGX_OK; -} diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c new file mode 100644 index 000000000..693b39992 --- /dev/null +++ b/src/http/ngx_http_output_filter.c @@ -0,0 +1,253 @@ + + +#include <ngx_core.h> +#include <ngx_files.h> +#include <ngx_string.h> +#include <ngx_hunk.h> +#include <ngx_http.h> +#include <ngx_http_output_filter.h> + + +/* STUB */ +int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in); + + + +static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src); + +ngx_http_module_t ngx_http_output_filter_module; + + +/* STUB */ +static ngx_http_output_filter_ctx_t module_ctx; + +void ngx_http_output_filter_init() +{ + module_ctx.hunk_size = 32 * 1024; + module_ctx.out.hunk = NULL; + module_ctx.out.next = NULL; + module_ctx.next_filter = ngx_http_write_filter; + + ngx_http_output_filter_module.ctx = &module_ctx; +} +/* */ + + +/* + flags NGX_HUNK_RECYCLED, NGX_HUNK_FLUSH, NGX_HUNK_LAST +*/ + +int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) +{ + int rc, first; + size_t size; + ssize_t n; + ngx_chain_t *ce; + ngx_http_output_filter_ctx_t *ctx; + + ctx = (ngx_http_output_filter_ctx_t *) + ngx_get_module_ctx(r->main ? r->main : r, + &ngx_http_output_filter_module); + + if (hunk && (hunk->type & NGX_HUNK_LAST)) + ctx->last = 1; + + first = 1; + + while (first || ctx->in) { + + /* input chain is not empty */ + if (ctx->in) { + + /* add hunk to input chain */ + if (first && hunk) { + for (ce = ctx->in; ce->next; ce = ce->next) + /* void */ ; + + ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR); + } + + first = 0; + + /* our hunk is still busy */ + if (ctx->hunk->pos.mem < ctx->hunk->last.mem) { + rc = ctx->next_filter(r, NULL); + + /* our hunk is free */ + } else { + ctx->out.hunk = ctx->hunk; + + rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk); +#if (NGX_FILE_AIO) + if (rc == NGX_AGAIN) + return rc; +#endif + if (rc == NGX_ERROR) + return rc; + + /* whole hunk is copied so we send to next filter chain part + up to next hunk that need to be copied */ + if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) { + ctx->out.next = ctx->in->next; + + for (ce = ctx->in->next; ce; ce = ce->next) { + if (ce->hunk->type & NGX_HUNK_FILE) + break; + + if ((ce->hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP) + && (r->filter & NGX_HTTP_FILTER_NEED_TEMP)) + break; + } + + ctx->out.next = ce; + + } else { + ctx->out.next = NULL; + } + + rc = ctx->next_filter(r, &ctx->out); + } + + /* delete completed hunks from input chain */ + for (ce = ctx->in; ce; ce = ce->next) { + if (ce->hunk->pos.file == ce->hunk->last.file) + ctx->in = ce->next; + } + + if (rc == NGX_OK) + ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; + else + return rc; + + /* input chain is empty */ + } else { + + first = 0; + + if (hunk == NULL) { + rc = ctx->next_filter(r, NULL); + + } else { + + /* we need to copy hunk to our hunk */ + if (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY) + && (hunk->type & NGX_HUNK_FILE)) + || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP) + && (hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) + ) { + + /* out hunk is still busy */ + if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) { + ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, + NGX_ERROR); + + rc = ctx->next_filter(r, NULL); + + } else { + if (ctx->hunk == NULL) { + + if (hunk->type & NGX_HUNK_LAST) { + size = hunk->last.mem - hunk->pos.mem; + if (size > ctx->hunk_size) + size = ctx->hunk_size; + + } else { + size = ctx->hunk_size; + } + + ngx_test_null(ctx->hunk, + ngx_create_temp_hunk(r->pool, size, + 50, 50), + NGX_ERROR); + ctx->hunk->type |= NGX_HUNK_RECYCLED; + + rc = ngx_http_output_filter_copy_hunk(ctx->hunk, + hunk); +#if (NGX_FILE_AIO) + if (rc == NGX_AGAIN) { + /* add hunk to input chain */ + ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, + NGX_ERROR); + + return rc; + } +#endif + if (rc == NGX_ERROR) + return rc; + + if (hunk->pos.mem < hunk->last.mem) + ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, + NGX_ERROR); + + ctx->out.hunk = ctx->hunk; + ctx->out.next = NULL; + + rc = ctx->next_filter(r, &ctx->out); + } + } + + } else { + ctx->out.hunk = hunk; + ctx->out.next = NULL; + + rc = ctx->next_filter(r, &ctx->out); + } + } + } + + if (rc == NGX_OK && ctx->hunk) + ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; + } + + if (rc == NGX_OK && ctx->last) + return NGX_OK; + + if (rc == NGX_OK) { + ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start; +#if level_event + ngx_del_event(r->connection->write, NGX_WRITE_EVENT); +#endif + } + + return rc; +} + + +static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src) +{ + size_t size; + ssize_t n; + + size = src->last.mem - src->pos.mem; + if (size > dst->end - dst->pos.mem) + size = dst->end - dst->pos.mem; + + if (src->type & NGX_HUNK_FILE) { + n = ngx_read_file(src->file, dst->pos.mem, size, src->pos.file); + + if (n == NGX_ERROR) { + return n; + +#if (NGX_FILE_AIO) + } else if (n == NGX_AGAIN) { + return n; +#endif + + } else { + ngx_assert((n == size), /* void */ ; , src->file->log, + ngx_read_file_n " reads only %d of %d" _ + n _ size); + } + + src->pos.mem += n; + dst->last.mem += n; + + } else { + ngx_memcpy(src->pos.mem, dst->pos.mem, size); + + src->pos.mem += size; + dst->last.mem += size; + } + + return NGX_OK; +} diff --git a/src/http/ngx_http_filter.h b/src/http/ngx_http_output_filter.h index 0f738cdd7..072e0bdf0 100644 --- a/src/http/ngx_http_filter.h +++ b/src/http/ngx_http_output_filter.h @@ -1,5 +1,5 @@ -#ifndef _NGX_HTTP_FILTER_H_INCLUDED_ -#define _NGX_HTTP_FILTER_H_INCLUDED_ +#ifndef _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_ +#define _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_ #include <ngx_core.h> @@ -14,7 +14,7 @@ typedef struct { ngx_chain_t out; size_t hunk_size; unsigned last; -} ngx_http_filter_ctx_t; +} ngx_http_output_filter_ctx_t; -#endif /* _NGX_HTTP_FILTER_H_INCLUDED_ */ +#endif /* _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_ */ diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c index 2ccbe2edb..dcb74c94a 100644 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -2,9 +2,9 @@ #include <ngx_config.h> #include <ngx_hunk.h> -#include <ngx_http.h> -#include <ngx_http_filter.h> #include <ngx_event_write.h> +#include <ngx_http.h> +#include <ngx_http_output_filter.h> #include <ngx_http_write_filter.h> @@ -48,7 +48,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) ch->hunk->type _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); - if (ch->hunk->type & NGX_HUNK_FLUSH) + if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED) flush = size; if (ch->hunk->type & NGX_HUNK_LAST) @@ -69,7 +69,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) ch->hunk->type _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); - if (ch->hunk->type & NGX_HUNK_FLUSH) + if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED) flush = size; if (ch->hunk->type & NGX_HUNK_LAST) @@ -85,5 +85,7 @@ int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->out = chain; + ngx_log_debug(r->connection->log, "write filter %x" _ chain); + return (chain ? NGX_AGAIN : NGX_OK); } diff --git a/src/http/ngx_http_write_filter.h b/src/http/ngx_http_write_filter.h index 6a2c6f24d..0b3fa5433 100644 --- a/src/http/ngx_http_write_filter.h +++ b/src/http/ngx_http_write_filter.h @@ -7,5 +7,7 @@ typedef struct { size_t buffer_output; } ngx_http_write_filter_ctx_t; +int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in); + #endif /* _NGX_HTTP_WRITE_FILTER_H_INCLUDED_ */ |