Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/ngx_connection.h1
-rw-r--r--src/http/ngx_http_event.c10
-rw-r--r--src/http/ngx_http_header_filter.c37
-rw-r--r--src/os/unix/ngx_freebsd_config.h6
-rw-r--r--src/os/unix/ngx_freebsd_init.c6
-rw-r--r--src/os/unix/ngx_freebsd_init.h2
-rw-r--r--src/os/unix/ngx_freebsd_sendfile_chain.c28
-rw-r--r--src/os/unix/ngx_linux_config.h19
-rw-r--r--src/os/unix/ngx_linux_init.c53
-rw-r--r--src/os/unix/ngx_socket.c46
-rw-r--r--src/os/unix/ngx_socket.h9
-rw-r--r--src/os/unix/ngx_solaris_config.h5
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_ */