nginx-0.3.56-RELEASE import
*) Feature: the "dav_access" directive.
*) Feature: the "if" directive supports the "-d", "!-d", "-e", "!-e",
"-x", and "!-x" operators.
*) Bugfix: a segmentation fault occurred if a request returned a
redirect and some sent to client header lines were logged in the
access log.
diff --git a/auto/lib/perl/conf b/auto/lib/perl/conf
index 1d7fe3b..9dbc279 100644
--- a/auto/lib/perl/conf
+++ b/auto/lib/perl/conf
@@ -20,6 +20,8 @@
fi
CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`"
+ # gcc 4.1/4.2
+ CFLAGS=`echo $CFLAGS | sed -e 's/-Wunused-value/-Wno-unused-value/'`
ngx_perl_ldopts=`$NGX_PERL -MExtUtils::Embed -e ldopts`
if $NGX_PERL -V:usemultiplicity | grep define > /dev/null; then
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index 3b7e6f3..20ec3b0 100644
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -9,6 +9,41 @@
<title lang="en">nginx changelog</title>
+<changes ver="0.3.56" date="04.08.2006">
+
+<change type="feature">
+<para lang="ru">
+ÄÉÒÅËÔÉ×Á dav_access.
+</para>
+<para lang="en">
+the "dav_access" directive.
+</para>
+</change>
+
+<change type="feature">
+<para lang="ru">
+ÄÉÒÅËÔÉ×Á if ÐÏÄÄÅÒÖÉ×ÁÅÔ ÏÐÅÒÁÔÏÒÙ "-d", "!-d", "-e", "!-e", "-x" É "!-x".
+</para>
+<para lang="en">
+the "if" directive supports the "-d", "!-d", "-e", "!-e", "-x", and "!-x"
+operators.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+ÐÒÉ ÚÁÐÉÓÉ × access_log ÎÅËÏÔÏÒÙÈ ÐÅÒÅÄÁ×ÁÅÍÙÈ ËÌÉÅÎÔÕ ÓÔÒÏË ÚÁÇÏÌÏ×ËÏ×
+ÐÒÏÉÓÈÏÄÉÌ segmentation fault, ÅÓÌÉ ÚÁÐÒÏÓ ×ÏÚ×ÒÁÝÁÌ ÒÅÄÉÒÅËÔ.
+</para>
+<para lang="en">
+a segmentation fault occurred if an request returned an redirect and
+some sent to client header lines were logged in the access log.
+</para>
+</change>
+
+</changes>
+
+
<changes ver="0.3.55" date="28.07.2006">
<change type="feature">
@@ -85,7 +120,7 @@
<change type="bugfix">
<para lang="ru">
-ÐÒÉ ÎÅËÏÔÏÒÙÈ ÕÓÌÏ×ÉÑÈ ×Ï ×ÒÅÍÑ ÐÅÒÅËÏÎÆÉÇÕÒÁÃÉÉ ËÏÄÙ ÓÉÍ×ÏÌÏ× ×
+ÐÒÉ ÎÅËÏÔÏÒÙÈ ÕÓÌÏ×ÉÑÈ ×Ï ×ÒÅÍÑ ÐÅÒÅËÏÎÆÉÇÕÒÁÃÉÉ ËÏÄÙ ÓÉÍ×ÏÌÏ×
×ÎÕÔÒÉ ÄÉÒÅËÔÉ×Ù charset_map ÍÏÇÌÉ ÓÞÉÔÁÔØÓÑ ÎÅ×ÅÒÎÙÍÉ;
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.3.50.
</para>
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 86beaea..c85e2a7 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VER "nginx/0.3.55"
+#define NGINX_VER "nginx/0.3.56"
#define NGINX_VAR "NGINX"
#define NGX_OLDPID_EXT ".oldbin"
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index a730ede..f6bf04b 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -166,7 +166,7 @@
ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
"temp file: \"%s\"", file->name.data);
- if (ngx_create_dir(file->name.data) == NGX_FILE_ERROR) {
+ if (ngx_create_dir(file->name.data, 0700) == NGX_FILE_ERROR) {
err = ngx_errno;
if (err != NGX_EEXIST) {
ngx_log_error(NGX_LOG_CRIT, file->log, err,
@@ -184,7 +184,7 @@
ngx_err_t
-ngx_create_full_path(u_char *dir)
+ngx_create_full_path(u_char *dir, ngx_uint_t access)
{
u_char *p, ch;
ngx_err_t err;
@@ -198,7 +198,7 @@
*p = '\0';
- if (ngx_create_dir(dir) == NGX_FILE_ERROR) {
+ if (ngx_create_dir(dir, access) == NGX_FILE_ERROR) {
err = ngx_errno;
if (err != NGX_EEXIST) {
return err;
@@ -370,7 +370,7 @@
path = cycle->pathes.elts;
for (i = 0; i < cycle->pathes.nelts; i++) {
- if (ngx_create_dir(path[i]->name.data) == NGX_FILE_ERROR) {
+ if (ngx_create_dir(path[i]->name.data, 0700) == NGX_FILE_ERROR) {
err = ngx_errno;
if (err != NGX_EEXIST) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, err,
diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
index 3ec3056..b51cad2 100644
--- a/src/core/ngx_file.h
+++ b/src/core/ngx_file.h
@@ -61,7 +61,7 @@
ngx_pool_t *pool, ngx_uint_t persistent,ngx_uint_t mode);
void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path);
ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path);
-ngx_err_t ngx_create_full_path(u_char *dir);
+ngx_err_t ngx_create_full_path(u_char *dir, ngx_uint_t access);
ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot);
ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user);
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 0ea937f..9901386 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -14,6 +14,7 @@
typedef struct {
ngx_uint_t methods;
ngx_flag_t create_full_put_path;
+ ngx_uint_t access;
} ngx_http_dav_loc_conf_t;
@@ -22,6 +23,8 @@
static ngx_int_t ngx_http_dav_error(ngx_http_request_t *, ngx_err_t err,
ngx_int_t not_found, char *failed, u_char *path);
static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path);
+static char *ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
@@ -53,6 +56,13 @@
offsetof(ngx_http_dav_loc_conf_t, create_full_put_path),
NULL },
+ { ngx_string("dav_access"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
+ ngx_http_dav_access,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
ngx_null_command
};
@@ -214,7 +224,7 @@
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http mkcol path: \"%s\"", path.data);
- if (ngx_create_dir(path.data) != NGX_FILE_ERROR) {
+ if (ngx_create_dir(path.data, dlcf->access) != NGX_FILE_ERROR) {
if (ngx_http_dav_location(r, path.data) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
@@ -233,6 +243,8 @@
static void
ngx_http_dav_put_handler(ngx_http_request_t *r)
{
+ char *failed;
+ u_char *name;
ngx_err_t err;
ngx_str_t *temp, path;
ngx_uint_t status;
@@ -267,6 +279,25 @@
}
}
+ dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
+
+#if !(NGX_WIN32)
+
+ if (ngx_change_file_access(temp->data, dlcf->access & ~0111)
+ == NGX_FILE_ERROR)
+ {
+ err = ngx_errno;
+ failed = ngx_change_file_access_n;
+ name = temp->data;
+
+ goto failed;
+ }
+
+#endif
+
+ failed = ngx_rename_file_n;
+ name = path.data;
+
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
goto ok;
}
@@ -275,10 +306,8 @@
if (err == NGX_ENOENT) {
- dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
-
if (dlcf->create_full_put_path) {
- err = ngx_create_full_path(path.data);
+ err = ngx_create_full_path(path.data, dlcf->access);
if (err == 0) {
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
@@ -303,6 +332,11 @@
err = ngx_errno;
}
+
+#else
+
+failed:
+
#endif
if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) {
@@ -311,9 +345,9 @@
temp->data);
}
- ngx_http_finalize_request(r, ngx_http_dav_error(r, err, NGX_HTTP_CONFLICT,
- ngx_rename_file_n,
- path.data));
+ ngx_http_finalize_request(r,
+ ngx_http_dav_error(r, err, NGX_HTTP_CONFLICT, failed, name));
+
return;
ok:
@@ -407,6 +441,66 @@
}
+static char *
+ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_dav_loc_conf_t *lcf = conf;
+
+ u_char *p;
+ ngx_str_t *value;
+ ngx_uint_t i, right, shift;
+
+ if (lcf->access != NGX_CONF_UNSET_UINT) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ lcf->access = 0700;
+
+ for (i = 1; i < 3; i++) {
+
+ p = value[i].data;
+
+ if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) {
+ shift = 6;
+ p += sizeof("user:") - 1;
+
+ } else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) {
+ shift = 3;
+ p += sizeof("group:") - 1;
+
+ } else if (ngx_strncmp(p, "all:", sizeof("all:") - 1) == 0) {
+ shift = 0;
+ p += sizeof("all:") - 1;
+
+ } else {
+ goto invalid;
+ }
+
+ if (ngx_strcmp(p, "rw") == 0) {
+ right = 7;
+
+ } else if (ngx_strcmp(p, "r") == 0) {
+ right = 5;
+
+ } else {
+ goto invalid;
+ }
+
+ lcf->access += right << shift;
+ }
+
+ return NGX_CONF_OK;
+
+invalid:
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid value \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+}
+
+
static void *
ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
{
@@ -424,6 +518,7 @@
*/
conf->create_full_put_path = NGX_CONF_UNSET;
+ conf->access = NGX_CONF_UNSET_UINT;
return conf;
}
@@ -441,6 +536,8 @@
ngx_conf_merge_value(conf->create_full_put_path, prev->create_full_put_path,
0);
+ ngx_conf_merge_uint_value(conf->access, prev->access, 0600);
+
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 980de19..30fbcd8 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -817,11 +817,41 @@
return NGX_CONF_OK;
}
+ if (p[1] == 'd') {
+ fop->op = ngx_http_script_file_dir;
+ return NGX_CONF_OK;
+ }
+
+ if (p[1] == 'e') {
+ fop->op = ngx_http_script_file_exists;
+ return NGX_CONF_OK;
+ }
+
+ if (p[1] == 'x') {
+ fop->op = ngx_http_script_file_exec;
+ return NGX_CONF_OK;
+ }
+
if (p[0] == '!') {
if (p[2] == 'f') {
fop->op = ngx_http_script_file_not_plain;
return NGX_CONF_OK;
}
+
+ if (p[2] == 'd') {
+ fop->op = ngx_http_script_file_not_dir;
+ return NGX_CONF_OK;
+ }
+
+ if (p[2] == 'e') {
+ fop->op = ngx_http_script_file_not_exists;
+ return NGX_CONF_OK;
+ }
+
+ if (p[2] == 'x') {
+ fop->op = ngx_http_script_file_not_exec;
+ return NGX_CONF_OK;
+ }
}
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 8c78e0f..344f613 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -17,6 +17,7 @@
#define NGX_DEFLAUT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
+static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_ssl_client_s_dn(ngx_http_request_t *r,
@@ -384,7 +385,8 @@
}
if (conf->verify) {
- SSL_CTX_set_verify(conf->ssl.ctx, NGX_SSL_VERIFY, NULL);
+ SSL_CTX_set_verify(conf->ssl.ctx, NGX_SSL_VERIFY,
+ ngx_http_ssl_verify_callback);
SSL_CTX_set_verify_depth(conf->ssl.ctx, conf->verify_depth);
@@ -422,6 +424,13 @@
}
+static int
+ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
+{
+ return 1;
+}
+
+
#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
static char *
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index ac4543b..a1b02f5 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -460,6 +460,8 @@
r->headers_out.location->value.len = b->last - p;
r->headers_out.location->value.data = p;
+ r->headers_out.location->key.len = sizeof("Location: ") - 1;
+ r->headers_out.location->key.data = (u_char *) "Location: ";
*b->last++ = CR; *b->last++ = LF;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index e645e81..42933e8 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1269,34 +1269,6 @@
return NGX_ERROR;
}
-#if (NGX_HTTP_SSL)
-
- if (r->connection->ssl) {
- sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
-
- if (sscf->verify) {
- rc = SSL_get_verify_result(r->connection->ssl->connection);
-
- if (rc != X509_V_OK) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client SSL certificate verify error: %l ", rc);
- ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
- return NGX_ERROR;
- }
-
- if (SSL_get_peer_certificate(r->connection->ssl->connection)
- == NULL)
- {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent no required SSL certificate");
- ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
- return NGX_ERROR;
- }
- }
- }
-
-#endif
-
if (r->headers_in.connection) {
if (r->headers_in.connection->value.len == 5
&& ngx_strcasecmp(r->headers_in.connection->value.data, "close")
@@ -1362,6 +1334,35 @@
}
}
+#if (NGX_HTTP_SSL)
+
+ if (r->connection->ssl) {
+ sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
+
+ if (sscf->verify) {
+ rc = SSL_get_verify_result(r->connection->ssl->connection);
+
+ if (rc != X509_V_OK) {
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ "client SSL certificate verify error: (%l:%s) ",
+ rc, X509_verify_cert_error_string(rc));
+ ngx_http_finalize_request(r, NGX_HTTPS_CERT_ERROR);
+ return NGX_ERROR;
+ }
+
+ if (SSL_get_peer_certificate(r->connection->ssl->connection)
+ == NULL)
+ {
+ ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+ "client sent no required SSL certificate");
+ ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
+ return NGX_ERROR;
+ }
+ }
+ }
+
+#endif
+
return NGX_OK;
}
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index 83c1998..947bce6 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -961,8 +961,13 @@
switch (code->op) {
case ngx_http_script_file_plain:
+ case ngx_http_script_file_dir:
+ case ngx_http_script_file_exists:
+ case ngx_http_script_file_exec:
goto false;
case ngx_http_script_file_not_plain:
+ case ngx_http_script_file_not_dir:
+ case ngx_http_script_file_not_exec:
goto true;
}
@@ -981,6 +986,54 @@
goto false;
}
goto true;
+
+ case ngx_http_script_file_dir:
+ if (ngx_is_dir(&fi)) {
+ goto true;
+ }
+ goto false;
+
+ case ngx_http_script_file_not_dir:
+ if (ngx_is_dir(&fi)) {
+ goto false;
+ }
+ goto true;
+
+ case ngx_http_script_file_exists:
+ if (ngx_is_file(&fi) || ngx_is_dir(&fi) || ngx_is_link(&fi)) {
+ goto true;
+ }
+ goto false;
+
+ case ngx_http_script_file_not_exists:
+ if (ngx_is_file(&fi) || ngx_is_dir(&fi) || ngx_is_link(&fi)) {
+ goto false;
+ }
+ goto true;
+
+#if (NGX_WIN32)
+
+ case ngx_http_script_file_exec:
+ goto false;
+
+ case ngx_http_script_file_not_exec:
+ goto true;
+
+#else
+
+ case ngx_http_script_file_exec:
+ if (ngx_is_exec(&fi)) {
+ goto true;
+ }
+ goto false;
+
+ case ngx_http_script_file_not_exec:
+ if (ngx_is_exec(&fi)) {
+ goto false;
+ }
+ goto true;
+
+#endif
}
false:
diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h
index c4aa408..cac7650 100644
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -140,7 +140,13 @@
typedef enum {
ngx_http_script_file_plain = 0,
- ngx_http_script_file_not_plain
+ ngx_http_script_file_not_plain,
+ ngx_http_script_file_dir,
+ ngx_http_script_file_not_dir,
+ ngx_http_script_file_exists,
+ ngx_http_script_file_not_exists,
+ ngx_http_script_file_exec,
+ ngx_http_script_file_not_exec
} ngx_http_script_file_op_e;
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 29b6495..dffef52 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -61,6 +61,10 @@
#define ngx_rename_file_n "rename"
+#define ngx_change_file_access(n, a) chmod((const char *) n, a)
+#define ngx_change_file_access_n "chmod"
+
+
#define ngx_file_info(file, sb) stat((const char *) file, sb)
#define ngx_file_info_n "stat()"
@@ -69,6 +73,8 @@
#define ngx_is_dir(sb) (S_ISDIR((sb)->st_mode))
#define ngx_is_file(sb) (S_ISREG((sb)->st_mode))
+#define ngx_is_link(sb) (S_ISLNK((sb)->st_mode))
+#define ngx_is_exec(sb) ((sb)->st_mode & S_IXUSR)
#define ngx_file_size(sb) (sb)->st_size
#define ngx_file_mtime(sb) (sb)->st_mtime
#define ngx_file_uniq(sb) (sb)->st_ino
@@ -95,7 +101,7 @@
#define ngx_read_dir_n "readdir()"
-#define ngx_create_dir(name) mkdir((const char *) name, 0700)
+#define ngx_create_dir(name, access) mkdir((const char *) name, access)
#define ngx_create_dir_n "mkdir()"
diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h
index beba0a8..b1c7230 100644
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -90,6 +90,7 @@
#define ngx_is_dir(fi) ((fi)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
#define ngx_is_file(fi) !((fi)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+#define ngx_is_link(fi) 0
#define ngx_file_size(fi) \
@@ -127,7 +128,7 @@
#define ngx_close_dir_n "FindClose()"
-#define ngx_create_dir(name) CreateDirectory((const char *) name, NULL)
+#define ngx_create_dir(name, access) CreateDirectory((const char *) name, NULL)
#define ngx_create_dir_n "CreateDirectory()"