# HG changeset patch # User Igor Sysoev # Date 1030029843 0 # Node ID c5f071d376e5e5cde476f5bdc9ccea26b5d1cd35 # Parent 34a521b1a14870d446532cae21a17296f73b07b1 nginx-0.0.1-2002-08-22-19:24:03 import diff --git a/src/core/ngx_alloc.c b/src/core/ngx_alloc.c --- a/src/core/ngx_alloc.c +++ b/src/core/ngx_alloc.c @@ -12,8 +12,8 @@ void *ngx_alloc(size_t size, ngx_log_t * p = malloc(size); if (p == NULL) - ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, - "ngx_alloc: malloc %d bytes failed", size); + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + "ngx_alloc: malloc() %d bytes failed", size); return p; } diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h new file mode 100644 --- /dev/null +++ b/src/core/ngx_core.h @@ -0,0 +1,10 @@ +#ifndef _NGX_CORE_H_INCLUDED_ +#define _NGX_CORE_H_INCLUDED_ + + +#define NGX_OK 0 +#define NGX_ERROR -1 +#define NGX_AGAIN -2 + + +#endif /* _NGX_CORE_H_INCLUDED_ */ diff --git a/src/core/ngx_hunk.h b/src/core/ngx_hunk.h --- a/src/core/ngx_hunk.h +++ b/src/core/ngx_hunk.h @@ -57,6 +57,14 @@ struct ngx_chain_s { ngx_chain_t *next; }; +#define ngx_add_hunk_to_chain(chain, h, pool, error) \ + do { \ + ngx_test_null(chain, ngx_create_chain_entry(pool), error); \ + chain->hunk = h; \ + chain->next = NULL; \ + } while (0); + + ngx_hunk_t *ngx_get_hunk(ngx_pool_t *pool, int size, int before, int after); diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -17,17 +17,37 @@ typedef enum { /* "[%time] [%level] %pid#%tid: %message:(%errno)%errstr, while %action" - " %peer and processing %context" + " %peer and while processing %context" + ---- message = "recv() failed"; errno = 32; action = "reading request headers from client"; peer = "192.168.1.1"; context = "URL /" - "[2002/08/20 12:00:00] [error] 412#3: recv() failed:(32)Broken pipe," + "[2002/08/20 12:00:00] [error] 412#3: recv() failed (32: Broken pipe)" " while reading request headers from client 192.168.1.1" - " and processing URL /" + " and while processing URL /" + + ---- + message = "recv() failed"; + errno = 32; + ngx_http_proxy_error_context_t: + action = "reading headers from server %s for client %s and " + "while processing %s" + backend = "127.0.0.1"; + peer = "192.168.1.1"; + context = "URL /" + + "[2002/08/20 12:00:00] [error] 412#3: recv() failed (32: Broken pipe)" + " while reading headers from backend 127.0.0.1" + " for client 192.168.1.1 and while processing URL /" + + ---- + "[alert] 412#3: ngx_alloc: malloc() 102400 bytes failed (12: Cannot " + "allocate memory) while reading request headers from client 192.168.1.1" + " and while processing URL /" OLD: @@ -42,7 +62,10 @@ typedef struct { int log_level; char *action; char *context; -/* char *func(ngx_log_t *log); */ +#if 0 + void *data; /* i.e. ngx_http_proxy_error_context_t */ + char *func(ngx_log_t *log); +#endif } ngx_log_t; #define MAX_ERROR_STR 2048 @@ -57,7 +80,7 @@ typedef struct { #define ngx_log_error(level, log, args...) \ if (log->log_level >= level) ngx_log_error_core(level, log, args) -#ifdef NGX_DEBUG +#if (NGX_DEBUG) #define ngx_log_debug(log, args...) \ if (log->log_level == NGX_LOG_DEBUG) \ ngx_log_error_core(NGX_LOG_DEBUG, log, 0, args) @@ -82,7 +105,7 @@ void ngx_log_error_core(int level, ngx_l #define ngx_log_error(level, log, ...) \ if (log->log_level >= level) ngx_log_error_core(level, log, __VA_ARGS__) -#ifdef NGX_DEBUG +#if (NGX_DEBUG) #define ngx_log_debug(log, ...) \ if (log->log_level == NGX_LOG_DEBUG) \ ngx_log_error_core(NGX_LOG_DEBUG, log, 0, __VA_ARGS__) @@ -104,7 +127,7 @@ void ngx_log_error_core(int level, ngx_l #include -#ifdef NGX_DEBUG +#if (NGX_DEBUG) #define ngx_log_debug(log, text) \ if (log->log_level == NGX_LOG_DEBUG) \ ngx_log_debug_core(log, text) diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -19,7 +19,7 @@ ngx_event_t *ngx_read_events, *n #if !(USE_KQUEUE) -#if 0 +#if 1 ngx_event_type_e ngx_event_type = NGX_SELECT_EVENT; #else ngx_event_type_e ngx_event_type = NGX_KQUEUE_EVENT; diff --git a/src/event/ngx_event_recv.c b/src/event/ngx_event_recv.c --- a/src/event/ngx_event_recv.c +++ b/src/event/ngx_event_recv.c @@ -1,5 +1,6 @@ #include +#include #include #include #include @@ -22,10 +23,10 @@ int ngx_event_recv_core(ngx_event_t *ev, if (ev->eof && ev->available == 0) { if (ev->error) { ngx_log_error(NGX_LOG_ERR, ev->log, ev->error, - "ngx_event_recv: recv failed while %s", + "ngx_event_recv: recv() failed while %s", ev->log->action); - return -1; + return NGX_ERROR; } return 0; @@ -39,14 +40,16 @@ int ngx_event_recv_core(ngx_event_t *ev, if (err == NGX_EAGAIN) { ngx_log_error(NGX_LOG_INFO, ev->log, err, - "ngx_event_recv: EAGAIN while %s", ev->log->action); - return -2; + "ngx_event_recv: recv() returns EAGAIN while %s", + ev->log->action); + return NGX_AGAIN; } ngx_log_error(NGX_LOG_INFO, ev->log, err, - "ngx_event_recv: recv failed while %s", ev->log->action); + "ngx_event_recv: recv() failed while %s", + ev->log->action); - return -1; + return NGX_ERROR; } #if (HAVE_KQUEUE) 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 @@ -93,6 +93,8 @@ struct ngx_http_request_s { ngx_buff_t *buff; ngx_pool_t *pool; + int filter; + unsigned header_only:1; unsigned unusual_uri:1; unsigned complex_uri:1; diff --git a/src/http/ngx_http_filter.c b/src/http/ngx_http_filter.c --- a/src/http/ngx_http_filter.c +++ b/src/http/ngx_http_filter.c @@ -1,5 +1,9 @@ +#include +#include +#include + ngx_http_module_t ngx_http_filter_module; @@ -9,8 +13,9 @@ static ngx_http_filter_ctx_t module_ctx; void ngx_http_filter_init() { - module_ctx.buffer_output = 10240; - module_ctx.out = NULL; + 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; @@ -28,103 +33,202 @@ int ngx_http_filter(ngx_http_request_t * int ngx_http_filter(ngx_http_request_t *r, ngx_hunk_t *hunk) { - enum { NO = 0, COPY, FILE } temp; - - ngx_http_write_ctx_t *ctx; + 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) { - if (hunk == NULL) - if (in == NULL) - next_filter(NULL); - else + /* 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 (hunk != NULL) - if (in == NULL) - if (temp == NO) - fast_chain = hunk; - next_filter(fast_chain); + 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 - if (ctx->hunk busy) - add hunk to ctx->in - next_filter(NULL); - else - if (hunk > ctx->hunk) - copy hunk part to ctx->hunk - add hunk to ctx->in - else - copy hunk to ctx->hunk - fast_chain = ctx->hunk - next_filter(fast_chain); - - else /* in != NULL */ - add hunk to ctx->in - - - - + return rc; + } - - - - - if ((r->filter & NGX_FILT_NEED_IN_MEMORY) && (hunk->type & NGX_HUNK_FILE)) - temp = FILE; + /* input chain is empty */ + } else { - else if ((r->filter & NGX_FILT_NEED_TEMP) - && (hunk->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) - temp = COPY; - - if (temp) { - size = hunk->last.mem - hunk->pos.mem; - - if (hunk->type & NGX_HUNK_LAST) { - if (size > ctx->hunk_size) - size = ctx->hunk_size; - - hunk_size = size; + if (hunk == NULL) { + rc = ctx->next_filter(r, NULL); } else { - hunk_size = ctx->hunk_size; + + /* 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 (!ctx->hunk) - ngx_test_null(ctx->hunk, ngx_create_temp_hunk(hunk_size), ...); + 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; +} + - if (temp == FILE) { - n = ngx_read_file(hunk->fd, ctx->hunk->pos.mem, size); +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 (n == -1) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, ngx_errno, + 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 -1; + return NGX_ERROR; } else { - ngx_assert((n == size), /* void */ ; , - r->connection->log, 0, - ngx_read_file_n " reads only %d of %d for client", - n, size); + ngx_assert((n == size), /* void */ ; , log, + ngx_read_file_n " reads only %d of %d for client" _ + n _ size); } - hunk->pos.mem += n; - ctx->hunk->last.mem += n; + src->pos.mem += n; + dst->last.mem += n; - } else if (temp == COPY) { - ngx_memcpy(ctx->hunk->pos.mem, hunk->pos.mem, size); + } else { + ngx_memcpy(src->pos.mem, dst->pos.mem, size); - hunk->pos.mem += size; - ctx->hunk->last.mem += size; + src->pos.mem += size; + dst->last.mem += size; } + return NGX_OK; +} @@ -140,100 +244,4 @@ int ngx_http_filter(ngx_http_request_t * ) ctx->next_filter(r, NULL); } - - /* hunk != NULL || ctx->hunk->pos.mem == ctx->hunk->last.mem */ - - /* find last link of saved chain */ - prev = &ctx->out; - for (ch = ctx->out; ch; ch = ch->next) { - prev = &ch->next; - } - - if hunk - if need our hunk - alloc it and add to our queue - else add hunk to our queue - -/* - size += ch->hunk->last.file - ch->hunk->pos.file; - - ngx_log_debug(r->connection->log, "old chunk: %x %qx %qd" _ - ch->hunk->type _ ch->hunk->pos.file _ - ch->hunk->last.file - ch->hunk->pos.file); - - if (ch->hunk->type & NGX_HUNK_FLUSH) - flush = size; - - if (ch->hunk->type & NGX_HUNK_LAST) - last = 1; - } -*/ - - /* add new chain to existent one */ - for (/* void */; in; in = in->next) { - ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), - NGX_HTTP_FILTER_ERROR); - - ch->hunk = h; - ch->next = NULL; - *prev = ch; - prev = &ch->next; - size += ch->hunk->last.file - ch->hunk->pos.file; - - ngx_log_debug(r->connection->log, "new chunk: %x %qx %qd" _ - ch->hunk->type _ ch->hunk->pos.file _ - ch->hunk->last.file - ch->hunk->pos.file); - - if (ch->hunk->type & NGX_HUNK_FLUSH) - flush = size; - - if (ch->hunk->type & NGX_HUNK_LAST) - last = 1; - } - - - - - -/* - !(HAVE_SENDFILE) == NGX_FILT_NEED_IN_MEMORY -*/ - - if ((r->filter & NGX_FILT_NEED_IN_MEMORY) && (h->type & NGX_HUNK_FILE)) { - - size = h->last.mem - h->pos.mem; - if (size > ctx->hunk_size) - size = ctx->hunk_size; - - if (!ctx->hunk) - ngx_test_null(ctx->hunk, ngx_create_temp_hunk(size), ...); - - ngx_read_file(h->fd, ctx->hunk->pos.mem, size); - - h->hunk->pos.mem += size; - } - - if ((r->filter & NGX_FILT_NEED_TEMP) - && (h->type & NGX_HUNK_MEMORY|NGX_HUNK_MMAP)) - { - size = h->last.mem - h->pos.mem; - if (size > ctx->hunk_size) - size = ctx->hunk_size; - - if (!ctx->hunk) - ngx_test_null(ctx->hunk, ngx_create_temp_hunk(size), ...); - - ngx_memcpy(ctx->hunk->pos.mem, h->pos.mem, size); - - h->hunk->pos.mem += size; - } - - - - - - - rc = ctx->next_filter(r, ch); - - /* STUB */ - rc = ngx_http_write_filter(r, ch); } diff --git a/src/http/ngx_http_filter.h b/src/http/ngx_http_filter.h --- a/src/http/ngx_http_filter.h +++ b/src/http/ngx_http_filter.h @@ -2,9 +2,19 @@ #define _NGX_HTTP_FILTER_H_INCLUDED_ -#define NGX_HTTP_FILTER_ERROR -1 -#define NGX_HTTP_FILTER_AGAIN 0 -#define NGX_HTTP_FILTER_DONE 1 +#include + +#define NGX_HTTP_FILTER_NEED_IN_MEMORY 1 +#define NGX_HTTP_FILTER_NEED_TEMP 2 + +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_filter_ctx_t; #endif /* _NGX_HTTP_FILTER_H_INCLUDED_ */ 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 @@ -44,7 +44,7 @@ int ngx_http_write_filter(ngx_http_reque prev = &ch->next; size += ch->hunk->last.file - ch->hunk->pos.file; - ngx_log_debug(r->connection->log, "old chunk: %x %qx %qd" _ + ngx_log_debug(r->connection->log, "old chunk: %x " QX_FMT " " QD_FMT _ ch->hunk->type _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); @@ -57,8 +57,7 @@ int ngx_http_write_filter(ngx_http_reque /* add new chain to existent one */ for (/* void */; in; in = in->next) { - ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), - NGX_HTTP_FILTER_ERROR); + ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR); ch->hunk = in->hunk; ch->next = NULL; @@ -66,7 +65,7 @@ int ngx_http_write_filter(ngx_http_reque prev = &ch->next; size += ch->hunk->last.file - ch->hunk->pos.file; - ngx_log_debug(r->connection->log, "new chunk: %x %qx %qd" _ + ngx_log_debug(r->connection->log, "new chunk: %x " QX_FMT " " QD_FMT _ ch->hunk->type _ ch->hunk->pos.file _ ch->hunk->last.file - ch->hunk->pos.file); @@ -78,13 +77,13 @@ int ngx_http_write_filter(ngx_http_reque } if (!last && flush == 0 && size < ctx->buffer_output) - return NGX_HTTP_FILTER_DONE; + return NGX_OK; chain = ngx_event_write(r->connection, ctx->out, flush); if (chain == (ngx_chain_t *) -1) - return NGX_HTTP_FILTER_ERROR; + return NGX_ERROR; ctx->out = chain; - return (chain ? NGX_HTTP_FILTER_AGAIN : NGX_HTTP_FILTER_DONE); + return (chain ? NGX_AGAIN : NGX_OK); } diff --git a/src/os/unix/ngx_types.h b/src/os/unix/ngx_types.h --- a/src/os/unix/ngx_types.h +++ b/src/os/unix/ngx_types.h @@ -5,6 +5,8 @@ #include +#define QD_FMT "%qd" +#define QX_FMT "%qx" #endif /* _NGX_TYPES_H_INCLUDED_ */ diff --git a/src/os/win32/ngx_sendfile.c b/src/os/win32/ngx_sendfile.c --- a/src/os/win32/ngx_sendfile.c +++ b/src/os/win32/ngx_sendfile.c @@ -53,7 +53,7 @@ int ngx_sendfile(ngx_socket_t s, ptfb = NULL; } -#if 0 +#if 1 tfrc = TransmitFile(s, fd, nbytes, 0, &olp, ptfb, 0); #else tfrc = TransmitFile(s, fd, nbytes, 0, NULL, ptfb, 0); @@ -67,8 +67,13 @@ int ngx_sendfile(ngx_socket_t s, rc = WSAGetOverlappedResult(s, &olp, (unsigned long *) sent, 0, NULL); #endif +#if 0 ngx_log_debug(log, "ngx_sendfile: %d, @%I64d %I64d:%d" _ tfrc _ offset _ *sent _ nbytes); +#else + ngx_log_debug(log, "ngx_sendfile: %d, @%I64d %d:%d" _ + tfrc _ offset _ olp.InternalHigh _ nbytes); +#endif if (rc == 0) { err = ngx_socket_errno; diff --git a/src/os/win32/ngx_types.h b/src/os/win32/ngx_types.h --- a/src/os/win32/ngx_types.h +++ b/src/os/win32/ngx_types.h @@ -10,4 +10,8 @@ typedef long time_t; typedef unsigned __int64 off_t; +#define QD_FMT "%I64d" +#define QX_FMT "%I64x" + + #endif /* _NGX_TYPES_H_INCLUDED_ */