nginx-0.0.1-2003-10-28-18:45:41 import

This commit is contained in:
Igor Sysoev 2003-10-28 15:45:41 +00:00
parent 2b0c76cfbd
commit ab0c4f5038
10 changed files with 200 additions and 193 deletions

View File

@ -17,8 +17,6 @@
#define ngx_test_null(p, alloc, rc) if ((p = alloc) == NULL) { return rc; } #define ngx_test_null(p, alloc, rc) if ((p = alloc) == NULL) { return rc; }
#define ngx_is_null(p, alloc) if ((p = alloc) == NULL)
typedef struct ngx_pool_large_s ngx_pool_large_t; typedef struct ngx_pool_large_s ngx_pool_large_t;

View File

@ -422,8 +422,8 @@ static int ngx_kqueue_process_events(ngx_log_t *log)
ev->available = event_list[i].data; ev->available = event_list[i].data;
if (event_list[i].flags & EV_EOF) { if (event_list[i].flags & EV_EOF) {
ev->eof = 1; ev->kq_eof = 1;
ev->error = event_list[i].fflags; ev->kq_errno = event_list[i].fflags;
} }
if (ev->oneshot && ev->timer_set) { if (ev->oneshot && ev->timer_set) {

View File

@ -29,8 +29,9 @@ struct ngx_event_s {
unsigned int index; unsigned int index;
ngx_event_t *prev; /* queue in mutex(), aio_read(), aio_write() */ /* queue in mutex(), aio_read(), aio_write() */
ngx_event_t *next; /* */ ngx_event_t *prev;
ngx_event_t *next;
ngx_event_t *timer_prev; ngx_event_t *timer_prev;
ngx_event_t *timer_next; ngx_event_t *timer_next;
@ -40,22 +41,22 @@ struct ngx_event_s {
ngx_log_t *log; ngx_log_t *log;
int available; /* kqueue only: */ /*
/* accept: number of sockets that wait */ * kqueue only:
/* to be accepted */ * accept: number of sockets that wait to be accepted
/* read: bytes to read */ * read: bytes to read
/* write: available space in buffer */ * write: available space in buffer
/* otherwise: */ *
/* accept: 1 if accept many, 0 otherwise */ * otherwise:
* accept: 1 if accept many, 0 otherwise
*/
int available;
unsigned oneshot:1; unsigned oneshot:1;
#if 0
unsigned listening:1;
#endif
unsigned write:1; unsigned write:1;
/* used to detect stale events in kqueue, rt signals and epoll */ /* used to detect the stale events in kqueue, rt signals and epoll */
unsigned instance:1; unsigned instance:1;
/* /*
@ -67,12 +68,12 @@ struct ngx_event_s {
/* ready event; the complete aio operation */ /* ready event; the complete aio operation */
unsigned ready:1; unsigned ready:1;
unsigned eof:1;
unsigned error:1;
unsigned timedout:1; unsigned timedout:1;
unsigned timer_set:1; unsigned timer_set:1;
#if 1
unsigned blocked:1;
#endif
unsigned delayed:1; unsigned delayed:1;
unsigned read_discarded:1; unsigned read_discarded:1;
@ -87,8 +88,8 @@ struct ngx_event_s {
#endif #endif
#if (HAVE_KQUEUE) #if (HAVE_KQUEUE)
unsigned eof:1; unsigned kq_eof:1;
int error; int kq_errno;
#endif #endif
#if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */ #if (HAVE_LOWAT_EVENT) /* kqueue's NOTE_LOWAT */
@ -108,41 +109,27 @@ struct ngx_event_s {
#if 0 #if 0
void *thr_ctx; /* event thread context if $(CC) doesn't
understand __thread declaration /* the threads support */
and pthread_getspecific() is too costly */
/*
* the event thread context, we store it here
* if $(CC) does not understand __thread declaration
* and pthread_getspecific() is too costly
*/
void *thr_ctx;
#if (NGX_EVENT_T_PADDING) #if (NGX_EVENT_T_PADDING)
int padding[NGX_EVENT_T_PADDING]; /* event should not cross
cache line in SMP */ /* event should not cross cache line in SMP */
int padding[NGX_EVENT_T_PADDING];
#endif #endif
#endif #endif
}; };
#if 1
typedef enum {
NGX_SELECT_EVENT_N = 0,
#if (HAVE_POLL)
NGX_POLL_EVENT_N,
#endif
#if (HAVE_DEVPOLL)
NGX_DEVPOLL_EVENT_N,
#endif
#if (HAVE_KQUEUE)
NGX_KQUEUE_EVENT_N,
#endif
#if (HAVE_AIO)
NGX_AIO_EVENT_N,
#endif
#if (HAVE_IOCP)
NGX_IOCP_EVENT_N,
#endif
NGX_DUMMY_EVENT_N /* avoid comma at end of enumerator list */
} ngx_event_type_e ;
#endif
typedef struct { typedef struct {
int (*add)(ngx_event_t *ev, int event, u_int flags); int (*add)(ngx_event_t *ev, int event, u_int flags);
int (*del)(ngx_event_t *ev, int event, u_int flags); int (*del)(ngx_event_t *ev, int event, u_int flags);
@ -159,6 +146,9 @@ typedef struct {
} ngx_event_actions_t; } ngx_event_actions_t;
extern ngx_event_actions_t ngx_event_actions;
/* /*
* The event filter requires to read/write the whole data - * The event filter requires to read/write the whole data -
* select, poll, /dev/poll, kqueue. * select, poll, /dev/poll, kqueue.
@ -243,12 +233,8 @@ typedef struct {
#define NGX_ONESHOT_EVENT EV_ONESHOT #define NGX_ONESHOT_EVENT EV_ONESHOT
#define NGX_CLEAR_EVENT EV_CLEAR #define NGX_CLEAR_EVENT EV_CLEAR
#ifndef HAVE_CLEAR_EVENT
#define HAVE_CLEAR_EVENT 1
#endif
#elif (HAVE_POLL)
#elif (HAVE_POLL) || (HAVE_DEVPOLL)
#define NGX_READ_EVENT POLLIN #define NGX_READ_EVENT POLLIN
#define NGX_WRITE_EVENT POLLOUT #define NGX_WRITE_EVENT POLLOUT
@ -256,7 +242,16 @@ typedef struct {
#define NGX_LEVEL_EVENT 0 #define NGX_LEVEL_EVENT 0
#define NGX_ONESHOT_EVENT 1 #define NGX_ONESHOT_EVENT 1
#else
#elif (HAVE_DEVPOLL)
#define NGX_READ_EVENT POLLIN
#define NGX_WRITE_EVENT POLLOUT
#define NGX_LEVEL_EVENT 0
#else /* select */
#define NGX_READ_EVENT 0 #define NGX_READ_EVENT 0
#define NGX_WRITE_EVENT 1 #define NGX_WRITE_EVENT 1
@ -266,84 +261,35 @@ typedef struct {
#endif /* HAVE_KQUEUE */ #endif /* HAVE_KQUEUE */
#ifndef NGX_CLEAR_EVENT
#define NGX_CLEAR_EVENT 0 /* dummy */
#endif
#if (USE_KQUEUE)
#define ngx_init_events ngx_kqueue_init
#define ngx_process_events ngx_kqueue_process_events
#define ngx_add_event ngx_kqueue_add_event
#define ngx_del_event ngx_kqueue_del_event
#if 0
#define ngx_add_timer ngx_kqueue_add_timer
#else
#define ngx_add_timer ngx_event_add_timer
#endif
#define ngx_event_recv ngx_event_recv_core
#else
#define ngx_init_events (ngx_event_init[ngx_event_type])
#define ngx_process_events ngx_event_actions.process
#define ngx_add_event ngx_event_actions.add
#define ngx_del_event ngx_event_actions.del
#define ngx_add_conn ngx_event_actions.add_conn
#define ngx_del_conn ngx_event_actions.del_conn
#if 0
#if (HAVE_IOCP_EVENT)
#define ngx_event_recv ngx_event_wsarecv
#elif (HAVE_AIO_EVENT)
#define ngx_event_recv ngx_event_aio_read
#else
#define ngx_event_recv ngx_io.recv
#define ngx_write_chain ngx_io.send_chain
#endif
#endif
#endif
/* ***************************** */
#define ngx_recv ngx_io.recv
#define ngx_recv_chain ngx_io.recv_chain
#define ngx_write_chain ngx_io.send_chain
#define ngx_add_timer ngx_event_add_timer
#define ngx_del_timer ngx_event_del_timer
#if (HAVE_IOCP_EVENT) #if (HAVE_IOCP_EVENT)
#define NGX_IOCP_ACCEPT 0 #define NGX_IOCP_ACCEPT 0
#define NGX_IOCP_IO 1 #define NGX_IOCP_IO 1
#endif #endif
/* ***************************** */
#ifndef NGX_CLEAR_EVENT
#define NGX_CLEAR_EVENT 0 /* dummy declaration */
#if !(USE_KQUEUE)
extern ngx_event_actions_t ngx_event_actions;
extern ngx_event_type_e ngx_event_type;
extern int ngx_event_flags;
#endif #endif
#define ngx_process_events ngx_event_actions.process
#define ngx_add_event ngx_event_actions.add
#define ngx_del_event ngx_event_actions.del
#define ngx_add_conn ngx_event_actions.add_conn
#define ngx_del_conn ngx_event_actions.del_conn
#define ngx_add_timer ngx_event_add_timer
#define ngx_del_timer ngx_event_del_timer
#define ngx_recv ngx_io.recv
#define ngx_recv_chain ngx_io.recv_chain
#define ngx_write_chain ngx_io.send_chain
/* ***************************** */
#define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */
#define NGX_EVENT_CONF 0x00200000 #define NGX_EVENT_CONF 0x00200000
@ -364,8 +310,10 @@ typedef struct {
} ngx_event_module_t; } ngx_event_module_t;
extern ngx_module_t ngx_events_module;
extern ngx_module_t ngx_event_core_module; extern int ngx_event_flags;
extern ngx_module_t ngx_events_module;
extern ngx_module_t ngx_event_core_module;
#define ngx_event_get_conf(conf_ctx, module) \ #define ngx_event_get_conf(conf_ctx, module) \
@ -380,24 +328,10 @@ void ngx_event_acceptex(ngx_event_t *ev);
int ngx_event_post_acceptex(ngx_listening_t *ls, int n); int ngx_event_post_acceptex(ngx_listening_t *ls, int n);
#endif #endif
/* ***************************** */
ssize_t ngx_event_recv_core(ngx_connection_t *c, char *buf, size_t size);
int ngx_event_close_connection(ngx_event_t *ev);
int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log);
void ngx_worker(ngx_cycle_t *cycle);
/* ***************************** */
#include <ngx_event_timer.h> #include <ngx_event_timer.h>
#if (WIN32) #if (WIN32)
#include <ngx_iocp_module.h> #include <ngx_iocp_module.h>
#endif #endif
@ -437,8 +371,9 @@ ngx_inline static int ngx_handle_read_event(ngx_event_t *rev)
return NGX_OK; return NGX_OK;
} }
if (rev->active && rev->ready) { if (rev->active && (rev->ready || rev->eof)) {
if (ngx_del_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) { if (ngx_del_event(rev, NGX_READ_EVENT, rev->eof ? NGX_CLOSE_EVENT : 0)
== NGX_ERROR) {
return NGX_ERROR; return NGX_ERROR;
} }
@ -551,7 +486,4 @@ ngx_inline static int ngx_handle_level_write_event(ngx_event_t *wev)
} }
/* ***************************** */
#endif /* _NGX_EVENT_H_INCLUDED_ */ #endif /* _NGX_EVENT_H_INCLUDED_ */

View File

@ -98,20 +98,46 @@ int ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
if (ngx_event_flags == NGX_HAVE_KQUEUE_EVENT) { if (ngx_event_flags == NGX_HAVE_KQUEUE_EVENT) {
if (p->upstream->read->error) { if (p->upstream->read->available == 0) {
ngx_log_error(NGX_LOG_ERR, p->log, p->upstream->read->error, if (p->upstream->read->kq_eof) {
p->upstream->read->ready = 0;
p->upstream->read->eof = 0;
p->upstream_eof = 1;
p->read = 1;
if (p->upstream->read->kq_errno) {
p->upstream->read->error = 1;
p->upstream_error = 1;
p->upstream_eof = 0;
ngx_log_error(NGX_LOG_ERR, p->log,
p->upstream->read->kq_errno,
/* TODO: ngx_readv_chain_n */
"readv() failed");
}
break;
}
}
#if 0
if (p->upstream->read->kq_errno) {
ngx_log_error(NGX_LOG_ERR, p->log,
p->upstream->read->kq_errno,
"readv() failed"); "readv() failed");
p->upstream_error = 1; p->upstream_error = 1;
break; break;
} else if (p->upstream->read->eof } else if (p->upstream->read->kq_eof
&& p->upstream->read->available == 0) { && p->upstream->read->available == 0) {
p->upstream_eof = 1; p->upstream_eof = 1;
p->read = 1; p->read = 1;
break; break;
} }
#endif
} }
#endif #endif

View File

@ -110,6 +110,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
offsetof(ngx_http_proxy_loc_conf_t, temp_file_write_size), offsetof(ngx_http_proxy_loc_conf_t, temp_file_write_size),
NULL}, NULL},
{ngx_string("proxy_pass_server"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_proxy_loc_conf_t, pass_server),
NULL},
ngx_null_command ngx_null_command
}; };
@ -237,19 +244,11 @@ ngx_log_debug(r->connection->log, "timer_set: %d" _
ngx_del_timer(r->connection->read); ngx_del_timer(r->connection->read);
} }
ngx_is_null(cl, ngx_http_proxy_create_request(p)) { if (!(cl = ngx_http_proxy_create_request(p))) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return; return;
} }
#if 0
cl = ngx_http_proxy_create_request(p);
if (cl == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
#endif
if (r->request_hunks) { if (r->request_hunks) {
cl->next = r->request_hunks; cl->next = r->request_hunks;
} }
@ -266,6 +265,7 @@ ngx_log_debug(r->connection->log, "timer_set: %d" _
out_ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); out_ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
if (out_ctx == NULL) { if (out_ctx == NULL) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
} }
p->output_chain_ctx = out_ctx; p->output_chain_ctx = out_ctx;
@ -288,6 +288,7 @@ ngx_log_debug(r->connection->log, "timer_set: %d" _
write_ctx = ngx_pcalloc(r->pool, sizeof(ngx_chain_write_ctx_t)); write_ctx = ngx_pcalloc(r->pool, sizeof(ngx_chain_write_ctx_t));
if (write_ctx == NULL) { if (write_ctx == NULL) {
ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
} }
out_ctx->output_ctx = write_ctx; out_ctx->output_ctx = write_ctx;
@ -767,7 +768,7 @@ static void ngx_http_proxy_process_upstream_headers(ngx_event_t *rev)
return; return;
} }
/* NGX_AGAIN: a header line parsing is still not complete */ /* rc == NGX_AGAIN: a header line parsing is still not complete */
if (p->header_in->last == p->header_in->end) { if (p->header_in->last == p->header_in->end) {
ngx_log_error(NGX_LOG_ERR, rev->log, 0, ngx_log_error(NGX_LOG_ERR, rev->log, 0,
@ -835,6 +836,8 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
r = p->request; r = p->request;
r->headers_out.status = p->status;
r->headers_out.content_length_n = -1; r->headers_out.content_length_n = -1;
r->headers_out.content_length = NULL; r->headers_out.content_length = NULL;
@ -852,6 +855,16 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
|| &ph[i] == p->headers_in.accept_ranges) { || &ph[i] == p->headers_in.accept_ranges) {
continue; continue;
} }
if (&ph[i] == p->headers_in.server && !p->lcf->pass_server) {
continue;
}
}
if (&ph[i] == p->headers_in.content_type) {
r->headers_out.content_type = &ph[i];
r->headers_out.content_type->key.len = 0;
continue;
} }
ch = ngx_push_table(r->headers_out.headers); ch = ngx_push_table(r->headers_out.headers);
@ -862,13 +875,26 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
*ch = ph[i]; *ch = ph[i];
if (&ph[i] == p->headers_in.content_type) { /*
r->headers_out.content_type = ch; * ngx_http_header_filter() output the following headers
r->headers_out.content_type->key.len = 0; * from r->headers_out.headers if they are set:
* r->headers_out.server,
* r->headers_out.date,
* r->headers_out.content_length
*/
if (&ph[i] == p->headers_in.server) {
r->headers_out.server = ch;
continue;
}
if (&ph[i] == p->headers_in.date) {
r->headers_out.date = ch;
continue; continue;
} }
if (&ph[i] == p->headers_in.content_length) { if (&ph[i] == p->headers_in.content_length) {
r->headers_out.content_length_n = r->headers_out.content_length_n =
ngx_atoi(p->headers_in.content_length->value.data, ngx_atoi(p->headers_in.content_length->value.data,
p->headers_in.content_length->value.len); p->headers_in.content_length->value.len);
@ -877,23 +903,9 @@ static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p)
} }
} }
/* STUB */
if (p->headers_in.server) {
r->headers_out.server = p->headers_in.server;
}
if (!p->accel && p->headers_in.date) {
r->headers_out.date = p->headers_in.date;
}
/* */
/* TODO: preallocate event_pipe hunks, look "Content-Length" */ /* TODO: preallocate event_pipe hunks, look "Content-Length" */
r->headers_out.status = p->status;
rc = ngx_http_send_header(r); rc = ngx_http_send_header(r);
p->header_sent = 1; p->header_sent = 1;
@ -1413,6 +1425,8 @@ static void *ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->next_upstream = NGX_CONF_UNSET; conf->next_upstream = NGX_CONF_UNSET;
conf->pass_server = NGX_CONF_UNSET;
return conf; return conf;
} }
@ -1451,6 +1465,8 @@ static char *ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf,
ngx_conf_merge_path_value(conf->temp_path, prev->temp_path, ngx_conf_merge_path_value(conf->temp_path, prev->temp_path,
"temp", 1, 2, 0, cf->pool); "temp", 1, 2, 0, cf->pool);
ngx_conf_merge_value(conf->pass_server, prev->pass_server, 0);
return NULL; return NULL;
} }

View File

@ -32,6 +32,8 @@ typedef struct {
ssize_t temp_file_write_size; ssize_t temp_file_write_size;
int cyclic_temp_file; int cyclic_temp_file;
int pass_server;
int next_upstream; int next_upstream;
ngx_path_t *temp_path; ngx_path_t *temp_path;

View File

@ -138,7 +138,7 @@ static ngx_command_t ngx_http_core_commands[] = {
NULL}, NULL},
{ngx_string("sendfile"), {ngx_string("sendfile"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot, ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, sendfile), offsetof(ngx_http_core_loc_conf_t, sendfile),
@ -173,7 +173,7 @@ static ngx_command_t ngx_http_core_commands[] = {
NULL}, NULL},
{ngx_string("msie_padding"), {ngx_string("msie_padding"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot, ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET, NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, msie_padding), offsetof(ngx_http_core_loc_conf_t, msie_padding),

View File

@ -25,8 +25,8 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
{ {
int rc, eintr, eagain; int rc, eintr, eagain;
char *prev; char *prev;
ssize_t hsize, fsize, size;
off_t sent, fprev; off_t sent, fprev;
ssize_t hsize, fsize, size;
struct iovec *iov; struct iovec *iov;
struct sf_hdtr hdtr; struct sf_hdtr hdtr;
ngx_err_t err; ngx_err_t err;
@ -67,15 +67,14 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
if (prev == cl->hunk->pos) { if (prev == cl->hunk->pos) {
iov->iov_len += cl->hunk->last - cl->hunk->pos; iov->iov_len += cl->hunk->last - cl->hunk->pos;
prev = cl->hunk->last;
} else { } else {
ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR); ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR);
iov->iov_base = cl->hunk->pos; iov->iov_base = cl->hunk->pos;
iov->iov_len = cl->hunk->last - cl->hunk->pos; iov->iov_len = cl->hunk->last - cl->hunk->pos;
prev = cl->hunk->last;
} }
prev = cl->hunk->last;
hsize += cl->hunk->last - cl->hunk->pos; hsize += cl->hunk->last - cl->hunk->pos;
} }
@ -118,14 +117,14 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
if (prev == cl->hunk->pos) { if (prev == cl->hunk->pos) {
iov->iov_len += cl->hunk->last - cl->hunk->pos; iov->iov_len += cl->hunk->last - cl->hunk->pos;
prev = cl->hunk->last;
} else { } else {
ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR); ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR);
iov->iov_base = cl->hunk->pos; iov->iov_base = cl->hunk->pos;
iov->iov_len = cl->hunk->last - cl->hunk->pos; iov->iov_len = cl->hunk->last - cl->hunk->pos;
prev = cl->hunk->last;
} }
prev = cl->hunk->last;
} }
/* /*
@ -182,6 +181,7 @@ ngx_log_debug(c->log, "NOPUSH");
"sendfile() sent only %qd bytes", sent); "sendfile() sent only %qd bytes", sent);
} else { } else {
c->write->error = 1;
ngx_log_error(NGX_LOG_CRIT, c->log, err, ngx_log_error(NGX_LOG_CRIT, c->log, err,
"sendfile() failed"); "sendfile() failed");
return NGX_CHAIN_ERROR; return NGX_CHAIN_ERROR;
@ -206,6 +206,7 @@ ngx_log_debug(c->log, "NOPUSH");
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR"); ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
} else { } else {
c->write->error = 1;
ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed"); ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
return NGX_CHAIN_ERROR; return NGX_CHAIN_ERROR;
} }

View File

@ -6,23 +6,30 @@
ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain) ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
{ {
char *prev;
ssize_t n; ssize_t n;
struct iovec *iov; struct iovec *iov;
ngx_err_t err; ngx_err_t err;
ngx_array_t io; ngx_array_t io;
#if (NGX_SUPPRESS_WARN) prev = NULL;
iov = NULL; iov = NULL;
#endif
ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR); ngx_init_array(io, c->pool, 10, sizeof(struct iovec), NGX_ERROR);
/* TODO: coalesce the neighbouring chain entries */ /* coalesce the neighbouring hunks */
while (chain) { while (chain) {
ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR); if (prev == chain->hunk->last) {
iov->iov_base = chain->hunk->last; iov->iov_len += chain->hunk->end - chain->hunk->last;
iov->iov_len = chain->hunk->end - chain->hunk->last;
} else {
ngx_test_null(iov, ngx_push_array(&io), NGX_ERROR);
iov->iov_base = chain->hunk->last;
iov->iov_len = chain->hunk->end - chain->hunk->last;
}
prev = chain->hunk->end;
chain = chain->next; chain = chain->next;
} }
@ -30,8 +37,12 @@ ngx_log_debug(c->log, "recv: %d:%d" _ io.nelts _ iov->iov_len);
n = readv(c->fd, (struct iovec *) io.elts, io.nelts); n = readv(c->fd, (struct iovec *) io.elts, io.nelts);
if (n == -1) { if (n == 0) {
c->read->eof = 1;
} else if (n == -1) {
c->read->ready = 0; c->read->ready = 0;
c->read->error = 1;
err = ngx_errno; err = ngx_errno;
if (err == NGX_EAGAIN) { if (err == NGX_EAGAIN) {

View File

@ -18,15 +18,19 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
ngx_log_debug(c->log, "recv: eof:%d, avail:%d, err:%d" _ ngx_log_debug(c->log, "recv: eof:%d, avail:%d, err:%d" _
rev->eof _ rev->available _ rev->error); rev->kq_eof _ rev->available _ rev->kq_errno);
if (rev->available == 0) { if (rev->available == 0) {
if (rev->eof) { if (rev->kq_eof) {
rev->ready = 0; rev->ready = 0;
if (rev->error) { rev->eof = 1;
ngx_set_socket_errno(rev->error);
return ngx_unix_recv_error(rev, rev->error); if (rev->kq_errno) {
rev->error = 1;
ngx_set_socket_errno(rev->kq_errno);
return ngx_unix_recv_error(rev, rev->kq_errno);
} }
return 0; return 0;
} else { } else {
@ -43,8 +47,14 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
if (n >= 0) { if (n >= 0) {
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
rev->available -= n; rev->available -= n;
/*
* rev->available can be negative here because some additional
* bytes can be received between kevent() and recv()
*/
if (rev->available <= 0) { if (rev->available <= 0) {
if (!rev->eof) { if (!rev->kq_eof) {
rev->ready = 0; rev->ready = 0;
} }
@ -60,10 +70,15 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
rev->ready = 0; rev->ready = 0;
} }
if (n == 0) {
rev->eof = 1;
}
return n; return n;
} }
rev->ready = 0; rev->ready = 0;
rev->error = 1;
n = ngx_unix_recv_error(rev, ngx_socket_errno); n = ngx_unix_recv_error(rev, ngx_socket_errno);
} while (n == NGX_EINTR); } while (n == NGX_EINTR);
@ -89,10 +104,16 @@ ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size)
if ((size_t) n < size) { if ((size_t) n < size) {
rev->ready = 0; rev->ready = 0;
} }
if (n == 0) {
rev->eof = 1;
}
return n; return n;
} }
rev->ready = 0; rev->ready = 0;
rev->error = 1;
n = ngx_unix_recv_error(rev, ngx_socket_errno); n = ngx_unix_recv_error(rev, ngx_socket_errno);
} while (n == NGX_EINTR); } while (n == NGX_EINTR);