Mercurial > hg > nginx-vendor-1-0
view src/core/ngx_conf_file.c @ 196:8759b346e431 NGINX_0_3_45
nginx 0.3.45
*) Feature: the "ssl_verify_client", "ssl_verify_depth", and
"ssl_client_certificate" directives.
*) Change: the $request_method variable now returns the main request
method.
*) Change: the ° symbol codes were changed in koi-win conversion
table.
*) Feature: the euro и N symbols were added to koi-win conversion table.
*) Bugfix: if nginx distributed the requests among several backends and
some backend failed, then requests intended for this backend was
directed to one live backend only instead of being distributed among
the rest.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Sat, 06 May 2006 00:00:00 +0400 |
parents | 003bd800ec2a |
children | e6da4931e0e0 |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev */ #include <ngx_config.h> #include <ngx_core.h> static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last); static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf); static char *ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static void ngx_conf_flush_files(ngx_cycle_t *cycle); static ngx_command_t ngx_conf_commands[] = { { ngx_string("include"), NGX_ANY_CONF|NGX_CONF_TAKE1, ngx_conf_include, 0, 0, NULL }, ngx_null_command }; ngx_module_t ngx_conf_module = { NGX_MODULE_V1, NULL, /* module context */ ngx_conf_commands, /* module directives */ NGX_CONF_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ ngx_conf_flush_files, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING }; /* The ten fixed arguments */ static int argument_number[] = { NGX_CONF_NOARGS, NGX_CONF_TAKE1, NGX_CONF_TAKE2, NGX_CONF_TAKE3, NGX_CONF_TAKE4, NGX_CONF_TAKE5, NGX_CONF_TAKE6, NGX_CONF_TAKE7 }; char * ngx_conf_parse(ngx_conf_t *cf, ngx_str_t *filename) { char *rv; ngx_fd_t fd; ngx_int_t rc; ngx_buf_t *b; ngx_uint_t block; ngx_conf_file_t *prev; #if (NGX_SUPPRESS_WARN) fd = NGX_INVALID_FILE; prev = NULL; #endif if (filename) { /* open configuration file */ fd = ngx_open_file(filename->data, NGX_FILE_RDONLY, NGX_FILE_OPEN); if (fd == NGX_INVALID_FILE) { ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, ngx_open_file_n " \"%s\" failed", filename->data); return NGX_CONF_ERROR; } prev = cf->conf_file; cf->conf_file = ngx_palloc(cf->pool, sizeof(ngx_conf_file_t)); if (cf->conf_file == NULL) { return NGX_CONF_ERROR; } if (ngx_fd_info(fd, &cf->conf_file->file.info) == -1) { ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, ngx_fd_info_n " \"%s\" failed", filename->data); } b = ngx_calloc_buf(cf->pool); if (b == NULL) { return NGX_CONF_ERROR; } cf->conf_file->buffer = b; b->start = ngx_alloc(ngx_pagesize, cf->log); if (b->start == NULL) { return NGX_CONF_ERROR; } b->pos = b->start; b->last = b->start; b->end = b->last + ngx_pagesize; b->temporary = 1; cf->conf_file->file.fd = fd; cf->conf_file->file.name.len = filename->len; cf->conf_file->file.name.data = filename->data; cf->conf_file->file.offset = 0; cf->conf_file->file.log = cf->log;; cf->conf_file->line = 1; block = 0; } else { block = 1; } for ( ;; ) { rc = ngx_conf_read_token(cf); /* * ngx_conf_read_token() may return * * NGX_ERROR there is error * NGX_OK the token terminated by ";" was found * NGX_CONF_BLOCK_START the token terminated by "{" was found * NGX_CONF_BLOCK_DONE the "}" was found * NGX_CONF_FILE_DONE the configuration file is done */ if (rc == NGX_ERROR) { break; } if (rc == NGX_CONF_BLOCK_DONE) { block = 0; } if (rc == NGX_CONF_FILE_DONE && block) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "unexpected end of file in %s:%ui, expecting \"}\"", cf->conf_file->file.name.data, cf->conf_file->line); rc = NGX_ERROR; break; } if (rc != NGX_OK && rc != NGX_CONF_BLOCK_START) { break; } if (cf->handler) { /* * the custom handler, i.e., that is used in the http's * "types { ... }" directive */ rv = (*cf->handler)(cf, NULL, cf->handler_conf); if (rv == NGX_CONF_OK) { continue; } if (rv == NGX_CONF_ERROR) { rc = NGX_ERROR; break; } ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "%s in %s:%ui", rv, cf->conf_file->file.name.data, cf->conf_file->line); rc = NGX_ERROR; break; } rc = ngx_conf_handler(cf, rc); if (rc == NGX_ERROR) { break; } } if (filename) { ngx_free(cf->conf_file->buffer->start); cf->conf_file = prev; if (ngx_close_file(fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, ngx_close_file_n " %s failed", cf->conf_file->file.name.data); return NGX_CONF_ERROR; } } if (rc == NGX_ERROR) { return NGX_CONF_ERROR; } return NGX_CONF_OK; } static ngx_int_t ngx_conf_handler(ngx_conf_t *cf, ngx_int_t last) { char *rv; void *conf, **confp; ngx_uint_t i, multi; ngx_str_t *name; ngx_command_t *cmd; name = cf->args->elts; multi = 0; for (i = 0; ngx_modules[i]; i++) { /* look up the directive in the appropriate modules */ if (ngx_modules[i]->type != NGX_CONF_MODULE && ngx_modules[i]->type != cf->module_type) { continue; } cmd = ngx_modules[i]->commands; if (cmd == NULL) { continue; } for ( /* void */ ; cmd->name.len; cmd++) { if (name->len != cmd->name.len) { continue; } if (ngx_strcmp(name->data, cmd->name.data) != 0) { continue; } /* is the directive's location right ? */ if (!(cmd->type & cf->cmd_type)) { if (cmd->type & NGX_CONF_MULTI) { multi = 1; continue; } goto not_allowed; } if (!(cmd->type & NGX_CONF_BLOCK) && last != NGX_OK) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "directive \"%s\" in %s:%ui " "is not terminated by \";\"", name->data, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } if ((cmd->type & NGX_CONF_BLOCK) && last != NGX_CONF_BLOCK_START) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "directive \"%s\" in %s:%ui " "has not the opening \"{\"", name->data, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } /* is the directive's argument count right ? */ if (!(cmd->type & NGX_CONF_ANY)) { if (cmd->type & NGX_CONF_FLAG) { if (cf->args->nelts != 2) { goto invalid; } } else if (cmd->type & NGX_CONF_1MORE) { if (cf->args->nelts < 2) { goto invalid; } } else if (cmd->type & NGX_CONF_2MORE) { if (cf->args->nelts < 3) { goto invalid; } } else if (cf->args->nelts > NGX_CONF_MAX_ARGS) { goto invalid; } else if (!(cmd->type & argument_number[cf->args->nelts - 1])) { goto invalid; } } /* set up the directive's configuration context */ conf = NULL; if (cmd->type & NGX_DIRECT_CONF) { conf = ((void **) cf->ctx)[ngx_modules[i]->index]; } else if (cmd->type & NGX_MAIN_CONF) { conf = &(((void **) cf->ctx)[ngx_modules[i]->index]); } else if (cf->ctx) { confp = *(void **) ((char *) cf->ctx + cmd->conf); if (confp) { conf = confp[ngx_modules[i]->ctx_index]; } } rv = cmd->set(cf, cmd, conf); if (rv == NGX_CONF_OK) { return NGX_OK; } if (rv == NGX_CONF_ERROR) { return NGX_ERROR; } ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "the \"%s\" directive %s in %s:%ui", name->data, rv, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } } if (multi == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "unknown directive \"%s\" in %s:%ui", name->data, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } not_allowed: ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "directive \"%s\" in %s:%ui " "is not allowed here", name->data, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; invalid: ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "invalid number arguments in " "directive \"%s\" in %s:%ui", name->data, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } static ngx_int_t ngx_conf_read_token(ngx_conf_t *cf) { u_char *start, ch, *src, *dst; int len; int found, need_space, last_space, sharp_comment, variable; int quoted, s_quoted, d_quoted; ssize_t n; ngx_str_t *word; ngx_buf_t *b; found = 0; need_space = 0; last_space = 1; sharp_comment = 0; variable = 0; quoted = s_quoted = d_quoted = 0; cf->args->nelts = 0; b = cf->conf_file->buffer; start = b->pos; for ( ;; ) { if (b->pos >= b->last) { if (cf->conf_file->file.offset >= ngx_file_size(&cf->conf_file->file.info)) { if (cf->args->nelts > 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "unexpected end of file in %s:%ui, " "expecting \";\" or \"}\"", cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } return NGX_CONF_FILE_DONE; } if (b->pos - start) { ngx_memcpy(b->start, start, b->pos - start); } n = ngx_read_file(&cf->conf_file->file, b->start + (b->pos - start), b->end - (b->start + (b->pos - start)), cf->conf_file->file.offset); if (n == NGX_ERROR) { return NGX_ERROR; } b->pos = b->start + (b->pos - start); start = b->start; b->last = b->pos + n; } ch = *b->pos++; if (ch == LF) { cf->conf_file->line++; if (sharp_comment) { sharp_comment = 0; } } if (sharp_comment) { continue; } if (quoted) { quoted = 0; continue; } if (need_space) { if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) { last_space = 1; need_space = 0; continue; } if (ch == ';') { return NGX_OK; } if (ch == '{') { return NGX_CONF_BLOCK_START; } if (ch == ')') { last_space = 1; need_space = 0; } else { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "unexpected \"%c\" in %s:%ui", ch, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } } if (last_space) { if (ch == ' ' || ch == '\t' || ch == CR || ch == LF) { continue; } start = b->pos - 1; switch (ch) { case ';': case '{': if (cf->args->nelts == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "unexpected \"%c\" in %s:%ui", ch, cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } if (ch == '{') { return NGX_CONF_BLOCK_START; } return NGX_OK; case '}': if (cf->args->nelts != 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "unexpected \"}\" in %s:%ui", cf->conf_file->file.name.data, cf->conf_file->line); return NGX_ERROR; } return NGX_CONF_BLOCK_DONE; case '#': sharp_comment = 1; continue; case '\\': quoted = 1; last_space = 0; continue; case '"': start++; d_quoted = 1; last_space = 0; continue; case '\'': start++; s_quoted = 1; last_space = 0; continue; default: last_space = 0; } } else { if (ch == '{' && variable) { continue; } variable = 0; if (ch == '\\') { quoted = 1; continue; } if (ch == '$') { variable = 1; continue; } if (d_quoted) { if (ch == '"') { d_quoted = 0; need_space = 1; found = 1; } } else if (s_quoted) { if (ch == '\'') { s_quoted = 0; need_space = 1; found = 1; } } else if (ch == ' ' || ch == '\t' || ch == CR || ch == LF || ch == ';' || ch == '{') { last_space = 1; found = 1; } if (found) { word = ngx_array_push(cf->args); if (word == NULL) { return NGX_ERROR; } word->data = ngx_palloc(cf->pool, b->pos - start + 1); if (word->data == NULL) { return NGX_ERROR; } for (dst = word->data, src = start, len = 0; src < b->pos - 1; len++) { if (*src == '\\') { switch (src[1]) { case '"': case '\'': case '\\': src++; break; case 't': *dst++ = '\t'; src += 2; continue; case 'r': *dst++ = '\r'; src += 2; continue; case 'n': *dst++ = '\n'; src += 2; continue; } } *dst++ = *src++; } *dst = '\0'; word->len = len; if (ch == ';') { return NGX_OK; } if (ch == '{') { return NGX_CONF_BLOCK_START; } found = 0; } } } } static char * ngx_conf_include(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value, file; value = cf->args->elts; file = value[1]; if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR) { return NGX_CONF_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data); return ngx_conf_parse(cf, &file); } ngx_int_t ngx_conf_full_name(ngx_cycle_t *cycle, ngx_str_t *name) { u_char *p; ngx_str_t old; if (name->data[0] == '/') { return NGX_OK; } #if (NGX_WIN32) if (name->len > 2 && name->data[1] == ':' && ((name->data[0] >= 'a' && name->data[0] <= 'z') || (name->data[0] >= 'A' && name->data[0] <= 'Z'))) { return NGX_OK; } #endif old = *name; name->len = cycle->root.len + old.len; name->data = ngx_palloc(cycle->pool, name->len + 1); if (name->data == NULL) { return NGX_ERROR; } p = ngx_cpymem(name->data, cycle->root.data, cycle->root.len), ngx_cpystrn(p, old.data, old.len + 1); return NGX_OK; } ngx_open_file_t * ngx_conf_open_file(ngx_cycle_t *cycle, ngx_str_t *name) { ngx_str_t full; ngx_uint_t i; ngx_list_part_t *part; ngx_open_file_t *file; #if (NGX_SUPPRESS_WARN) full.len = 0; full.data = NULL; #endif if (name) { full = *name; if (ngx_conf_full_name(cycle, &full) == NGX_ERROR) { return NULL; } part = &cycle->open_files.part; file = part->elts; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; file = part->elts; i = 0; } if (full.len != file[i].name.len) { continue; } if (ngx_strcmp(full.data, file[i].name.data) == 0) { return &file[i]; } } } file = ngx_list_push(&cycle->open_files); if (file == NULL) { return NULL; } if (name) { file->fd = NGX_INVALID_FILE; file->name = full; } else { file->fd = ngx_stderr_fileno; file->name.len = 0; file->name.data = NULL; } file->buffer = NULL; return file; } static void ngx_conf_flush_files(ngx_cycle_t *cycle) { ngx_uint_t i; ngx_list_part_t *part; ngx_open_file_t *file; ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "flush files"); part = &cycle->open_files.part; file = part->elts; for (i = 0; /* void */ ; i++) { if (i >= part->nelts) { if (part->next == NULL) { break; } part = part->next; file = part->elts; i = 0; } if (file[i].buffer == NULL || file[i].pos - file[i].buffer == 0) { continue; } ngx_write_fd(file[i].fd, file[i].buffer, file[i].pos - file[i].buffer); } } void ngx_cdecl ngx_conf_log_error(ngx_uint_t level, ngx_conf_t *cf, ngx_err_t err, char *fmt, ...) { u_char errstr[NGX_MAX_CONF_ERRSTR], *buf, *last; va_list args; last = errstr + NGX_MAX_CONF_ERRSTR; va_start(args, fmt); buf = ngx_vsnprintf(errstr, last - errstr, fmt, args); va_end(args); *buf = '\0'; if (err) { buf = ngx_snprintf(buf, last - buf - 1, " (%d: ", err); buf = ngx_strerror_r(err, buf, last - buf - 1); *buf++ = ')'; *buf = '\0'; } if (cf->conf_file == NULL) { ngx_log_error(level, cf->log, 0, "%s", errstr); return; } ngx_log_error(level, cf->log, 0, "%s in %s:%ui", errstr, cf->conf_file->file.name.data, cf->conf_file->line); } char * ngx_conf_set_flag_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_str_t *value; ngx_flag_t *fp; ngx_conf_post_t *post; fp = (ngx_flag_t *) (p + cmd->offset); if (*fp != NGX_CONF_UNSET) { return "is duplicate"; } value = cf->args->elts; if (ngx_strcasecmp(value[1].data, "on") == 0) { *fp = 1; } else if (ngx_strcasecmp(value[1].data, "off") == 0) { *fp = 0; } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid value \"%s\" in \"%s\" directive, " "it must be \"on\" or \"off\"", value[1].data, cmd->name.data); return NGX_CONF_ERROR; } if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, fp); } return NGX_CONF_OK; } char * ngx_conf_set_str_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_str_t *field, *value; ngx_conf_post_t *post; field = (ngx_str_t *) (p + cmd->offset); if (field->data) { return "is duplicate"; } value = cf->args->elts; *field = value[1]; if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, field); } return NGX_CONF_OK; } char * ngx_conf_set_table_elt_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_str_t *value; ngx_array_t **a; ngx_table_elt_t *elt; ngx_conf_post_t *post; a = (ngx_array_t **) (p + cmd->offset); if (*a == NULL) { *a = ngx_array_create(cf->pool, 4, sizeof(ngx_table_elt_t)); if (*a == NULL) { return NGX_CONF_ERROR; } } elt = ngx_array_push(*a); if (elt == NULL) { return NGX_CONF_ERROR; } value = cf->args->elts; elt->hash = 0; elt->key = value[1]; elt->value = value[2]; if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, elt); } return NGX_CONF_OK; } char * ngx_conf_set_num_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_int_t *np; ngx_str_t *value; ngx_conf_post_t *post; np = (ngx_int_t *) (p + cmd->offset); if (*np != NGX_CONF_UNSET) { return "is duplicate"; } value = cf->args->elts; *np = ngx_atoi(value[1].data, value[1].len); if (*np == NGX_ERROR) { return "invalid number"; } if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, np); } return NGX_CONF_OK; } char * ngx_conf_set_size_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; size_t *sp; ngx_str_t *value; ngx_conf_post_t *post; sp = (size_t *) (p + cmd->offset); if (*sp != NGX_CONF_UNSET_SIZE) { return "is duplicate"; } value = cf->args->elts; *sp = ngx_parse_size(&value[1]); if (*sp == (size_t) NGX_ERROR) { return "invalid value"; } if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, sp); } return NGX_CONF_OK; } char * ngx_conf_set_msec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_msec_t *msp; ngx_str_t *value; ngx_conf_post_t *post; msp = (ngx_msec_t *) (p + cmd->offset); if (*msp != NGX_CONF_UNSET_MSEC) { return "is duplicate"; } value = cf->args->elts; *msp = ngx_parse_time(&value[1], 0); if (*msp == (ngx_msec_t) NGX_ERROR) { return "invalid value"; } if (*msp == (ngx_msec_t) NGX_PARSE_LARGE_TIME) { return "value must be less than 597 hours"; } if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, msp); } return NGX_CONF_OK; } char * ngx_conf_set_sec_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; time_t *sp; ngx_str_t *value; ngx_conf_post_t *post; sp = (time_t *) (p + cmd->offset); if (*sp != NGX_CONF_UNSET) { return "is duplicate"; } value = cf->args->elts; *sp = ngx_parse_time(&value[1], 1); if (*sp == NGX_ERROR) { return "invalid value"; } if (*sp == NGX_PARSE_LARGE_TIME) { return "value must be less than 68 years"; } if (cmd->post) { post = cmd->post; return post->post_handler(cf, post, sp); } return NGX_CONF_OK; } char * ngx_conf_set_bufs_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_str_t *value; ngx_bufs_t *bufs; bufs = (ngx_bufs_t *) (p + cmd->offset); if (bufs->num) { return "is duplicate"; } value = cf->args->elts; bufs->num = ngx_atoi(value[1].data, value[1].len); if (bufs->num == NGX_ERROR || bufs->num == 0) { return "invalid value"; } bufs->size = ngx_parse_size(&value[2]); if (bufs->size == (size_t) NGX_ERROR || bufs->size == 0) { return "invalid value"; } return NGX_CONF_OK; } char * ngx_conf_set_enum_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_uint_t *np, i; ngx_str_t *value; ngx_conf_enum_t *e; np = (ngx_uint_t *) (p + cmd->offset); if (*np != NGX_CONF_UNSET_UINT) { return "is duplicate"; } value = cf->args->elts; e = cmd->post; for (i = 0; e[i].name.len != 0; i++) { if (e[i].name.len != value[1].len || ngx_strcasecmp(e[i].name.data, value[1].data) != 0) { continue; } *np = e[i].value; return NGX_CONF_OK; } ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "invalid value \"%s\"", value[1].data); return NGX_CONF_ERROR; } char * ngx_conf_set_bitmask_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; ngx_uint_t *np, i, m; ngx_str_t *value; ngx_conf_bitmask_t *mask; np = (ngx_uint_t *) (p + cmd->offset); value = cf->args->elts; mask = cmd->post; for (i = 1; i < cf->args->nelts; i++) { for (m = 0; mask[m].name.len != 0; m++) { if (mask[m].name.len != value[i].len || ngx_strcasecmp(mask[m].name.data, value[i].data) != 0) { continue; } if (*np & mask[m].mask) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "duplicate value \"%s\"", value[i].data); } else { *np |= mask[m].mask; } break; } if (mask[m].name.len == 0) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "invalid value \"%s\"", value[i].data); return NGX_CONF_ERROR; } } return NGX_CONF_OK; } char * ngx_conf_unsupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { return "unsupported on this platform"; } char * ngx_conf_deprecated(ngx_conf_t *cf, void *post, void *data) { ngx_conf_deprecated_t *d = post; ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "the \"%s\" directive is deprecated, " "use the \"%s\" directive instead", d->old_name, d->new_name); return NGX_CONF_OK; } char * ngx_conf_check_num_bounds(ngx_conf_t *cf, void *post, void *data) { ngx_conf_num_bounds_t *bounds = post; ngx_int_t *np = data; if (bounds->high == -1) { if (*np >= bounds->low) { return NGX_CONF_OK; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "value must be equal or more than %i", bounds->low); return NGX_CONF_ERROR; } if (*np >= bounds->low && *np <= bounds->high) { return NGX_CONF_OK; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "value must be between %i and %i", bounds->low, bounds->high); return NGX_CONF_ERROR; }