aboutsummaryrefslogtreecommitdiff
path: root/src/http
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2002-09-02 14:48:24 +0000
committerIgor Sysoev <igor@sysoev.ru>2002-09-02 14:48:24 +0000
commita58e3ca14300fce97b2124233afe140c8d59199f (patch)
treed24eff379cc7dfb5c6952f1bb15735cd63ba2179 /src/http
parent016b85270268989d769bade2004a7c628a47d726 (diff)
downloadnginx-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.c9
-rw-r--r--src/http/modules/ngx_http_static_handler.c47
-rw-r--r--src/http/ngx_http.c10
-rw-r--r--src/http/ngx_http.h18
-rw-r--r--src/http/ngx_http_event.c384
-rw-r--r--src/http/ngx_http_filter.c236
-rw-r--r--src/http/ngx_http_output_filter.c253
-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.c10
-rw-r--r--src/http/ngx_http_write_filter.h2
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_ */