# HG changeset patch # User Igor Sysoev # Date 1031393665 0 # Node ID 6f58641241bbc5d2b7cacb339fd5333e76173813 # Parent 708f8bb772ec837e5b4e035aff40c96d374c37c0 nginx-0.0.1-2002-09-07-14:14:25 import diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -84,6 +84,7 @@ void ngx_log_error_core(int level, ngx_l errstr[len + 1] = '\0'; fputs(errstr, stderr); + fflush(stderr); } #if !(HAVE_VARIADIC_MACROS) diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -106,6 +106,9 @@ NGX_AIO_EVENT overlapped, a #ifndef HAVE_CLEAR_EVENT #define HAVE_CLEAR_EVENT 1 +#endif + +#if (HAVE_CLEAR_EVENT) #define NGX_CLEAR_EVENT EV_CLEAR #endif diff --git a/src/event/ngx_event_write.c b/src/event/ngx_event_write.c --- a/src/event/ngx_event_write.c +++ b/src/event/ngx_event_write.c @@ -98,23 +98,20 @@ ngx_chain_t *ngx_event_write(ngx_connect (ngx_iovec_t *) trailer->elts, trailer->nelts, &sent, c->log); } else { - size_t sendv_sent; + rc = ngx_sendv(c, (ngx_iovec_t *) header->elts, + header->nelts); - sendv_sent = 0; - rc = ngx_sendv(c->fd, (ngx_iovec_t *) header->elts, - header->nelts, &sendv_sent); - sent = sendv_sent; + sent = rc > 0 ? rc: 0; + ngx_log_debug(c->log, "sendv: " QD_FMT _ sent); } #if (HAVE_MAX_SENDFILE_IOVEC) } #endif - /* save sent for logging */ + if (rc == NGX_ERROR) + return (ngx_chain_t *) NGX_ERROR; - if (rc == NGX_ERROR) - return (ngx_chain_t *) -1; - - c->sent = sent; + c->sent += sent; flush -= sent; for (ch = in; ch; ch = ch->next) { diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -28,6 +28,7 @@ int ngx_http_init(ngx_pool_t *pool, ngx_ #else ngx_http_server.doc_root = "/home/is/work/xml/site-1.0.0/html"; #endif + ngx_http_server.doc_root = "html"; ngx_http_server.doc_root_len = strlen(ngx_http_server.doc_root) + 1; diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -36,12 +36,6 @@ #define NGX_HTTP_DIRECTORY_HANDLER 1 -typedef struct { - void *ctx; /* STUB */ -} ngx_http_module_t; - -/* STUB */ -#define ngx_get_module_ctx(r, module) (module)->ctx typedef struct { char *doc_root; @@ -82,6 +76,10 @@ struct ngx_http_request_s { char *location; ngx_fd_t fd; + void **ctx; + void **loc_conf; + void **srv_conf; + ngx_pool_t *pool; ngx_hunk_t *header_in; @@ -140,6 +138,18 @@ typedef struct { } ngx_http_log_ctx_t; +typedef struct { + int index; +} ngx_http_module_t; + +#define NGX_HTTP_MODULE 0 + +#define ngx_get_module_loc_conf(r, module) r->loc_conf[module.index] +#define ngx_get_module_ctx(r, module) r->ctx[module.index] + + + +/* STUB */ #define NGX_INDEX "index.html" diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -361,6 +361,7 @@ static int ngx_http_discarded_read(ngx_e static int ngx_http_handler(ngx_http_request_t *r) { int rc; + ngx_msec_t timeout; ngx_del_timer(r->connection->read); r->header_timeout = 1; @@ -393,7 +394,16 @@ static int ngx_http_handler(ngx_http_req return ngx_http_close_request(r); } - ngx_add_timer(r->connection->write, 5000); + if (r->connection->sent > 0) { + ngx_log_debug(r->connection->log, "sent: " QD_FMT _ + r->connection->sent); + timeout = (ngx_msec_t) (r->connection->sent * 10); + ngx_log_debug(r->connection->log, "timeout: %d" _ timeout); + ngx_add_timer(r->connection->write, timeout); + + } else { + ngx_add_timer(r->connection->write, 10000); + } r->connection->write->event_handler = ngx_http_writer; return rc; @@ -488,6 +498,8 @@ static int ngx_http_writer(ngx_event_t * 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: %d" _ rc); diff --git a/src/http/ngx_http_modules.c b/src/http/ngx_http_modules.c new file mode 100644 --- /dev/null +++ b/src/http/ngx_http_modules.c @@ -0,0 +1,7 @@ + +extern ngx_http_module_t ngx_http_output_filter_module; + +ngx_http_module_t *ngx_http_modules[] = { + ngx_http_output_filter_module, + NULL +}; diff --git a/src/http/ngx_http_output_filter.c b/src/http/ngx_http_output_filter.c --- a/src/http/ngx_http_output_filter.c +++ b/src/http/ngx_http_output_filter.c @@ -8,67 +8,78 @@ #include -/* 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); +static int ngx_http_output_filter_init( + int (*next_filter)(ngx_http_request_t *r, ngx_chain_t *ch)); +static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool); +static void *ngx_http_output_filter_set_hunk_size(ngx_pool_t *pool, void *conf, + char *size); -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 = { + NGX_HTTP_MODULE +}; -ngx_http_module_t ngx_http_output_filter_module; +static int (*ngx_http_output_next_filter)(ngx_http_request_t *r, + ngx_chain_t *ch); /* STUB */ -static ngx_http_output_filter_ctx_t module_ctx; +int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *ch); -void ngx_http_output_filter_init() +int ngx_http_output_filter_stub_init(ngx_pool_t *pool, void *loc_conf) { - 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_conf_t *conf; - ngx_http_output_filter_module.ctx = &module_ctx; + ngx_http_output_filter_init(ngx_http_write_filter); + conf = ngx_http_output_filter_create_conf(pool); + ngx_http_output_filter_set_hunk_size(pool, conf, "32"); + + loc_conf = conf; } /* */ -/* - 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; + int rc, once; size_t size; ssize_t n; ngx_chain_t *ce; ngx_http_output_filter_ctx_t *ctx; + ngx_http_output_filter_conf_t *conf; ctx = (ngx_http_output_filter_ctx_t *) - ngx_get_module_ctx(r->main ? r->main : r, - &ngx_http_output_filter_module); + ngx_get_module_ctx(r->main ? r->main : r, + ngx_http_output_filter_module); + + if (ctx == NULL) { + ngx_test_null(ctx, + ngx_pcalloc(r->pool, sizeof(ngx_http_output_filter_ctx_t)), + NGX_ERROR); + + ctx->next_filter = ngx_http_output_next_filter; + } + + ngx_log_debug(r->connection->log, "HUNK: x%x CTX-IN: x%x CTX->HUNK: x%x" _ + hunk _ ctx->in _ ctx->hunk); if (hunk && (hunk->type & NGX_HUNK_LAST)) ctx->last = 1; - first = 1; - - while (first || ctx->in) { + for (once = 1; once || ctx->in; once--) { /* input chain is not empty */ if (ctx->in) { /* add hunk to input chain */ - if (first && hunk) { + if (once && 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); @@ -122,8 +133,6 @@ int ngx_http_output_filter(ngx_http_requ /* input chain is empty */ } else { - first = 0; - if (hunk == NULL) { rc = ctx->next_filter(r, NULL); @@ -147,12 +156,17 @@ int ngx_http_output_filter(ngx_http_requ if (ctx->hunk == NULL) { if (hunk->type & NGX_HUNK_LAST) { + + conf = (ngx_http_output_filter_conf_t *) + ngx_get_module_loc_conf(r->main ? r->main : r, + ngx_http_output_filter_module); + size = hunk->last.mem - hunk->pos.mem; - if (size > ctx->hunk_size) - size = ctx->hunk_size; + if (size > conf->hunk_size) + size = conf->hunk_size; } else { - size = ctx->hunk_size; + size = conf->hunk_size; } ngx_test_null(ctx->hunk, @@ -251,3 +265,36 @@ static int ngx_http_output_filter_copy_h return NGX_OK; } + + +static int ngx_http_output_filter_init( + int (*next_filter)(ngx_http_request_t *r, ngx_chain_t *ch)) +{ + ngx_http_output_next_filter = next_filter; + + return NGX_OK; +} + +static void *ngx_http_output_filter_create_conf(ngx_pool_t *pool) +{ + ngx_http_output_filter_conf_t *conf; + + ngx_test_null(conf, + ngx_pcalloc(pool, sizeof(ngx_http_output_filter_conf_t)), + NULL); + + conf->hunk_size = 16384; +} + +static void *ngx_http_output_filter_set_hunk_size(ngx_pool_t *pool, void *conf, + char *size) +{ + ngx_http_output_filter_conf_t *cf = (ngx_http_output_filter_conf_t *) conf; + + cf->hunk_size = atoi(size); + if (cf->hunk_size <= 0) + return "Error"; + + cf->hunk_size *= 1024; + return NULL; +} diff --git a/src/http/ngx_http_output_filter.h b/src/http/ngx_http_output_filter.h --- a/src/http/ngx_http_output_filter.h +++ b/src/http/ngx_http_output_filter.h @@ -2,19 +2,28 @@ #define _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_ -#include +#include +#include + #define NGX_HTTP_FILTER_NEED_IN_MEMORY 1 #define NGX_HTTP_FILTER_NEED_TEMP 2 + +typedef struct { + size_t hunk_size; +} ngx_http_output_filter_conf_t; + typedef struct { int (*next_filter)(ngx_http_request_t *r, ngx_chain_t *ch); ngx_hunk_t *hunk; ngx_chain_t *in; ngx_chain_t out; - size_t hunk_size; unsigned last; } ngx_http_output_filter_ctx_t; +int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk); + + #endif /* _NGX_HTTP_OUTPUT_FILTER_H_INCLUDED_ */ diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -32,7 +32,7 @@ printf("\nstate: %d, pos: %x, end: %x, c state, p, r->header_in->last, ch, p); */ - /* GCC compiles switch as jump table */ + /* GCC 2.95.2 and VC 6.0 compiles switch as jump table */ switch (state) { diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -1,27 +1,19 @@ #include - +#include #include #include #include #include - #include -ngx_http_module_t ngx_http_write_filter_module; +ngx_http_module_t ngx_http_write_filter_module = { + NGX_HTTP_MODULE +}; /* STUB */ -static ngx_http_write_filter_ctx_t module_ctx; - -void ngx_http_write_filter_init() -{ - module_ctx.buffer_output = 10240; - module_ctx.out = NULL; - - ngx_http_write_filter_module.ctx = &module_ctx; -} /* */ @@ -31,10 +23,17 @@ int ngx_http_write_filter(ngx_http_reque off_t size, flush; ngx_chain_t *ch, **prev, *chain; ngx_http_write_filter_ctx_t *ctx; + ngx_http_write_filter_conf_t *conf; + ctx = (ngx_http_write_filter_ctx_t *) ngx_get_module_ctx(r->main ? r->main : r, - &ngx_http_write_filter_module); + ngx_http_write_filter_module); + if (ctx == NULL) + ngx_test_null(ctx, + ngx_pcalloc(r->pool, sizeof(ngx_http_write_filter_ctx_t)), + NGX_ERROR); + size = flush = 0; last = 0; prev = &ctx->out; @@ -76,7 +75,11 @@ int ngx_http_write_filter(ngx_http_reque last = 1; } - if (!last && flush == 0 && size < ctx->buffer_output) + conf = (ngx_http_write_filter_conf_t *) + ngx_get_module_loc_conf(r->main ? r->main : r, + ngx_http_write_filter_module); + + if (!last && flush == 0 && size < conf->buffer_output) return NGX_OK; chain = ngx_event_write(r->connection, ctx->out, flush); @@ -89,3 +92,29 @@ int ngx_http_write_filter(ngx_http_reque return (chain ? NGX_AGAIN : NGX_OK); } + + +static void *ngx_http_write_filter_create_conf(ngx_pool_t *pool) +{ + ngx_http_write_filter_conf_t *conf; + + ngx_test_null(conf, + ngx_pcalloc(pool, sizeof(ngx_http_write_filter_conf_t)), + NULL); + + conf->buffer_output = 16384; +} + +static void *ngx_http_write_filter_set_hunk_size(ngx_pool_t *pool, void *conf, + char *size) +{ + ngx_http_write_filter_conf_t *cf = (ngx_http_write_filter_conf_t *) conf; + + cf->buffer_output = atoi(size); + if (cf->buffer_output <= 0) + return "Error"; + + cf->buffer_output *= 1024; + return NULL; +} + diff --git a/src/http/ngx_http_write_filter.h b/src/http/ngx_http_write_filter.h --- a/src/http/ngx_http_write_filter.h +++ b/src/http/ngx_http_write_filter.h @@ -2,11 +2,19 @@ #define _NGX_HTTP_WRITE_FILTER_H_INCLUDED_ +#include +#include + + +typedef struct { + size_t buffer_output; +} ngx_http_write_filter_conf_t; + typedef struct { ngx_chain_t *out; - size_t buffer_output; } ngx_http_write_filter_ctx_t; + int ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in); diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -10,8 +10,10 @@ ssize_t ngx_read_file(ngx_file_t *file, n = pread(file->fd, buf, size, offset); - if (n == NGX_ERROR) + if (n == -1) { ngx_log_error(NGX_LOG_ERR, file->log, ngx_errno, "read() failed"); + return NGX_ERROR; + } return n; } diff --git a/src/os/unix/ngx_sendv.c b/src/os/unix/ngx_sendv.c --- a/src/os/unix/ngx_sendv.c +++ b/src/os/unix/ngx_sendv.c @@ -1,18 +1,28 @@ #include #include -#include +#include +#include +#include #include -ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent) +ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n) { ssize_t rc; + ngx_err_t err; - rc = writev(s, iovec, n); + rc = writev(c->fd, iovec, n); - if (rc == -1) + if (rc == -1) { + err = ngx_socket_errno; + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "sendv() eagain"); + return NGX_AGAIN; + } + + ngx_log_error(NGX_LOG_ERR, c->log, err, "sendv() failed"); return NGX_ERROR; + } - *sent = rc; - return NGX_OK; + return rc; } diff --git a/src/os/unix/ngx_sendv.h b/src/os/unix/ngx_sendv.h --- a/src/os/unix/ngx_sendv.h +++ b/src/os/unix/ngx_sendv.h @@ -3,13 +3,13 @@ #include -#include +#include typedef struct iovec ngx_iovec_t; #define ngx_iov_base iov_base #define ngx_iov_len iov_len -ssize_t ngx_sendv(ngx_socket_t s, ngx_iovec_t *iovec, int n, size_t *sent); +ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n); #endif /* _NGX_SENDV_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_sendv.c b/src/os/win32/ngx_sendv.c new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_sendv.c @@ -0,0 +1,34 @@ + +#include +#include +#include +#include +#include +#include + +ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n) +{ + int rc; + size_t sent; + ngx_err_t err; + + ngx_log_debug(c->log, "WSASend() start"); + + rc = WSASend(c->fd, iovec, n, &sent, 0, NULL, NULL); + + ngx_log_debug(c->log, "WSASend() done"); + + if (rc == -1) { + err = ngx_socket_errno; + + if (err == NGX_EAGAIN) { + ngx_log_error(NGX_LOG_INFO, c->log, err, "WSASend() eagain"); + return NGX_AGAIN; + } + + ngx_log_error(NGX_LOG_ERR, c->log, err, "WSASend() failed"); + return NGX_ERROR; + } + + return sent; +} diff --git a/src/os/win32/ngx_sendv.h b/src/os/win32/ngx_sendv.h --- a/src/os/win32/ngx_sendv.h +++ b/src/os/win32/ngx_sendv.h @@ -3,12 +3,13 @@ #include +#include typedef WSABUF ngx_iovec_t; #define ngx_iov_base buf #define ngx_iov_len len -#define ngx_sendv(s, iovec, n, sent) WSASend(s, iovec, n, sent, 0, NULL, NULL) +ssize_t ngx_sendv(ngx_connection_t *c, ngx_iovec_t *iovec, int n); #endif /* _NGX_SENDV_H_INCLUDED_ */