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.
This commit is contained in:
Igor Sysoev 2006-08-04 16:04:04 +00:00
parent db488c0592
commit f08b1910d9
14 changed files with 288 additions and 46 deletions

View file

@ -20,6 +20,8 @@ if test -n "$NGX_PERL_VER"; then
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

View file

@ -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 @@ was used and nginx was switches to a next upstream.
<change type="bugfix">
<para lang="ru">
при некоторых условиях во время переконфигурации коды символов в
ÐÒÉ ÎÅËÏÔÏÒÙÈ ÕÓÌÏ×ÉÑÈ ×Ï ×ÒÅÍÑ ÐÅÒÅËÏÎÆÉÇÕÒÁÃÉÉ ËÏÄÙ ÓÉÍ×ÏÌÏ×
×ÎÕÔÒÉ ÄÉÒÅËÔÉ×Ù charset_map ÍÏÇÌÉ ÓÞÉÔÁÔØÓÑ ÎÅ×ÅÒÎÙÍÉ;
ÏÛÉÂËÁ ÐÏÑ×ÉÌÁÓØ × 0.3.50.
</para>

View file

@ -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"

View file

@ -166,7 +166,7 @@ ngx_create_path(ngx_file_t *file, ngx_path_t *path)
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_create_path(ngx_file_t *file, ngx_path_t *path)
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 @@ ngx_create_full_path(u_char *dir)
*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 @@ ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user)
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,

View file

@ -61,7 +61,7 @@ ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path,
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);

View file

@ -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 void ngx_http_dav_put_handler(ngx_http_request_t *r);
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 @@ static ngx_command_t ngx_http_dav_commands[] = {
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_http_dav_handler(ngx_http_request_t *r)
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 @@ ngx_http_dav_handler(ngx_http_request_t *r)
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 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
}
}
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 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
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 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
err = ngx_errno;
}
#else
failed:
#endif
if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) {
@ -311,9 +345,9 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
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 @@ 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)
{
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 @@ ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
*/
conf->create_full_put_path = NGX_CONF_UNSET;
conf->access = NGX_CONF_UNSET_UINT;
return conf;
}
@ -441,6 +536,8 @@ ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
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;
}

View file

@ -817,11 +817,41 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
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,

View file

@ -17,6 +17,7 @@ typedef u_char *(*ngx_ssl_variable_handler_pt)(ngx_connection_t *);
#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 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
}
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 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
}
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 *

View file

@ -460,6 +460,8 @@ ngx_http_header_filter(ngx_http_request_t *r)
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;
}

View file

@ -1269,34 +1269,6 @@ ngx_http_process_request_header(ngx_http_request_t *r)
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 @@ ngx_http_process_request_header(ngx_http_request_t *r)
}
}
#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;
}

View file

@ -961,8 +961,13 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
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 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
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:

View file

@ -140,7 +140,13 @@ typedef struct {
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;

View file

@ -61,6 +61,10 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
#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 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
#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 @@ ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir);
#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()"

View file

@ -90,6 +90,7 @@ ngx_int_t ngx_file_info(u_char *filename, ngx_file_info_t *fi);
#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 @@ ngx_int_t ngx_read_dir(ngx_dir_t *dir);
#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()"