+Changes with nginx 0.7.33 02 Feb 2009
+
+ *) Bugfix: a double response might be returned if the epoll or rtsig
+ methods are used and a redirect was returned to a request with
+ body.
+ Thanks to Eden Li.
+
+ *) Bugfix: the $sent_http_location variable was empty for some
+ redirects types.
+
+ *) Bugfix: a segmentation fault might occur in worker process if
+ "resolver" directive was used in SMTP proxy.
+
+
Changes with nginx 0.7.32 26 Jan 2009
*) Feature: now a directory existence testing can be set explicitly in
+éÚÍÅÎÅÎÉÑ × nginx 0.7.33 02.02.2009
+
+ *) éÓÐÒÁ×ÌÅÎÉÅ: ÅÓÌÉ ÎÁ ÚÁÐÒÏÓ Ó ÔÅÌÏÍ ×ÏÚ×ÒÁÝÁÌÓÑ ÒÅÄÉÒÅËÔ, ÔÏ ÏÔ×ÅÔ
+ ÍÏÇ ÂÙÔØ Ä×ÏÊÎÙÍ ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÍÅÔÏÄÏ× epoll ÉÌÉ rtsig.
+ óÐÁÓÉÂÏ Eden Li.
+
+ *) éÓÐÒÁ×ÌÅÎÉÅ: ÄÌÑ ÎÅËÏÔÏÒÙÈ ÔÉÐÏ× ÒÅÄÉÒÅËÔÏ× × ÐÅÒÅÍÅÎÎÏÊ
+ $sent_http_location ÂÙÌÏ ÐÕÓÔÏÅ ÚÎÁÞÅÎÉÅ.
+
+ *) éÓÐÒÁ×ÌÅÎÉÅ: ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÄÉÒÅËÔÉ×Ù resolver × SMTP
+ ÐÒÏËÓÉ-ÓÅÒ×ÅÒÅ × ÒÁÂÏÞÅÍ ÐÒÏÃÅÓÓÅ ÍÏÇ ÐÒÏÉÚÏÊÔÉ segmentation fault.
+
+
éÚÍÅÎÅÎÉÑ × nginx 0.7.32 26.01.2009
*) äÏÂÁ×ÌÅÎÉÅ: ÔÅÐÅÒØ × ÄÉÒÅËÔÉ×Å try_files ÍÏÖÎÏ Ñ×ÎÏ ÕËÁÚÁÔØ ÐÒÏ×ÅÒËÕ
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.7.32"
+#define NGINX_VERSION "0.7.33"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
ngx_int_t
ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
{
+ u_char *name;
ngx_resolver_t *r;
ngx_resolver_node_t *rn;
ngx_queue_insert_head(&r->addr_expire_queue, &rn->queue);
- ctx->name.len = rn->nlen;
- ctx->name.data = ngx_resolver_dup(r, rn->name, rn->nlen);
- if (ctx->name.data == NULL) {
+ name = ngx_resolver_dup(r, rn->name, rn->nlen);
+ if (name == NULL) {
goto failed;
}
+ ctx->name.len = rn->nlen;
+ ctx->name.data = name;
+
/* unlock addr mutex */
ctx->state = NGX_OK;
ctx->handler(ctx);
- ngx_resolver_free(r, ctx->name.data);
+ ngx_resolver_free(r, name);
return NGX_OK;
}
ctx->next = rn->waiting;
rn->waiting = ctx;
- return NGX_AGAIN;
+ /* unlock addr mutex */
+
+ return NGX_OK;
}
ngx_queue_remove(&rn->queue);
ctx->handler(ctx);
}
- if (naddrs) {
+ if (naddrs > 1) {
ngx_resolver_free(r, addrs);
}
goto short_response;
}
- len -= 2;
-
if (ngx_resolver_copy(r, &name, buf, &buf[i], &buf[n]) != NGX_OK) {
return;
}
ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver an:%V", &name);
- if (len != (size_t) rn->nlen || ngx_strncmp(name.data, rn->name, len) != 0)
+ if (name.len != (size_t) rn->nlen
+ || ngx_strncmp(name.data, rn->name, name.len) != 0)
{
- ngx_resolver_free(r, rn->name);
+ if (rn->nlen) {
+ ngx_resolver_free(r, rn->name);
+ }
+
+ rn->nlen = (u_short) name.len;
rn->name = name.data;
- name.data = ngx_resolver_dup(r, rn->name, len);
+ name.data = ngx_resolver_dup(r, rn->name, name.len);
if (name.data == NULL) {
goto failed;
}
ngx_http_index_handler(ngx_http_request_t *r)
{
u_char *p, *name;
- size_t len, nlen, root, allocated;
+ size_t len, root, reserve, allocated;
ngx_int_t rc;
ngx_str_t path, uri;
ngx_uint_t i, dir_tested;
root = 0;
dir_tested = 0;
name = NULL;
+ /* suppress MSVC warning */
path.data = NULL;
index = ilcf->indices->elts;
return ngx_http_internal_redirect(r, &index[i].name, &r->args);
}
- len = ilcf->max_index_len;
- nlen = index[i].name.len;
+ reserve = ilcf->max_index_len;
+ len = index[i].name.len;
} else {
ngx_memzero(&e, sizeof(ngx_http_script_engine_t));
e.request = r;
e.flushed = 1;
- /* 1 byte for terminating '\0' */
-
+ /* 1 is for terminating '\0' as in static names */
len = 1;
while (*(uintptr_t *) e.ip) {
len += lcode(&e);
}
- nlen = len;
-
/* 16 bytes are preallocation */
- len += 16;
+ reserve = len + 16;
}
- if (len > (size_t) (path.data + allocated - name)) {
+ if (reserve > allocated) {
- name = ngx_http_map_uri_to_path(r, &path, &root, len);
+ name = ngx_http_map_uri_to_path(r, &path, &root, reserve);
if (name == NULL) {
return NGX_ERROR;
}
- allocated = path.len;
+ allocated = path.data + path.len - name;
}
if (index[i].values == NULL) {
}
if (*name == '/') {
- uri.len = nlen - 1;
+ uri.len = len - 1;
uri.data = name;
return ngx_http_internal_redirect(r, &uri, &r->args);
}
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- uri.len = r->uri.len + nlen - 1;
+ uri.len = r->uri.len + len - 1;
if (!clcf->alias) {
uri.data = path.data + root;
}
p = ngx_copy(uri.data, r->uri.data, r->uri.len);
- ngx_memcpy(p, name, nlen - 1);
+ ngx_memcpy(p, name, len - 1);
}
return ngx_http_internal_redirect(r, &uri, &r->args);
continue;
}
- /* include the terminating '\0' to the length to use ngx_copy() */
+ /* include the terminating '\0' to the length to use ngx_memcpy() */
index->name.len++;
continue;
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.7.32';
+our $VERSION = '0.7.33';
require XSLoader;
XSLoader::load('nginx', $VERSION);
ngx_http_core_try_files_phase(ngx_http_request_t *r,
ngx_http_phase_handler_t *ph)
{
- size_t len, root, alias;
- ssize_t reserve, allocated;
+ size_t len, root, alias, reserve, allocated;
u_char *p, *name;
ngx_str_t path;
ngx_uint_t test_dir;
allocated = 0;
root = 0;
name = NULL;
- path.len = 0;
+ /* suppress MSVC warning */
path.data = NULL;
tf = clcf->try_files;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "set http keepalive handler");
if (r->discard_body) {
+ r->write_event_handler = ngx_http_request_empty_handler;
r->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
ngx_add_timer(rev, clcf->lingering_timeout);
return;
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_sent_content_length(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_variable_sent_location(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_sent_last_modified(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_sent_connection(ngx_http_request_t *r,
{ ngx_string("sent_http_content_length"), NULL,
ngx_http_variable_sent_content_length, 0, 0, 0 },
+ { ngx_string("sent_http_location"), NULL,
+ ngx_http_variable_sent_location, 0, 0, 0 },
+
{ ngx_string("sent_http_last_modified"), NULL,
ngx_http_variable_sent_last_modified, 0, 0, 0 },
}
+static ngx_int_t
+ngx_http_variable_sent_location(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ if (r->headers_out.location) {
+ v->len = r->headers_out.location->value.len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = r->headers_out.location->value.data;
+
+ return NGX_OK;
+ }
+
+ return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
+ &r->headers_out.headers.part,
+ sizeof("sent_http_") - 1);
+}
+
+
static ngx_int_t
ngx_http_variable_sent_last_modified(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx);
+static void ngx_mail_smtp_resolve_name(ngx_event_t *rev);
static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx);
static void ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c);
static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev);
static void
ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx)
{
- ngx_connection_t *c;
- ngx_mail_session_t *s;
- ngx_mail_core_srv_conf_t *cscf;
+ ngx_connection_t *c;
+ ngx_mail_session_t *s;
s = ctx->data;
c = s->connection;
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
"address resolved: %V", &s->host);
+ c->read->handler = ngx_mail_smtp_resolve_name;
+
+ ngx_post_event(c->read, &ngx_posted_events);
+}
+
+
+static void
+ngx_mail_smtp_resolve_name(ngx_event_t *rev)
+{
+ ngx_connection_t *c;
+ ngx_mail_session_t *s;
+ ngx_resolver_ctx_t *ctx;
+ ngx_mail_core_srv_conf_t *cscf;
+
+ c = rev->data;
+ s = c->data;
+
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
ctx = ngx_resolve_start(cscf->resolver, NULL);