diff options
-rw-r--r-- | src/core/ngx_connection.h | 1 | ||||
-rw-r--r-- | src/http/ngx_http_event.c | 10 | ||||
-rw-r--r-- | src/http/ngx_http_header_filter.c | 37 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_config.h | 6 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_init.c | 6 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_init.h | 2 | ||||
-rw-r--r-- | src/os/unix/ngx_freebsd_sendfile_chain.c | 28 | ||||
-rw-r--r-- | src/os/unix/ngx_linux_config.h | 19 | ||||
-rw-r--r-- | src/os/unix/ngx_linux_init.c | 53 | ||||
-rw-r--r-- | src/os/unix/ngx_socket.c | 46 | ||||
-rw-r--r-- | src/os/unix/ngx_socket.h | 9 | ||||
-rw-r--r-- | src/os/unix/ngx_solaris_config.h | 5 |
12 files changed, 181 insertions, 41 deletions
diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h index c75fd1f06..81b5987ca 100644 --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -46,6 +46,7 @@ struct ngx_connection_s { unsigned pipeline:1; unsigned unexpected_eof:1; unsigned tcp_nopush:1; + unsigned tcp_nopush_enabled:1; }; diff --git a/src/http/ngx_http_event.c b/src/http/ngx_http_event.c index b4a9ae97d..be6d3910a 100644 --- a/src/http/ngx_http_event.c +++ b/src/http/ngx_http_event.c @@ -1133,6 +1133,16 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) ctx->action = "keepalive"; + if (c->tcp_nopush) { + if (ngx_tcp_push(c->fd) == NGX_ERROR) { + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, + ngx_tcp_push_n " failed"); + ngx_http_close_connection(c); + return; + } + c->tcp_nopush = 0; + } + if ((ngx_event_flags & NGX_HAVE_AIO_EVENT) || blocked) { ngx_http_keepalive_handler(rev); } diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 8989f7c0a..0f7c95330 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -4,6 +4,12 @@ #include <ngx_http.h> #include <nginx.h> +/* STUB probably, needed for ngx_freebsd_tcp_nopush_flush */ +#ifdef __FreeBSD__ +#include <ngx_freebsd_init.h> +#endif + + static int ngx_http_header_filter_init(ngx_pool_t *pool); static int ngx_http_header_filter(ngx_http_request_t *r); @@ -94,6 +100,23 @@ static int ngx_http_header_filter(ngx_http_request_t *r) ngx_chain_t *ch; ngx_table_elt_t *header; +#ifdef __FreeBSD__ + + if (r->keepalive) { + if (ngx_freebsd_tcp_nopush_flush) { + r->connection->tcp_nopush_enabled = 1; + } + + } else { + r->connection->tcp_nopush_enabled = 1; + } + +#else + + r->connection->tcp_nopush_enabled = 1; + +#endif + if (r->http_version < NGX_HTTP_VERSION_10) { return NGX_OK; } @@ -219,12 +242,12 @@ static int ngx_http_header_filter(ngx_http_request_t *r) len += 28; } - if (r->keepalive == 0) { - /* "Connection: close\r\n" */ - len += 19; - } else { + if (r->keepalive) { /* "Connection: keep-alive\r\n" */ len += 24; + } else { + /* "Connection: close\r\n" */ + len += 19; } header = (ngx_table_elt_t *) r->headers_out.headers->elts; @@ -323,11 +346,11 @@ static int ngx_http_header_filter(ngx_http_request_t *r) h->last = ngx_cpymem(h->last, "Transfer-Encoding: chunked" CRLF, 28); } - if (r->keepalive == 0) { - h->last = ngx_cpymem(h->last, "Connection: close" CRLF, 19); + if (r->keepalive) { + h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, 24); } else { - h->last = ngx_cpymem(h->last, "Connection: keep-alive" CRLF, 24); + h->last = ngx_cpymem(h->last, "Connection: close" CRLF, 19); } for (i = 0; i < r->headers_out.headers->nelts; i++) { diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h index fa08f8f4f..7c229a417 100644 --- a/src/os/unix/ngx_freebsd_config.h +++ b/src/os/unix/ngx_freebsd_config.h @@ -13,6 +13,7 @@ #include <sys/uio.h> #include <sys/ioctl.h> #include <sys/resource.h> +#include <sys/sysctl.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> /* TCP_NOPUSH */ @@ -105,4 +106,9 @@ #endif +#ifndef HAVE_FIONBIO +#define HAVE_FIONBIO 1 +#endif + + #endif /* _NGX_FREEBSD_CONFIG_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c index e01f9b613..6eae456ed 100644 --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -56,7 +56,7 @@ int ngx_os_init(ngx_log_t *log) size_t size; ngx_err_t err; - size = 20; + size = sizeof(ngx_freebsd_kern_ostype); if (sysctlbyname("kern.ostype", ngx_freebsd_kern_ostype, &size, NULL, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, @@ -64,7 +64,7 @@ int ngx_os_init(ngx_log_t *log) return NGX_ERROR; } - size = 20; + size = sizeof(ngx_freebsd_kern_osrelease); if (sysctlbyname("kern.osrelease", ngx_freebsd_kern_osrelease, &size, NULL, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, @@ -76,7 +76,7 @@ int ngx_os_init(ngx_log_t *log) ngx_freebsd_kern_ostype, ngx_freebsd_kern_osrelease); - size = 4; + size = sizeof(int); if (sysctlbyname("kern.osreldate", &ngx_freebsd_kern_osreldate, &size, NULL, 0) == -1) { ngx_log_error(NGX_LOG_ALERT, log, errno, diff --git a/src/os/unix/ngx_freebsd_init.h b/src/os/unix/ngx_freebsd_init.h index 967951d8d..700fca409 100644 --- a/src/os/unix/ngx_freebsd_init.h +++ b/src/os/unix/ngx_freebsd_init.h @@ -4,7 +4,6 @@ #include <ngx_config.h> #include <ngx_core.h> -#include <sys/sysctl.h> /* STUB */ @@ -22,6 +21,7 @@ extern int ngx_freebsd_net_inet_tcp_sendspace; extern int ngx_freebsd_sendfile_nbytes_bug; extern int ngx_freebsd_tcp_nopush_flush; extern int ngx_freebsd_kern_ipc_zero_copy_send; +extern int ngx_freebsd_tcp_nopush_flush; #endif /* _NGX_FREEBSD_INIT_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c index cd21ed904..a888c3613 100644 --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -105,17 +105,15 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) if (file) { - if (!c->tcp_nopush && ngx_freebsd_tcp_nopush_flush) { + if (!c->tcp_nopush && c->tcp_nopush_enabled) { c->tcp_nopush = 1; tcp_nopush = 1; - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH, - (const void *) &tcp_nopush, - sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, - "setsockopt(TCP_NOPUSH) failed"); + if (ngx_tcp_nopush(c->fd) == NGX_ERROR) { + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, + ngx_tcp_nopush_n " failed"); return NGX_CHAIN_ERROR; } +ngx_log_debug(c->log, "NOPUSH"); } hdtr.headers = (struct iovec *) header.elts; @@ -222,21 +220,5 @@ ngx_chain_t *ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in) } while ((tail && tail == ce) || eintr); - /* STUB: should be in app code, no need to clear TCP_NOPUSH - if the conneciton close()d or shutdown()ed */ - - if (c->tcp_nopush) { - c->tcp_nopush = 0; - tcp_nopush = 0; - if (setsockopt(c->fd, IPPROTO_TCP, TCP_NOPUSH, - (const void *) &tcp_nopush, - sizeof(int)) == -1) - { - ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, - "setsockopt(!TCP_NOPUSH) failed"); - return NGX_CHAIN_ERROR; - } - } - return ce; } diff --git a/src/os/unix/ngx_linux_config.h b/src/os/unix/ngx_linux_config.h index cfd941342..b90792c96 100644 --- a/src/os/unix/ngx_linux_config.h +++ b/src/os/unix/ngx_linux_config.h @@ -2,10 +2,14 @@ #define _NGX_LINUX_CONFIG_H_INCLUDED_ -#define _XOPEN_SOURCE 500 +#define _FILE_OFFSET_BITS 64 +#define _LARGEFILE_SOURCE +#define _XOPEN_SOURCE 500 /* pread, pwrite */ #include <unistd.h> +#undef _XOPEN_SOURCE 500 + #include <stddef.h> /* offsetof */ #include <stdlib.h> #include <stdio.h> @@ -13,7 +17,7 @@ #include <signal.h> #include <time.h> -#define __USE_BSD +#define __USE_BSD /* bzero */ #include <string.h> #undef __USE_BSD @@ -23,14 +27,16 @@ #include <sys/uio.h> #include <sys/ioctl.h> #include <sys/resource.h> +#include <sys/sysctl.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> -typedef unsigned int u_int; -typedef unsigned char u_char; +typedef unsigned int u_int; +typedef unsigned short u_short; +typedef unsigned char u_char; #ifndef HAVE_SELECT @@ -56,4 +62,9 @@ typedef unsigned char u_char; #endif +#ifndef HAVE_FIONBIO +#define HAVE_FIONBIO 1 +#endif + + #endif /* _NGX_LINUX_CONFIG_H_INCLUDED_ */ diff --git a/src/os/unix/ngx_linux_init.c b/src/os/unix/ngx_linux_init.c new file mode 100644 index 000000000..64bdce4eb --- /dev/null +++ b/src/os/unix/ngx_linux_init.c @@ -0,0 +1,53 @@ + +#include <ngx_config.h> +#include <ngx_core.h> + + +/* STUB */ +ssize_t ngx_unix_recv(ngx_connection_t *c, char *buf, size_t size); +ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in); +int ngx_posix_init(ngx_log_t *log); + + +char ngx_linux_kern_ostype[50]; +char ngx_linux_kern_osrelease[20]; + + +ngx_os_io_t ngx_os_io = { + ngx_unix_recv, + NULL, + NULL, + ngx_writev_chain, + NGX_HAVE_ZEROCOPY +}; + + +int ngx_os_init(ngx_log_t *log) +{ + int name[2], len; + + name[0] = CTL_KERN; + name[1] = KERN_OSTYPE; + len = sizeof(ngx_linux_kern_ostype); + if (sysctl(name, sizeof(name), ngx_linux_kern_ostype, &len, NULL, 0) + == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, "sysctl(KERN_OSTYPE) failed"); + return NGX_ERROR; + } + + name[0] = CTL_KERN; + name[1] = KERN_OSRELEASE; + len = sizeof(ngx_linux_kern_osrelease); + if (sysctl(name, sizeof(name), ngx_linux_kern_osrelease, &len, NULL, 0) + == -1) { + ngx_log_error(NGX_LOG_ALERT, log, errno, + "sysctl(KERN_OSRELEASE) failed"); + return NGX_ERROR; + } + + ngx_log_error(NGX_LOG_INFO, log, 0, "OS: %s %s", + ngx_linux_kern_ostype, ngx_linux_kern_osrelease); + + + return ngx_posix_init(log); +} diff --git a/src/os/unix/ngx_socket.c b/src/os/unix/ngx_socket.c index 0746fa0ec..941fc8cd1 100644 --- a/src/os/unix/ngx_socket.c +++ b/src/os/unix/ngx_socket.c @@ -1,5 +1,6 @@ -#include <ngx_socket.h> +#include <ngx_config.h> +#include <ngx_core.h> /* @@ -10,7 +11,8 @@ ioctl() and fcntl() are syscalls on FreeBSD, Solaris 7/8 and Linux */ -#if 1 + +#if (HAVE_FIONBIO) int ngx_nonblocking(ngx_socket_t s) { @@ -19,6 +21,7 @@ int ngx_nonblocking(ngx_socket_t s) return ioctl(s, FIONBIO, &nb); } + int ngx_blocking(ngx_socket_t s) { unsigned long nb = 0; @@ -27,3 +30,42 @@ int ngx_blocking(ngx_socket_t s) } #endif + + +#ifdef __FreeBSD__ + +int ngx_tcp_nopush(ngx_socket_t s) +{ + int tcp_nopush; + + tcp_nopush = 1; + + return setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, + (const void *) &tcp_nopush, sizeof(int)); +} + + +int ngx_tcp_push(ngx_socket_t s) +{ + int tcp_nopush; + + tcp_nopush = 0; + + return setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, + (const void *) &tcp_nopush, sizeof(int)); +} + +#else + + +int ngx_tcp_nopush(ngx_socket_t s) +{ + return NGX_OK; +} + +int ngx_tcp_push(ngx_socket_t s) +{ + return NGX_OK; +} + +#endif diff --git a/src/os/unix/ngx_socket.h b/src/os/unix/ngx_socket.h index cee1f4aeb..2a412d377 100644 --- a/src/os/unix/ngx_socket.h +++ b/src/os/unix/ngx_socket.h @@ -13,7 +13,7 @@ typedef int ngx_socket_t; #define ngx_socket_n "socket()" -#if 1 +#if (HAVE_FIONBIO) int ngx_nonblocking(ngx_socket_t s); int ngx_blocking(ngx_socket_t s); @@ -28,6 +28,13 @@ int ngx_blocking(ngx_socket_t s); #endif +int ngx_tcp_nopush(ngx_socket_t s); +#define ngx_tcp_nopush_n "setsockopt(TCP_NOPUSH)" + +int ngx_tcp_push(ngx_socket_t s); +#define ngx_tcp_push_n "setsockopt(!TCP_NOPUSH)" + + #define ngx_shutdown_socket shutdown #define ngx_shutdown_socket_n "shutdown()" diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h index 197750105..31e17e1c1 100644 --- a/src/os/unix/ngx_solaris_config.h +++ b/src/os/unix/ngx_solaris_config.h @@ -57,4 +57,9 @@ typedef uint32_t u_int32_t; #endif +#ifndef HAVE_FIONBIO +#define HAVE_FIONBIO 1 +#endif + + #endif /* _NGX_SOLARIS_CONFIG_H_INCLUDED_ */ |