nginx-0.1.2-RELEASE import
*) Feature: the --user=USER, --group=GROUP, and --with-ld-opt=OPTIONS
options in configure.
*) Feature: the server_name directive supports *.domain.tld.
*) Bugfix: the portability improvements.
*) Bugfix: if configuration file was set in command line, the
reconfiguration was impossible; the bug had appeared in 0.1.1.
*) Bugfix: proxy module may get caught in an endless loop when sendfile
is not used.
*) Bugfix: with sendfile the response was not recoded according to the
charset module directives; the bug had appeared in 0.1.1.
*) Bugfix: very seldom bug in the kqueue processing.
*) Bugfix: the gzip module compressed the proxied responses that was
already compressed.
diff --git a/src/http/modules/ngx_http_charset_filter.c b/src/http/modules/ngx_http_charset_filter.c
index d22a86b..f2e85e5 100644
--- a/src/http/modules/ngx_http_charset_filter.c
+++ b/src/http/modules/ngx_http_charset_filter.c
@@ -12,7 +12,7 @@
typedef struct {
char **tables;
ngx_str_t name;
- unsigned server;
+ ngx_uint_t server; /* unsigned server:1; */
} ngx_http_charset_t;
@@ -45,7 +45,7 @@
} ngx_http_charset_ctx_t;
-static void ngx_charset_recode(ngx_buf_t *b, char *table);
+static ngx_uint_t ngx_charset_recode(ngx_buf_t *b, char *table);
static char *ngx_charset_map_block(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -232,14 +232,31 @@
}
-static void ngx_charset_recode(ngx_buf_t *b, char *table)
+static ngx_uint_t ngx_charset_recode(ngx_buf_t *b, char *table)
{
- u_char *p, c;
+ u_char *p;
+ ngx_uint_t change;
+
+ change = 0;
for (p = b->pos; p < b->last; p++) {
- c = *p;
- *p = table[c];
+ if (*p != table[*p]) {
+ change = 1;
+ break;
+ }
}
+
+ if (change) {
+
+ while (p < b->last) {
+ *p = table[*p];
+ p++;
+ }
+
+ b->in_file = 0;
+ }
+
+ return change;
}
@@ -419,7 +436,9 @@
return NGX_ERROR;
}
+ c->tables = NULL;
c->name = *name;
+ c->server = 0;
return i;
}
diff --git a/src/http/modules/ngx_http_chunked_filter.c b/src/http/modules/ngx_http_chunked_filter.c
index 2112461..7881248 100644
--- a/src/http/modules/ngx_http_chunked_filter.c
+++ b/src/http/modules/ngx_http_chunked_filter.c
@@ -63,7 +63,7 @@
ngx_chain_t *in)
{
u_char *chunk;
- size_t size, len;
+ size_t size;
ngx_buf_t *b;
ngx_chain_t out, tail, *cl, *tl, **ll;
@@ -98,6 +98,20 @@
}
if (size) {
+ if (!(b = ngx_calloc_buf(r->pool))) {
+ return NGX_ERROR;
+ }
+
+ if (!(chunk = ngx_palloc(r->pool, 11))) {
+ return NGX_ERROR;
+ }
+
+ b->temporary = 1;
+ b->pos = chunk;
+ b->last = ngx_sprintf(chunk, "%uxS" CRLF, size);
+
+ out.buf = b;
+#if 0
ngx_test_null(chunk, ngx_palloc(r->pool, 11), NGX_ERROR);
len = ngx_snprintf((char *) chunk, 11, SIZE_T_X_FMT CRLF, size);
@@ -107,6 +121,7 @@
b->last = chunk + len;
out.buf = b;
+#endif
}
if (cl->buf->last_buf) {
diff --git a/src/http/modules/ngx_http_gzip_filter.c b/src/http/modules/ngx_http_gzip_filter.c
index 4089ffb..bb3a1f0 100644
--- a/src/http/modules/ngx_http_gzip_filter.c
+++ b/src/http/modules/ngx_http_gzip_filter.c
@@ -837,26 +837,30 @@
return buf + 1;
}
-#if 0
- return buf + ngx_snprintf((char *) buf, NGX_INT32_LEN + 4, "%.2f",
- (float) ctx->zin / ctx->zout);
-#endif
-
/* we prefer do not use the FPU */
zint = (ngx_uint_t) (ctx->zin / ctx->zout);
zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100);
- if ((ctx->zin * 1000 / ctx->zout) %10 > 4) {
- if (++zfrac > 99) {
+ if ((ctx->zin * 1000 / ctx->zout) % 10 > 4) {
+
+ /* the rounding, e.g., 2.125 to 2.13 */
+
+ zfrac++;
+
+ if (zfrac > 99) {
zint++;
zfrac = 0;
}
}
+ return ngx_sprintf(buf, "%ui.%02ui", zint, zfrac);
+
+#if 0
return buf + ngx_snprintf((char *) buf, NGX_INT32_LEN + 4,
"%" NGX_UINT_T_FMT ".%02" NGX_UINT_T_FMT,
zint, zfrac);
+#endif
}
diff --git a/src/http/modules/ngx_http_headers_filter.c b/src/http/modules/ngx_http_headers_filter.c
index f7fe52c..faf8192 100644
--- a/src/http/modules/ngx_http_headers_filter.c
+++ b/src/http/modules/ngx_http_headers_filter.c
@@ -134,10 +134,16 @@
return NGX_ERROR;
}
+ cc->value.len = ngx_sprintf(cc->value.data, "max-age=%T",
+ conf->expires)
+ - cc->value.data;
+
+#if 0
cc->value.len = ngx_snprintf((char *) cc->value.data,
sizeof("max-age=") + TIME_T_LEN,
"max-age=" TIME_T_FMT,
conf->expires);
+#endif
}
}
}
diff --git a/src/http/modules/ngx_http_range_filter.c b/src/http/modules/ngx_http_range_filter.c
index a08e25f..082fd3c 100644
--- a/src/http/modules/ngx_http_range_filter.c
+++ b/src/http/modules/ngx_http_range_filter.c
@@ -264,9 +264,14 @@
}
r->headers_out.content_range->value.len =
+ ngx_sprintf(r->headers_out.content_range->value.data,
+ "bytes */%O", r->headers_out.content_length_n)
+ - r->headers_out.content_range->value.data;
+#if 0
ngx_snprintf((char *) r->headers_out.content_range->value.data,
8 + 20 + 1, "bytes */" OFF_T_FMT,
r->headers_out.content_length_n);
+#endif
r->headers_out.content_length_n = -1;
if (r->headers_out.content_length) {
@@ -297,12 +302,20 @@
/* "Content-Range: bytes SSSS-EEEE/TTTT" header */
r->headers_out.content_range->value.len =
+ ngx_sprintf(r->headers_out.content_range->value.data,
+ "bytes %O-%O/%O",
+ range->start, range->end - 1,
+ r->headers_out.content_length_n)
+ - r->headers_out.content_range->value.data;
+
+#if 0
ngx_snprintf((char *)
r->headers_out.content_range->value.data,
6 + 20 + 1 + 20 + 1 + 20 + 1,
"bytes " OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT,
range->start, range->end - 1,
r->headers_out.content_length_n);
+#endif
r->headers_out.content_length_n = range->end - range->start;
@@ -343,6 +356,15 @@
if (r->headers_out.charset.len) {
ctx->boundary_header.len =
+ ngx_sprintf(ctx->boundary_header.data,
+ CRLF "--%010ui" CRLF
+ "Content-Type: %s; charset=%s" CRLF
+ "Content-Range: bytes ",
+ boundary,
+ r->headers_out.content_type->value.data,
+ r->headers_out.charset.data)
+ - ctx->boundary_header.data;
+#if 0
ngx_snprintf((char *) ctx->boundary_header.data, len,
CRLF "--%010" NGX_UINT_T_FMT CRLF
"Content-Type: %s; charset=%s" CRLF
@@ -350,17 +372,29 @@
boundary,
r->headers_out.content_type->value.data,
r->headers_out.charset.data);
+#endif
r->headers_out.charset.len = 0;
} else {
ctx->boundary_header.len =
+ ngx_sprintf(ctx->boundary_header.data,
+ CRLF "--%010ui" CRLF
+ "Content-Type: %s" CRLF
+ "Content-Range: bytes ",
+ boundary,
+ r->headers_out.content_type->value.data)
+ - ctx->boundary_header.data;
+
+#if 0
ngx_snprintf((char *) ctx->boundary_header.data, len,
CRLF "--%010" NGX_UINT_T_FMT CRLF
"Content-Type: %s" CRLF
"Content-Range: bytes ",
boundary,
r->headers_out.content_type->value.data);
+
+#endif
}
ngx_test_null(r->headers_out.content_type->value.data,
@@ -370,12 +404,18 @@
/* "Content-Type: multipart/byteranges; boundary=0123456789" */
r->headers_out.content_type->value.len =
+ ngx_sprintf(r->headers_out.content_type->value.data,
+ "multipart/byteranges; boundary=%010ui",
+ boundary)
+ - r->headers_out.content_type->value.data;
+#if 0
ngx_snprintf((char *)
r->headers_out.content_type->value.data,
31 + 10 + 1,
"multipart/byteranges; boundary=%010"
NGX_UINT_T_FMT,
boundary);
+#endif
/* the size of the last boundary CRLF "--0123456789--" CRLF */
len = 4 + 10 + 4;
@@ -389,11 +429,18 @@
/* the size of the range: "SSSS-EEEE/TTTT" CRLF CRLF */
range[i].content_range.len =
+ ngx_sprintf(range[i].content_range.data,
+ "%O-%O/%O" CRLF CRLF,
+ range[i].start, range[i].end - 1,
+ r->headers_out.content_length_n)
+ - range[i].content_range.data;
+#if 0
ngx_snprintf((char *) range[i].content_range.data,
20 + 1 + 20 + 1 + 20 + 5,
OFF_T_FMT "-" OFF_T_FMT "/" OFF_T_FMT CRLF CRLF,
range[i].start, range[i].end - 1,
r->headers_out.content_length_n);
+#endif
len += ctx->boundary_header.len + range[i].content_range.len
+ (size_t) (range[i].end - range[i].start);
diff --git a/src/http/modules/ngx_http_status_handler.c b/src/http/modules/ngx_http_status_handler.c
index 6206ac3..357afff 100644
--- a/src/http/modules/ngx_http_status_handler.c
+++ b/src/http/modules/ngx_http_status_handler.c
@@ -159,6 +159,9 @@
+ 1 + (r->server_name ? cmcf->max_server_name_len : 1)
+ 2; /* "\r\n" */
+ /* BUG: cmcf->max_server_name_len and "*.domain.tld" */
+
+
if (r->request_line.len) {
len += 1 + 1 + r->request_line.len + 1;
}
diff --git a/src/http/modules/ngx_http_userid_filter.c b/src/http/modules/ngx_http_userid_filter.c
index 5f8e452..bafdea8 100644
--- a/src/http/modules/ngx_http_userid_filter.c
+++ b/src/http/modules/ngx_http_userid_filter.c
@@ -367,7 +367,7 @@
} else if (conf->expires) {
p = ngx_cpymem(p, expires, sizeof("; expires=") - 1);
- p += ngx_http_cookie_time(p, ngx_time() + conf->expires);
+ p = ngx_http_cookie_time(p, ngx_time() + conf->expires);
}
if (conf->domain.len > 1) {
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c
index f0794f3..5d61167 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.c
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.c
@@ -289,6 +289,8 @@
offsetof(ngx_http_proxy_headers_in_t, content_type) },
{ ngx_string("Content-Length"),
offsetof(ngx_http_proxy_headers_in_t, content_length) },
+ { ngx_string("Content-Encoding"),
+ offsetof(ngx_http_proxy_headers_in_t, content_encoding) },
{ ngx_string("Last-Modified"),
offsetof(ngx_http_proxy_headers_in_t, last_modified) },
{ ngx_string("Location"),
@@ -400,7 +402,7 @@
#if (HAVE_KQUEUE)
- if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
if (!ev->pending_eof) {
return;
@@ -1310,10 +1312,10 @@
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
{
-#if __FreeBSD__
-
ssize_t *np = data;
+#if (NGX_FREEBSD)
+
if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"proxy_send_lowat\" must be less than %d "
@@ -1323,15 +1325,12 @@
return NGX_CONF_ERROR;
}
+#elif !(HAVE_SO_SNDLOWAT)
-#else
-
-#if 0
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"\"proxy_send_lowat\" is not supported, ignored");
*np = 0;
-#endif
#endif
diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h
index 728259c..3e721ba 100644
--- a/src/http/modules/proxy/ngx_http_proxy_handler.h
+++ b/src/http/modules/proxy/ngx_http_proxy_handler.h
@@ -130,6 +130,7 @@
ngx_table_elt_t *connection;
ngx_table_elt_t *content_type;
ngx_table_elt_t *content_length;
+ ngx_table_elt_t *content_encoding;
ngx_table_elt_t *last_modified;
ngx_table_elt_t *location;
ngx_table_elt_t *accept_ranges;
diff --git a/src/http/modules/proxy/ngx_http_proxy_header.c b/src/http/modules/proxy/ngx_http_proxy_header.c
index 07722fc..cd5deeb 100644
--- a/src/http/modules/proxy/ngx_http_proxy_header.c
+++ b/src/http/modules/proxy/ngx_http_proxy_header.c
@@ -113,6 +113,11 @@
continue;
}
+ if (&h[i] == headers_in->content_encoding) {
+ r->headers_out.content_encoding = ho;
+ continue;
+ }
+
if (&h[i] == headers_in->last_modified) {
r->headers_out.last_modified = ho;
/* TODO: update r->headers_out.last_modified_time */
diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c
index be5d69a..88479da 100644
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -692,12 +692,14 @@
/* rc == NGX_OK */
-#if 1 /* test only, see below about "post aio operation" */
+#if 0 /* test only, see below about "post aio operation" */
if (c->read->ready) {
/* post aio operation */
ngx_http_proxy_process_upstream_status_line(c->read);
+#if 0
return;
+#endif
}
#endif
@@ -718,7 +720,7 @@
#if (HAVE_KQUEUE)
- if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)
+ if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT)
&& !p->request_sent
&& c->write->pending_eof)
{
@@ -776,7 +778,7 @@
ngx_add_timer(c->read, p->lcf->read_timeout);
-#if 0
+#if 1
if (c->read->ready) {
/* post aio operation */
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index a37ffc6..90bbbe2 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -11,6 +11,14 @@
static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
+ ngx_http_in_port_t *in_port,
+ ngx_http_listen_t *lscf,
+ ngx_http_core_srv_conf_t *cscf);
+static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
+ ngx_http_in_addr_t *in_addr,
+ ngx_http_core_srv_conf_t *cscf);
+
static char *ngx_http_merge_locations(ngx_conf_t *cf,
ngx_array_t *locations,
void **loc_conf,
@@ -79,6 +87,11 @@
ngx_iocp_conf_t *iocpcf;
#endif
+#if (NGX_SUPPRESS_WARN)
+ /* MSVC thinks 'in_ports' may be used without having been initialized */
+ ngx_memzero(&in_ports, sizeof(ngx_array_t));
+#endif
+
/* the main http context */
ngx_test_null(ctx,
ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)),
@@ -274,18 +287,23 @@
/*
- * create the lists of the ports, the addresses and the server names
- * to allow quickly find the server core module configuration at run-time
+ * create the lists of ports, addresses and server names
+ * to quickly find the server core module configuration at run-time
*/
- ngx_init_array(in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t),
- NGX_CONF_ERROR);
+ if (ngx_array_init(&in_ports, cf->pool, 10, sizeof(ngx_http_in_port_t))
+ == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
+ }
/* "server" directives */
+
cscfp = cmcf->servers.elts;
for (s = 0; s < cmcf->servers.nelts; s++) {
/* "listen" directives */
+
lscf = cscfp[s]->listen.elts;
for (l = 0; l < cscfp[s]->listen.nelts; l++) {
@@ -308,38 +326,26 @@
if (lscf[l].addr == in_addr[a].addr) {
- /* the address is already bound to this port */
+ /* the address is already in the address list */
- /* "server_name" directives */
- s_name = cscfp[s]->server_names.elts;
- for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
-
- /*
- * add the server name and server core module
- * configuration to the address:port
- */
-
- /* TODO: duplicate names can be checked here */
-
- ngx_test_null(name,
- ngx_push_array(&in_addr[a].names),
- NGX_CONF_ERROR);
-
- name->name = s_name[n].name;
- name->core_srv_conf = s_name[n].core_srv_conf;
+ if (ngx_http_add_names(cf, &in_addr[a], cscfp[s])
+ == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
}
/*
- * check duplicate "default" server that
- * serves this address:port
+ * check the duplicate "default" server
+ * for this address:port
*/
if (lscf[l].default_server) {
+
if (in_addr[a].default_server) {
ngx_log_error(NGX_LOG_ERR, cf->log, 0,
- "duplicate default server in %s:%d",
- lscf[l].file_name.data,
- lscf[l].line);
+ "the duplicate default server in %s:%d",
+ lscf[l].file_name.data,
+ lscf[l].line);
return NGX_CONF_ERROR;
}
@@ -354,31 +360,31 @@
} else if (in_addr[a].addr == INADDR_ANY) {
- /*
- * "*:port" must be the last resort so move it
- * to the end of the address list and add
- * the new address at its place
- */
+ /* the INADDR_ANY is always the last address */
- ngx_test_null(inaddr,
- ngx_push_array(&in_port[p].addrs),
- NGX_CONF_ERROR);
+ if (!(inaddr = ngx_array_push(&in_port[p].addrs))) {
+ return NGX_CONF_ERROR;
+ }
+
+ /*
+ * the INADDR_ANY must be the last resort
+ * so we move it to the end of the address list
+ * and put the new address in its place
+ */
ngx_memcpy(inaddr, &in_addr[a],
sizeof(ngx_http_in_addr_t));
in_addr[a].addr = lscf[l].addr;
+ in_addr[a].names.elts = NULL;
in_addr[a].default_server = lscf[l].default_server;
in_addr[a].core_srv_conf = cscfp[s];
- /*
- * create the empty list of the server names that
- * can be served on this address:port
- */
-
- ngx_init_array(inaddr->names, cf->pool, 10,
- sizeof(ngx_http_server_name_t),
- NGX_CONF_ERROR);
+ if (ngx_http_add_names(cf, &in_addr[a], cscfp[s])
+ == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
+ }
addr_found = 1;
@@ -393,22 +399,11 @@
* bound to this port
*/
- ngx_test_null(inaddr,
- ngx_push_array(&in_port[p].addrs),
- NGX_CONF_ERROR);
-
- inaddr->addr = lscf[l].addr;
- inaddr->default_server = lscf[l].default_server;
- inaddr->core_srv_conf = cscfp[s];
-
- /*
- * create the empty list of the server names that
- * can be served on this address:port
- */
-
- ngx_init_array(inaddr->names, cf->pool, 10,
- sizeof(ngx_http_server_name_t),
- NGX_CONF_ERROR);
+ if (ngx_http_add_address(cf, &in_port[p], &lscf[l],
+ cscfp[s]) == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
+ }
}
}
}
@@ -417,54 +412,42 @@
/* add the port to the in_port list */
- ngx_test_null(in_port,
- ngx_push_array(&in_ports),
- NGX_CONF_ERROR);
+ if (!(in_port = ngx_array_push(&in_ports))) {
+ return NGX_CONF_ERROR;
+ }
in_port->port = lscf[l].port;
+ in_port->addrs.elts = NULL;
- ngx_test_null(in_port->port_text.data, ngx_palloc(cf->pool, 7),
- NGX_CONF_ERROR);
- in_port->port_text.len = ngx_snprintf((char *)
- in_port->port_text.data,
- 7, ":%d",
- in_port->port);
+ if (!(in_port->port_text.data = ngx_palloc(cf->pool, 7))) {
+ return NGX_CONF_ERROR;
+ }
- /* create list of the addresses that bound to this port ... */
+ in_port->port_text.len = ngx_sprintf(in_port->port_text.data,
+ ":%d", in_port->port)
+ - in_port->port_text.data;
- ngx_init_array(in_port->addrs, cf->pool, 10,
- sizeof(ngx_http_in_addr_t),
- NGX_CONF_ERROR);
-
- ngx_test_null(inaddr, ngx_push_array(&in_port->addrs),
- NGX_CONF_ERROR);
-
- /* ... and add the address to this list */
-
- inaddr->addr = lscf[l].addr;
- inaddr->default_server = lscf[l].default_server;
- inaddr->core_srv_conf = cscfp[s];
-
- /*
- * create the empty list of the server names that
- * can be served on this address:port
- */
-
- ngx_init_array(inaddr->names, cf->pool, 10,
- sizeof(ngx_http_server_name_t),
- NGX_CONF_ERROR);
+ if (ngx_http_add_address(cf, in_port, &lscf[l], cscfp[s])
+ == NGX_ERROR)
+ {
+ return NGX_CONF_ERROR;
+ }
}
}
}
- /* optimize the lists of the ports, the addresses and the server names */
+
+ /* optimize the lists of ports, addresses and server names */
/* AF_INET only */
in_port = in_ports.elts;
for (p = 0; p < in_ports.nelts; p++) {
- /* check whether the all server names point to the same server */
+ /*
+ * check whether all name-based servers have the same configuraiton
+ * as the default server, or some servers restrict the host names
+ */
in_addr = in_port[p].addrs.elts;
for (a = 0; a < in_port[p].addrs.nelts; a++) {
@@ -473,15 +456,19 @@
name = in_addr[a].names.elts;
for (n = 0; n < in_addr[a].names.nelts; n++) {
- if (in_addr[a].core_srv_conf != name[n].core_srv_conf) {
+ if (in_addr[a].core_srv_conf != name[n].core_srv_conf
+ || name[n].core_srv_conf->restrict_host_names
+ != NGX_HTTP_RESTRICT_HOST_OFF)
+ {
virtual_names = 1;
break;
}
}
/*
- * if the all server names point to the same server
- * then we do not need to check them at run-time
+ * if all name-based servers have the same configuration
+ * as the default server, and no servers restrict the host names
+ * then we do not need to check them at run-time at all
*/
if (!virtual_names) {
@@ -588,30 +575,117 @@
}
#if (NGX_DEBUG)
+ {
+ u_char address[20];
+ ngx_uint_t p, a, n;
+
in_port = in_ports.elts;
for (p = 0; p < in_ports.nelts; p++) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
"port: %d %08x", in_port[p].port, &in_port[p]);
in_addr = in_port[p].addrs.elts;
for (a = 0; a < in_port[p].addrs.nelts; a++) {
- u_char ip[20];
- ngx_inet_ntop(AF_INET, &in_addr[a].addr, ip, 20);
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "%s %08x", ip, in_addr[a].core_srv_conf);
+ ngx_inet_ntop(AF_INET, &in_addr[a].addr, address, 20);
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, cf->log, 0,
+ "%s:%d %08x",
+ address, in_port[p].port, in_addr[a].core_srv_conf);
s_name = in_addr[a].names.elts;
for (n = 0; n < in_addr[a].names.nelts; n++) {
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0,
- "%s %08x", s_name[n].name.data,
+ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, cf->log, 0,
+ "%s:%d %s %08x",
+ address, in_port[p].port, s_name[n].name.data,
s_name[n].core_srv_conf);
}
}
}
+ }
#endif
return NGX_CONF_OK;
}
+/*
+ * add the server address, the server names and the server core module
+ * configurations to the port (in_port)
+ */
+
+static ngx_int_t ngx_http_add_address(ngx_conf_t *cf,
+ ngx_http_in_port_t *in_port,
+ ngx_http_listen_t *lscf,
+ ngx_http_core_srv_conf_t *cscf)
+{
+ ngx_http_in_addr_t *in_addr;
+
+ if (in_port->addrs.elts == NULL) {
+ if (ngx_array_init(&in_port->addrs, cf->pool, 10,
+ sizeof(ngx_http_in_addr_t)) == NGX_ERROR)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ if (!(in_addr = ngx_array_push(&in_port->addrs))) {
+ return NGX_ERROR;
+ }
+
+ in_addr->addr = lscf->addr;
+ in_addr->names.elts = NULL;
+ in_addr->default_server = lscf->default_server;
+ in_addr->core_srv_conf = cscf;
+
+#if (NGX_DEBUG)
+ {
+ u_char text[20];
+ ngx_inet_ntop(AF_INET, &in_addr->addr, text, 20);
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cf->log, 0, "address: %s:%d",
+ text, in_port->port);
+ }
+#endif
+
+ return ngx_http_add_names(cf, in_addr, cscf);
+}
+
+
+/*
+ * add the server names and the server core module
+ * configurations to the address:port (in_addr)
+ */
+
+static ngx_int_t ngx_http_add_names(ngx_conf_t *cf,
+ ngx_http_in_addr_t *in_addr,
+ ngx_http_core_srv_conf_t *cscf)
+{
+ ngx_uint_t i;
+ ngx_http_server_name_t *server_names, *name;
+
+ if (in_addr->names.elts == NULL) {
+ if (ngx_array_init(&in_addr->names, cf->pool, 10,
+ sizeof(ngx_http_server_name_t)) == NGX_ERROR)
+ {
+ return NGX_ERROR;
+ }
+ }
+
+ server_names = cscf->server_names.elts;
+ for (i = 0; i < cscf->server_names.nelts; i++) {
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0,
+ "name: %s", server_names[i].name.data);
+
+ /* TODO: duplicate names can be checked here */
+
+ if (!(name = ngx_array_push(&in_addr->names))) {
+ return NGX_ERROR;
+ }
+
+ *name = server_names[i];
+ }
+
+ return NGX_OK;
+}
+
+
static char *ngx_http_merge_locations(ngx_conf_t *cf,
ngx_array_t *locations,
void **loc_conf,
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 58021e8..8544e25 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -36,7 +36,7 @@
void *dummy);
static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_set_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
-static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static char *ngx_http_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_set_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -126,9 +126,9 @@
#if 0
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
#else
- NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
#endif
- ngx_set_listen,
+ ngx_http_listen,
NGX_HTTP_SRV_CONF_OFFSET,
0,
NULL },
@@ -576,7 +576,7 @@
clcfp = locations->elts;
for (i = 0; i < locations->nelts; i++) {
-#if (HAVE_PCRE)
+#if (NGX_PCRE)
if (clcfp[i]->regex) {
break;
}
@@ -638,7 +638,7 @@
}
}
-#if (HAVE_PCRE)
+#if (NGX_PCRE)
/* regex matches */
@@ -673,7 +673,7 @@
return NGX_HTTP_LOCATION_REGEX;
}
-#endif /* HAVE_PCRE */
+#endif /* NGX_PCRE */
return NGX_OK;
}
@@ -991,7 +991,7 @@
first = *(ngx_http_core_loc_conf_t **) one;
second = *(ngx_http_core_loc_conf_t **) two;
-#if (HAVE_PCRE)
+#if (NGX_PCRE)
if (first->regex && !second->regex) {
/* shift the regex matches to the end */
@@ -1026,7 +1026,7 @@
ngx_http_conf_ctx_t *ctx, *pctx;
ngx_http_core_srv_conf_t *cscf;
ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp;
-#if (HAVE_PCRE)
+#if (NGX_PCRE)
ngx_str_t err;
u_char errstr[NGX_MAX_CONF_ERRSTR];
#endif
@@ -1076,7 +1076,7 @@
&& value[1].data[0] == '~'
&& value[1].data[1] == '*'))
{
-#if (HAVE_PCRE)
+#if (NGX_PCRE)
err.len = NGX_MAX_CONF_ERRSTR;
err.data = errstr;
@@ -1129,7 +1129,7 @@
return NGX_CONF_ERROR;
}
-#if (HAVE_PCRE)
+#if (NGX_PCRE)
if (clcf->regex == NULL
&& ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len)
!= 0)
@@ -1323,12 +1323,8 @@
n->name.len = ngx_strlen(n->name.data);
n->core_srv_conf = conf;
+ n->wildcard = 0;
-#if 0
- ctx = (ngx_http_conf_ctx_t *)
- cf->cycle->conf_ctx[ngx_http_module.index];
- cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
-#endif
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
if (cmcf->max_server_name_len < n->name.len) {
@@ -1512,7 +1508,7 @@
}
-static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+static char *ngx_http_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_core_srv_conf_t *scf = conf;
@@ -1607,13 +1603,8 @@
ngx_http_server_name_t *sn;
ngx_http_core_main_conf_t *cmcf;
- /* TODO: several names */
/* TODO: warn about duplicate 'server_name' directives */
-#if 0
- ctx = (ngx_http_conf_ctx_t *) cf->cycle->conf_ctx[ngx_http_module.index];
- cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
-#endif
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
value = cf->args->elts;
@@ -1627,12 +1618,23 @@
return NGX_CONF_ERROR;
}
- ngx_test_null(sn, ngx_push_array(&scf->server_names), NGX_CONF_ERROR);
+ if (!(sn = ngx_array_push(&scf->server_names))) {
+ return NGX_CONF_ERROR;
+ }
sn->name.len = value[i].len;
sn->name.data = value[i].data;
sn->core_srv_conf = scf;
+ if (sn->name.data[0] == '*') {
+ sn->name.len--;
+ sn->name.data++;
+ sn->wildcard = 1;
+
+ } else {
+ sn->wildcard = 0;
+ }
+
if (cmcf->max_server_name_len < sn->name.len) {
cmcf->max_server_name_len = sn->name.len;
}
@@ -1806,7 +1808,7 @@
{
ssize_t *np = data;
-#if __FreeBSD__
+#if (NGX_FREEBSD)
if (*np >= ngx_freebsd_net_inet_tcp_sendspace) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 787f8b8..9a17130 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -96,13 +96,15 @@
ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf
for this address:port */
- unsigned default_server:1;
+ ngx_uint_t default_server; /* unsigned default_server:1; */
} ngx_http_in_addr_t;
typedef struct {
ngx_str_t name;
ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */
+
+ ngx_uint_t wildcard; /*unsigned wildcard:1; */
} ngx_http_server_name_t;
@@ -135,7 +137,7 @@
struct ngx_http_core_loc_conf_s {
ngx_str_t name; /* location name */
-#if (HAVE_PCRE)
+#if (NGX_PCRE)
ngx_regex_t *regex;
#endif
diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c
index 5b7f3eb..a083b45 100644
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -317,10 +317,15 @@
if (r->headers_out.content_length == NULL) {
if (r->headers_out.content_length_n >= 0) {
+ b->last = ngx_sprintf(b->last, "Content-Length: %O" CRLF,
+ r->headers_out.content_length_n);
+
+#if 0
b->last += ngx_snprintf((char *) b->last,
sizeof("Content-Length: ") + NGX_OFF_T_LEN + 2,
"Content-Length: " OFF_T_FMT CRLF,
r->headers_out.content_length_n);
+#endif
}
}
@@ -372,7 +377,7 @@
{
b->last = ngx_cpymem(b->last, "Last-Modified: ",
sizeof("Last-Modified: ") - 1);
- b->last += ngx_http_time(b->last, r->headers_out.last_modified_time);
+ b->last = ngx_http_time(b->last, r->headers_out.last_modified_time);
*(b->last++) = CR; *(b->last++) = LF;
}
@@ -389,10 +394,14 @@
if (clcf->keepalive_header
&& (r->headers_in.gecko || r->headers_in.konqueror))
{
+ b->last = ngx_sprintf(b->last, "Keep-Alive: timeout=%T" CRLF,
+ clcf->keepalive_header);
+#if 0
b->last += ngx_snprintf((char *) b->last,
sizeof("Keep-Alive: timeout=") + TIME_T_LEN + 2,
"Keep-Alive: timeout=" TIME_T_FMT CRLF,
clcf->keepalive_header);
+#endif
}
} else {
diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c
index 51166cf..9a1389d 100644
--- a/src/http/ngx_http_log_handler.c
+++ b/src/http/ngx_http_log_handler.c
@@ -210,9 +210,13 @@
static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
uintptr_t data)
{
+ return ngx_sprintf(buf, "%ui", r->connection->number);
+
+#if 0
return buf + ngx_snprintf((char *) buf, NGX_INT_T_LEN + 1,
"%" NGX_UINT_T_FMT,
r->connection->number);
+#endif
}
@@ -244,8 +248,12 @@
ngx_gettimeofday(&tv);
+ return ngx_sprintf(buf, "%l.%03l", tv.tv_sec, tv.tv_usec / 1000);
+
+#if 0
return buf + ngx_snprintf((char *) buf, TIME_T_LEN + 5, "%ld.%03ld",
tv.tv_sec, tv.tv_usec / 1000);
+#endif
}
@@ -264,24 +272,36 @@
static u_char *ngx_http_log_status(ngx_http_request_t *r, u_char *buf,
uintptr_t data)
{
+ return ngx_sprintf(buf, "%ui",
+ r->err_status ? r->err_status : r->headers_out.status);
+
+#if 0
return buf + ngx_snprintf((char *) buf, 4, "%" NGX_UINT_T_FMT,
r->err_status ? r->err_status : r->headers_out.status);
+#endif
}
static u_char *ngx_http_log_length(ngx_http_request_t *r, u_char *buf,
uintptr_t data)
{
+ return ngx_sprintf(buf, "%O", r->connection->sent);
+
+#if 0
return buf + ngx_snprintf((char *) buf, NGX_OFF_T_LEN + 1, OFF_T_FMT,
r->connection->sent);
+#endif
}
static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf,
uintptr_t data)
{
+ return ngx_sprintf(buf, "%O", r->connection->sent - r->header_size);
+#if 0
return buf + ngx_snprintf((char *) buf, NGX_OFF_T_LEN + 1, OFF_T_FMT,
r->connection->sent - r->header_size);
+#endif
}
@@ -467,8 +487,7 @@
return (u_char *)
sizeof("Mon, 28 Sep 1970 06:00:00 GMT") - 1;
}
- return buf + ngx_http_time(buf,
- r->headers_out.last_modified_time);
+ return ngx_http_time(buf, r->headers_out.last_modified_time);
}
if (buf) {
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 6069847..74173d8 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1091,27 +1091,47 @@
name = r->virtual_names->elts;
for (i = 0; i < r->virtual_names->nelts; i++) {
- if (r->headers_in.host_name_len != name[i].name.len) {
- continue;
- }
- if (ngx_strncasecmp(r->headers_in.host->value.data,
- name[i].name.data,
- r->headers_in.host_name_len) == 0)
- {
- r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
- r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
- r->server_name = &name[i].name;
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "server name: %s", name[i].name.data);
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- r->connection->log->file = clcf->err_log->file;
- if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION))
- {
- r->connection->log->log_level = clcf->err_log->log_level;
+ if (name[i].wildcard) {
+ if (r->headers_in.host_name_len <= name[i].name.len) {
+ continue;
}
- break;
+ if (ngx_rstrncasecmp(r->headers_in.host->value.data,
+ name[i].name.data,
+ name[i].name.len) == 0)
+ {
+ continue;
+ }
+
+ } else {
+ if (r->headers_in.host_name_len != name[i].name.len) {
+ continue;
+ }
+
+ if (ngx_strncasecmp(r->headers_in.host->value.data,
+ name[i].name.data,
+ name[i].name.len) != 0)
+ {
+ continue;
+ }
}
+
+ r->srv_conf = name[i].core_srv_conf->ctx->srv_conf;
+ r->loc_conf = name[i].core_srv_conf->ctx->loc_conf;
+ r->server_name = &name[i].name;
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+ r->connection->log->file = clcf->err_log->file;
+
+ if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
+ r->connection->log->log_level = clcf->err_log->log_level;
+ }
+
+ break;
}
if (i == r->virtual_names->nelts) {
@@ -1562,7 +1582,13 @@
if (b != c->buffer) {
- /* move the large header buffers to the free list */
+ /*
+ * If the large header buffers were allocated while the previous
+ * request processing then we do not use c->buffer for
+ * the pipelined request (see ngx_http_init_request()).
+ *
+ * Now we would move the large header buffers to the free list.
+ */
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@@ -1614,6 +1640,14 @@
hc->pipeline = 0;
+ /*
+ * To keep a memory footprint as small as possible for an idle
+ * keepalive connection we try to free the ngx_http_request_t and
+ * c->buffer's memory if they were allocated outside the c->pool.
+ * The large header buffers are always allocated outside the c->pool and
+ * are freed too.
+ */
+
if (ngx_pfree(c->pool, r) == NGX_OK) {
hc->request = NULL;
}
@@ -1621,6 +1655,12 @@
b = c->buffer;
if (ngx_pfree(c->pool, b->start) == NGX_OK) {
+
+ /*
+ * the special note for ngx_http_keepalive_handler() that
+ * c->buffer's memory was freed
+ */
+
b->pos = NULL;
} else {
@@ -1655,7 +1695,7 @@
rev->event_handler = ngx_http_keepalive_handler;
if (wev->active) {
- if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT)
== NGX_ERROR)
{
@@ -1702,7 +1742,7 @@
}
#if 0
- /* if "keepalive_buffers off" then we need some other place */
+ /* if ngx_http_request_t was freed then we need some other place */
r->http_state = NGX_HTTP_KEEPALIVE_STATE;
#endif
@@ -1734,7 +1774,7 @@
#if (HAVE_KQUEUE)
- if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
if (rev->pending_eof) {
ngx_log_error(NGX_LOG_INFO, c->log, rev->kq_errno,
"kevent() reported that client %s closed "
@@ -1751,6 +1791,13 @@
size = b->end - b->start;
if (b->pos == NULL) {
+
+ /*
+ * The c->buffer's memory was freed by ngx_http_set_keepalive().
+ * However, the c->buffer->start and c->buffer->end were not changed
+ * to keep the buffer size.
+ */
+
if (!(b->pos = ngx_palloc(c->pool, size))) {
ngx_http_close_connection(c);
return;
@@ -1824,7 +1871,7 @@
wev->event_handler = ngx_http_empty_handler;
if (wev->active) {
- if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {
+ if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT)
== NGX_ERROR)
{
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 022b8a8..8a9c8f2 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -38,11 +38,11 @@
#define NGX_HTTP_PARSE_HEADER_ERROR 14
#define NGX_HTTP_PARSE_INVALID_HEADER 14
#define NGX_HTTP_PARSE_TOO_LONG_HEADER 15
-#define NGX_HTTP_PARSE_NO_HOST_HEADER 17
-#define NGX_HTTP_PARSE_INVALID_CL_HEADER 18
-#define NGX_HTTP_PARSE_POST_WO_CL_HEADER 19
-#define NGX_HTTP_PARSE_HTTP_TO_HTTPS 20
-#define NGX_HTTP_PARSE_INVALID_HOST 21
+#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_PARSE_HTTP_TO_HTTPS 19
+#define NGX_HTTP_PARSE_INVALID_HOST 20
#define NGX_HTTP_OK 200
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index a8c6894..37e0f3f 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -125,6 +125,7 @@
if (!last) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"the http output chain is empty");
+ return NGX_ERROR;
}
return NGX_OK;
}