nginx-0.1.1-RELEASE import
*) Feature: the gzip_types directive.
*) Feature: the tcp_nodelay directive.
*) Feature: the send_lowat directive is working not only on OSes that
support kqueue NOTE_LOWAT, but also on OSes that support SO_SNDLOWAT.
*) Feature: the setproctitle() emulation for Linux and Solaris.
*) Bugfix: the "Location" header rewrite bug fixed while the proxying.
*) Bugfix: the ngx_http_chunked_module module may get caught in an
endless loop.
*) Bugfix: the /dev/poll module bugs fixed.
*) Bugfix: the responses were corrupted when the temporary files were
used while the proxying.
*) Bugfix: the unescaped requests were passed to the backend.
*) Bugfix: while the build configuration on Linux 2.4 the
--with-poll_module parameter was required.
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 7d68884..ea1d19b 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -202,13 +202,7 @@
#endif
#if (NGX_READ_EVENT != POLLIN)
- if (event == NGX_READ_EVENT) {
- event = POLLOUT;
-#if (NGX_WRITE_EVENT != POLLOUT)
- } else {
- event = POLLIN;
-#endif
- }
+ event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
#endif
#if (NGX_DEBUG)
@@ -218,6 +212,7 @@
#endif
ev->active = 1;
+
return ngx_devpoll_set_event(ev, event, 0);
}
@@ -229,6 +224,10 @@
c = ev->data;
+#if (NGX_READ_EVENT != POLLIN)
+ event = (event == NGX_READ_EVENT) ? POLLIN : POLLOUT;
+#endif
+
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
"devpoll del event: fd:%d ev:%04X", c->fd, event);
@@ -242,13 +241,9 @@
return NGX_OK;
}
- /* we need to restore the second event if it exists */
+ /* restore the paired event if it exists */
- if (event == NGX_READ_EVENT) {
- if (ev->accept) {
- return NGX_OK;
- }
-
+ if (event == POLLIN) {
e = c->write;
event = POLLOUT;
@@ -257,7 +252,7 @@
event = POLLIN;
}
- if (e) {
+ if (e && e->active) {
return ngx_devpoll_set_event(e, event, 0);
}
@@ -273,7 +268,7 @@
c = ev->data;
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
- "devpoll fd:%d ev:%d fl:%d", c->fd, event, flags);
+ "devpoll fd:%d ev:%04X fl:%04X", c->fd, event, flags);
if (nchanges >= max_changes) {
ngx_log_error(NGX_LOG_WARN, ev->log, 0,
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index 26b2c81..72c5b7c 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -131,10 +131,6 @@
{
ngx_rtsig_conf_t *rtscf;
- if (ngx_poll_module_ctx.actions.init(cycle) == NGX_ERROR) {
- return NGX_ERROR;
- }
-
rtscf = ngx_event_get_conf(cycle->conf_ctx, ngx_rtsig_module);
sigemptyset(&set);
@@ -170,7 +166,9 @@
static void ngx_rtsig_done(ngx_cycle_t *cycle)
{
- ngx_poll_module_ctx.actions.done(cycle);
+ ngx_free(overflow_list);
+
+ overflow_list = NULL;
}
@@ -697,7 +695,7 @@
* the new overflow.
*
* Learn the /proc/sys/kernel/rtsig-max value because
- * it can be changed sisnce the last checking.
+ * it can be changed since the last checking.
*/
name[0] = CTL_KERN;
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 3d7e15c..4718dcd 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -461,6 +461,39 @@
}
+ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat)
+{
+ int sndlowat;
+
+#if (HAVE_LOWAT_EVENT)
+
+ if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+ c->write->available = lowat;
+ return NGX_OK;
+ }
+
+#endif
+
+ if (lowat == 0 || c->sndlowat) {
+ return NGX_OK;
+ }
+
+ sndlowat = (int) lowat;
+
+ if (setsockopt(c->fd, SOL_SOCKET, SO_SNDLOWAT,
+ (const void *) &sndlowat, sizeof(int)) == -1)
+ {
+ ngx_connection_error(c, ngx_socket_errno,
+ "setsockopt(SO_SNDLOWAT) failed");
+ return NGX_ERROR;
+ }
+
+ c->sndlowat = 1;
+
+ return NGX_OK;
+}
+
+
static char *ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
int m;
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 7237bd4..c173adc 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -207,7 +207,7 @@
ngx_int_t (*add_conn)(ngx_connection_t *c);
ngx_int_t (*del_conn)(ngx_connection_t *c, u_int flags);
- ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t try);
+ ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);
ngx_int_t (*process_events)(ngx_cycle_t *cycle);
ngx_int_t (*init)(ngx_cycle_t *cycle);
@@ -479,6 +479,9 @@
#endif
+ngx_int_t ngx_send_lowat(ngx_connection_t *c, size_t lowat);
+
+
/* used in ngx_log_debugX() */
#define ngx_event_ident(p) ((ngx_connection_t *) (p))->fd
@@ -497,7 +500,7 @@
{
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
- /* kqueue */
+ /* kqueue, epoll */
if (!rev->active && !rev->ready) {
if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT)
@@ -531,7 +534,7 @@
}
}
- /* aio, iocp, epoll, rtsig */
+ /* aio, iocp, rtsig */
return NGX_OK;
}
@@ -563,14 +566,25 @@
}
-ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, u_int flags)
+ngx_inline static int ngx_handle_write_event(ngx_event_t *wev, size_t lowat)
{
+ ngx_connection_t *c;
+
+ if (lowat) {
+ c = wev->data;
+
+ if (ngx_send_lowat(c, lowat) == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+ }
+
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
- /* kqueue */
+ /* kqueue, epoll */
if (!wev->active && !wev->ready) {
- if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT|flags)
+ if (ngx_add_event(wev, NGX_WRITE_EVENT,
+ NGX_CLEAR_EVENT | (lowat ? NGX_LOWAT_EVENT : 0))
== NGX_ERROR)
{
return NGX_ERROR;
@@ -602,7 +616,7 @@
}
}
- /* aio, iocp, epoll, rtsig */
+ /* aio, iocp, rtsig */
return NGX_OK;
}
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 8c48a7a..151cc42 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -72,6 +72,13 @@
return n;
}
+ if (!SSL_is_init_finished(c->ssl->ssl)) {
+ handshake = "in SSL handshake";
+
+ } else {
+ handshake = "";
+ }
+
sslerr = SSL_get_error(c->ssl->ssl, n);
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
@@ -91,13 +98,6 @@
#endif
}
- if (!SSL_is_init_finished(c->ssl->ssl)) {
- handshake = "in SSL handshake";
-
- } else {
- handshake = "";
- }
-
c->ssl->no_rcv_shut = 1;
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
@@ -240,8 +240,9 @@
static ngx_int_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
{
- int n, sslerr;
- ngx_err_t err;
+ int n, sslerr;
+ ngx_err_t err;
+ char *handshake;
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %d", size);
@@ -265,13 +266,21 @@
}
if (sslerr == SSL_ERROR_WANT_READ) {
+
+ if (!SSL_is_init_finished(c->ssl->ssl)) {
+ handshake = "in SSL handshake";
+
+ } else {
+ handshake = "";
+ }
+
ngx_log_error(NGX_LOG_ALERT, c->log, err,
"SSL wants to read%s", handshake);
return NGX_ERROR;
#if 0
return NGX_AGAIN;
- }
#endif
+ }
c->ssl->no_rcv_shut = 1;
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index c1982fd..71fc500 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -64,8 +64,7 @@
if (p->downstream->fd != -1) {
wev = p->downstream->write;
- wev->available = p->send_lowat;
- if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
+ if (ngx_handle_write_event(wev, p->send_lowat) == NGX_ERROR) {
return NGX_ABORT;
}
@@ -302,16 +301,41 @@
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0, "pipe buf");
}
- for (cl = p->in; cl; cl = cl->next) {
+ for (cl = p->busy; cl; cl = cl->next) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe buf in " PTR_FMT ", pos " PTR_FMT ", size: %d",
+ "pipe buf busy " PTR_FMT ", pos " PTR_FMT ", size: %d",
cl->buf->start, cl->buf->pos,
cl->buf->last - cl->buf->pos);
}
- for (cl = p->busy; cl; cl = cl->next) {
+ for (cl = p->out; cl; cl = cl->next) {
+ if (cl->buf->in_file && cl->buf->temporary) {
+ ngx_log_debug5(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "pipe buf out shadow "
+ PTR_FMT ", pos " PTR_FMT ", size: %d "
+ "file: " OFF_T_FMT ", size: %d",
+ cl->buf->start, cl->buf->pos,
+ cl->buf->last - cl->buf->pos,
+ cl->buf->file_pos,
+ cl->buf->file_last - cl->buf->file_pos);
+
+ } else if (cl->buf->in_file) {
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "pipe buf out file " OFF_T_FMT ", size: %d",
+ cl->buf->file_pos,
+ cl->buf->file_last - cl->buf->file_pos);
+ } else {
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
+ "pipe buf out " PTR_FMT ", pos " PTR_FMT
+ ", size: %d",
+ cl->buf->start, cl->buf->pos,
+ cl->buf->last - cl->buf->pos);
+ }
+ }
+
+ for (cl = p->in; cl; cl = cl->next) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
- "pipe buf busy " PTR_FMT ", pos " PTR_FMT ", size: %d",
+ "pipe buf in " PTR_FMT ", pos " PTR_FMT ", size: %d",
cl->buf->start, cl->buf->pos,
cl->buf->last - cl->buf->pos);
}
@@ -337,7 +361,9 @@
if (p->free_bufs) {
for (cl = p->free_raw_bufs; cl; cl = cl->next) {
- ngx_pfree(p->pool, cl->buf->start);
+ if (cl->buf->shadow == NULL) {
+ ngx_pfree(p->pool, cl->buf->start);
+ }
}
}
}
@@ -597,8 +623,11 @@
ngx_chain_add_link(p->out, p->last_out, cl);
if (b->last_shadow) {
- b->shadow->last = b->shadow->pos = b->shadow->start;
+ b->shadow->pos = b->shadow->start;
+ b->shadow->last = b->shadow->start;
+
ngx_alloc_link_and_set_buf(tl, b->shadow, p->pool, NGX_ABORT);
+
*last_free = tl;
last_free = &tl->next;
}
@@ -650,28 +679,24 @@
{
ngx_buf_t *b, *next;
- if (buf->shadow == NULL) {
+ b = buf->shadow;
+
+ if (b == NULL) {
return;
}
- b = buf->shadow;
-
while (!b->last_shadow) {
next = b->shadow;
- b->in_file = 0;
- b->temp_file = 0;
- b->flush = 0;
- b->zerocopy_busy = 0;
+ b->temporary = 0;
+ b->recycled = 0;
b->shadow = NULL;
b = next;
}
- b->in_file = 0;
- b->temp_file = 0;
- b->flush = 0;
- b->zerocopy_busy = 0;
+ b->temporary = 0;
+ b->recycled = 0;
b->last_shadow = 0;
b->shadow = NULL;