diff --git a/auto/cc b/auto/cc index 67f364d4e..16684b0c8 100644 --- a/auto/cc +++ b/auto/cc @@ -62,8 +62,8 @@ case $CC in # debug CFLAGS="$CFLAGS -g" - # DragonFly's gcc3 generate DWARF - CFLAGS="$CFLAGS -g -gstabs" + # DragonFly's gcc3 generates DWARF + #CFLAGS="$CFLAGS -g -gstabs" have=HAVE_GCC_VARIADIC_MACROS . auto/have diff --git a/auto/modules b/auto/modules index e2c909280..8fcaf8a22 100644 --- a/auto/modules +++ b/auto/modules @@ -1,10 +1,4 @@ -if [ $EVENT_RTSIG = YES ]; then - have=HAVE_RTSIG . auto/have - EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE" - CORE_SRCS="$CORE_SRCS $RTSIG_SRCS" -fi - if [ $EVENT_SELECT = NO -a $EVENT_FOUND = NO ]; then EVENT_SELECT=YES fi diff --git a/auto/nohave b/auto/nohave new file mode 100644 index 000000000..49bb7ceb8 --- /dev/null +++ b/auto/nohave @@ -0,0 +1,8 @@ + +cat << END >> $NGX_AUTO_CONFIG_H + +#ifndef $have +#define $have 0 +#endif + +END diff --git a/auto/os/freebsd b/auto/os/freebsd index 82e442c56..5fa8e33e3 100644 --- a/auto/os/freebsd +++ b/auto/os/freebsd @@ -42,8 +42,8 @@ then have=HAVE_KQUEUE . auto/have have=HAVE_CLEAR_EVENT . auto/have - CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS" EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE" + CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS" EVENT_FOUND=YES fi @@ -60,6 +60,9 @@ fi if [ $EVENT_AIO = YES ]; then - CORE_SRCS="$CORE_SRCS $AIO_SRCS" + have=HAVE_AIO . auto/have EVENT_MODULES="$EVENT_MODULES $AIO_MODULE" + CORE_SRCS="$CORE_SRCS $AIO_SRCS" +else + have=HAVE_AIO . auto/nohave fi diff --git a/auto/os/linux b/auto/os/linux index 78ab3d14b..4a9823dd9 100644 --- a/auto/os/linux +++ b/auto/os/linux @@ -30,6 +30,15 @@ if [ $ngx_found = yes ]; then fi +# rtsig + +if [ $EVENT_RTSIG = YES ]; then + have=HAVE_RTSIG . auto/have + EVENT_MODULES="$EVENT_MODULES $RTSIG_MODULE" + CORE_SRCS="$CORE_SRCS $RTSIG_SRCS" +fi + + # sendfile() CC_TEST_FLAGS="-D_GNU_SOURCE" diff --git a/src/core/ngx_atomic.h b/src/core/ngx_atomic.h index 311ef8892..6270d8a51 100644 --- a/src/core/ngx_atomic.h +++ b/src/core/ngx_atomic.h @@ -64,7 +64,7 @@ static ngx_inline uint32_t ngx_atomic_cmp_set(ngx_atomic_t *lock, " setz %%al; " " movzbl %%al, %0; " - : "+a" (res) : "m" (*lock), "a" (old), "q" (set)); + : "=a" (res) : "m" (*lock), "a" (old), "q" (set)); return res; } diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 3fc8d0ef4..8f0336a9b 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -374,28 +374,29 @@ static int ngx_http_proxy_handler(ngx_http_request_t *r) } -void ngx_http_proxy_check_broken_connection(ngx_event_t *wev) +void ngx_http_proxy_check_broken_connection(ngx_event_t *ev) { ngx_connection_t *c; ngx_http_request_t *r; ngx_http_proxy_ctx_t *p; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0, "http proxy check client"); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ev->log, 0, + "http proxy check client, write event:%d", ev->write); - c = wev->data; + c = ev->data; r = c->data; p = ngx_http_get_module_ctx(r, ngx_http_proxy_module); #if (HAVE_KQUEUE) - if (wev->kq_eof) { - wev->eof = 1; + if (ev->kq_eof) { + ev->eof = 1; - if (wev->kq_errno) { - wev->error = 1; + if (ev->kq_errno) { + ev->error = 1; } if (!p->cachable && p->upstream->peer.connection) { - ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno, + ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno, "kevent() reported that client have closed " "prematurely connection, " "so upstream connection is closed too"); @@ -403,7 +404,7 @@ void ngx_http_proxy_check_broken_connection(ngx_event_t *wev) return; } - ngx_log_error(NGX_LOG_INFO, wev->log, wev->kq_errno, + ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno, "kevent() reported that client have closed " "prematurely connection"); diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h index 210ca89f8..d204cac59 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -227,7 +227,7 @@ void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p); #endif -void ngx_http_proxy_check_broken_connection(ngx_event_t *wev); +void ngx_http_proxy_check_broken_connection(ngx_event_t *ev); void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev); void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p); diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c index 6bc11a25d..00a078009 100644 --- a/src/http/modules/proxy/ngx_http_proxy_upstream.c +++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c @@ -70,40 +70,36 @@ int ngx_http_proxy_request_upstream(ngx_http_proxy_ctx_t *p) } r->request_body = rb; - if (r->headers_in.content_length_n > 0) { - - if (!(tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)))) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } - - tf->file.fd = NGX_INVALID_FILE; - tf->file.log = r->connection->log; - tf->path = p->lcf->temp_path; - tf->pool = r->pool; - tf->warn = "a client request body is buffered to a temporary file"; - /* tf->persistent = 0; */ - - rb->buf_size = p->lcf->request_buffer_size; - rb->handler = ngx_http_proxy_init_upstream; - rb->data = p; - /* rb->bufs = NULL; */ - /* rb->buf = NULL; */ - /* rb->rest = 0; */ - - rb->temp_file = tf; - - rc = ngx_http_read_client_request_body(r); - - if (rc == NGX_AGAIN) { - return NGX_DONE; - } - - if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { - return rc; - } + if (r->headers_in.content_length_n <= 0) { + ngx_http_proxy_init_upstream(p); + return NGX_DONE; } - ngx_http_proxy_init_upstream(p); + if (!(tf = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t)))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + tf->file.fd = NGX_INVALID_FILE; + tf->file.log = r->connection->log; + tf->path = p->lcf->temp_path; + tf->pool = r->pool; + tf->warn = "a client request body is buffered to a temporary file"; + /* tf->persistent = 0; */ + + rb->buf_size = p->lcf->request_buffer_size; + rb->handler = ngx_http_proxy_init_upstream; + rb->data = p; + /* rb->bufs = NULL; */ + /* rb->buf = NULL; */ + /* rb->rest = 0; */ + + rb->temp_file = tf; + + rc = ngx_http_read_client_request_body(r); + + if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { + return rc; + } return NGX_DONE; } @@ -323,13 +319,15 @@ static void ngx_http_proxy_init_upstream(void *data) r = p->request; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http proxy set timer: %d", + "http proxy init upstream, client timer: %d", r->connection->read->timer_set); if (r->connection->read->timer_set) { ngx_del_timer(r->connection->read); } + r->connection->read->event_handler = ngx_http_proxy_check_broken_connection; + if ((ngx_event_flags & (NGX_USE_CLEAR_EVENT|NGX_HAVE_KQUEUE_EVENT)) && !r->connection->write->active) { diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 6562c8d52..86321b51b 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -39,6 +39,7 @@ static char *client_header_errors[] = { "client %s sent too long header line, URL: %s", "client %s sent HTTP/1.1 request without \"Host\" header, URL: %s", "client %s sent invalid \"Content-Length\" header, URL: %s" + "client %s sent POST method without \"Content-Length\" header, URL: %s" }; @@ -873,6 +874,10 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) } } + if (r->method == NGX_HTTP_POST && r->headers_in.content_length_n <= 0) { + return NGX_HTTP_PARSE_POST_WO_CL_HEADER; + } + if (r->headers_in.connection) { if (r->headers_in.connection->value.len == 5 && ngx_strcasecmp(r->headers_in.connection->value.data, "close") @@ -1222,10 +1227,17 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) wev = c->write; wev->event_handler = ngx_http_empty_handler; + + /* skip the tralling "\r\n" before the possible pipelined request */ + + while (h->pos < h->last && (*h->pos == CR || *h->pos == LF)) { + h->pos++; + } + if (h->pos < h->last) { /* - * Pipelined request. + * The pipelined request. * * We do not know here whether the pipelined request is complete * so if the large client headers are not enabled diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index 555d55593..a3161531f 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -30,6 +30,7 @@ #define NGX_HTTP_PARSE_TOO_LONG_HEADER 15 #define NGX_HTTP_PARSE_NO_HOST_HEADER 16 #define NGX_HTTP_PARSE_INVALID_CL_HEADER 17 +#define NGX_HTTP_PARSE_POST_WO_CL_HEADER 18 #define NGX_HTTP_OK 200 diff --git a/src/os/unix/ngx_aio.h b/src/os/unix/ngx_aio.h index a357ff524..0bbb7ec9b 100644 --- a/src/os/unix/ngx_aio.h +++ b/src/os/unix/ngx_aio.h @@ -5,9 +5,9 @@ #include -ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size); +ssize_t ngx_aio_read(ngx_connection_t *c, u_char *buf, size_t size); ssize_t ngx_aio_read_chain(ngx_connection_t *c, ngx_chain_t *cl); -ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size); +ssize_t ngx_aio_write(ngx_connection_t *c, u_char *buf, size_t size); ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in); diff --git a/src/os/unix/ngx_aio_read.c b/src/os/unix/ngx_aio_read.c index 84301886a..6c0c40084 100644 --- a/src/os/unix/ngx_aio_read.c +++ b/src/os/unix/ngx_aio_read.c @@ -17,7 +17,7 @@ * timeout, aio_cancel(), aio_error() */ -ssize_t ngx_aio_read(ngx_connection_t *c, char *buf, size_t size) +ssize_t ngx_aio_read(ngx_connection_t *c, u_char *buf, size_t size) { int n; ngx_event_t *rev; diff --git a/src/os/unix/ngx_aio_read_chain.c b/src/os/unix/ngx_aio_read_chain.c index 8fc8870dd..3a56e8613 100644 --- a/src/os/unix/ngx_aio_read_chain.c +++ b/src/os/unix/ngx_aio_read_chain.c @@ -8,7 +8,7 @@ ssize_t ngx_aio_read_chain(ngx_connection_t *c, ngx_chain_t *cl) { int n; - char *buf, *prev; + u_char *buf, *prev; size_t size, total; ngx_err_t err; diff --git a/src/os/unix/ngx_aio_write.c b/src/os/unix/ngx_aio_write.c index 113196165..319af1261 100644 --- a/src/os/unix/ngx_aio_write.c +++ b/src/os/unix/ngx_aio_write.c @@ -17,7 +17,7 @@ * timeout, aio_cancel(), aio_error() */ -ssize_t ngx_aio_write(ngx_connection_t *c, char *buf, size_t size) +ssize_t ngx_aio_write(ngx_connection_t *c, u_char *buf, size_t size) { int n; ngx_event_t *wev; diff --git a/src/os/unix/ngx_aio_write_chain.c b/src/os/unix/ngx_aio_write_chain.c index c8108f3e0..f5e125e4f 100644 --- a/src/os/unix/ngx_aio_write_chain.c +++ b/src/os/unix/ngx_aio_write_chain.c @@ -8,7 +8,7 @@ ngx_chain_t *ngx_aio_write_chain(ngx_connection_t *c, ngx_chain_t *in) { int n; - char *buf, *prev; + u_char *buf, *prev; off_t sent; size_t size; ngx_err_t err;