Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.12 ]​[ nginx-1.16.0 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_stream.h>
0011 
0012 
0013 static ngx_int_t ngx_stream_upstream_add_variables(ngx_conf_t *cf);
0014 static ngx_int_t ngx_stream_upstream_addr_variable(ngx_stream_session_t *s,
0015     ngx_stream_variable_value_t *v, uintptr_t data);
0016 static ngx_int_t ngx_stream_upstream_response_time_variable(
0017     ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
0018 static ngx_int_t ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s,
0019     ngx_stream_variable_value_t *v, uintptr_t data);
0020 
0021 static char *ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd,
0022     void *dummy);
0023 static char *ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
0024     void *conf);
0025 static void *ngx_stream_upstream_create_main_conf(ngx_conf_t *cf);
0026 static char *ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf);
0027 
0028 
0029 static ngx_command_t  ngx_stream_upstream_commands[] = {
0030 
0031     { ngx_string("upstream"),
0032       NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE1,
0033       ngx_stream_upstream,
0034       0,
0035       0,
0036       NULL },
0037 
0038     { ngx_string("server"),
0039       NGX_STREAM_UPS_CONF|NGX_CONF_1MORE,
0040       ngx_stream_upstream_server,
0041       NGX_STREAM_SRV_CONF_OFFSET,
0042       0,
0043       NULL },
0044 
0045       ngx_null_command
0046 };
0047 
0048 
0049 static ngx_stream_module_t  ngx_stream_upstream_module_ctx = {
0050     ngx_stream_upstream_add_variables,     /* preconfiguration */
0051     NULL,                                  /* postconfiguration */
0052 
0053     ngx_stream_upstream_create_main_conf,  /* create main configuration */
0054     ngx_stream_upstream_init_main_conf,    /* init main configuration */
0055 
0056     NULL,                                  /* create server configuration */
0057     NULL                                   /* merge server configuration */
0058 };
0059 
0060 
0061 ngx_module_t  ngx_stream_upstream_module = {
0062     NGX_MODULE_V1,
0063     &ngx_stream_upstream_module_ctx,       /* module context */
0064     ngx_stream_upstream_commands,          /* module directives */
0065     NGX_STREAM_MODULE,                     /* module type */
0066     NULL,                                  /* init master */
0067     NULL,                                  /* init module */
0068     NULL,                                  /* init process */
0069     NULL,                                  /* init thread */
0070     NULL,                                  /* exit thread */
0071     NULL,                                  /* exit process */
0072     NULL,                                  /* exit master */
0073     NGX_MODULE_V1_PADDING
0074 };
0075 
0076 
0077 static ngx_stream_variable_t  ngx_stream_upstream_vars[] = {
0078 
0079     { ngx_string("upstream_addr"), NULL,
0080       ngx_stream_upstream_addr_variable, 0,
0081       NGX_STREAM_VAR_NOCACHEABLE, 0 },
0082 
0083     { ngx_string("upstream_bytes_sent"), NULL,
0084       ngx_stream_upstream_bytes_variable, 0,
0085       NGX_STREAM_VAR_NOCACHEABLE, 0 },
0086 
0087     { ngx_string("upstream_connect_time"), NULL,
0088       ngx_stream_upstream_response_time_variable, 2,
0089       NGX_STREAM_VAR_NOCACHEABLE, 0 },
0090 
0091     { ngx_string("upstream_first_byte_time"), NULL,
0092       ngx_stream_upstream_response_time_variable, 1,
0093       NGX_STREAM_VAR_NOCACHEABLE, 0 },
0094 
0095     { ngx_string("upstream_session_time"), NULL,
0096       ngx_stream_upstream_response_time_variable, 0,
0097       NGX_STREAM_VAR_NOCACHEABLE, 0 },
0098 
0099     { ngx_string("upstream_bytes_received"), NULL,
0100       ngx_stream_upstream_bytes_variable, 1,
0101       NGX_STREAM_VAR_NOCACHEABLE, 0 },
0102 
0103       ngx_stream_null_variable
0104 };
0105 
0106 
0107 static ngx_int_t
0108 ngx_stream_upstream_add_variables(ngx_conf_t *cf)
0109 {
0110     ngx_stream_variable_t  *var, *v;
0111 
0112     for (v = ngx_stream_upstream_vars; v->name.len; v++) {
0113         var = ngx_stream_add_variable(cf, &v->name, v->flags);
0114         if (var == NULL) {
0115             return NGX_ERROR;
0116         }
0117 
0118         var->get_handler = v->get_handler;
0119         var->data = v->data;
0120     }
0121 
0122     return NGX_OK;
0123 }
0124 
0125 
0126 static ngx_int_t
0127 ngx_stream_upstream_addr_variable(ngx_stream_session_t *s,
0128     ngx_stream_variable_value_t *v, uintptr_t data)
0129 {
0130     u_char                       *p;
0131     size_t                        len;
0132     ngx_uint_t                    i;
0133     ngx_stream_upstream_state_t  *state;
0134 
0135     v->valid = 1;
0136     v->no_cacheable = 0;
0137     v->not_found = 0;
0138 
0139     if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
0140         v->not_found = 1;
0141         return NGX_OK;
0142     }
0143 
0144     len = 0;
0145     state = s->upstream_states->elts;
0146 
0147     for (i = 0; i < s->upstream_states->nelts; i++) {
0148         if (state[i].peer) {
0149             len += state[i].peer->len;
0150         }
0151 
0152         len += 2;
0153     }
0154 
0155     p = ngx_pnalloc(s->connection->pool, len);
0156     if (p == NULL) {
0157         return NGX_ERROR;
0158     }
0159 
0160     v->data = p;
0161 
0162     i = 0;
0163 
0164     for ( ;; ) {
0165         if (state[i].peer) {
0166             p = ngx_cpymem(p, state[i].peer->data, state[i].peer->len);
0167         }
0168 
0169         if (++i == s->upstream_states->nelts) {
0170             break;
0171         }
0172 
0173         *p++ = ',';
0174         *p++ = ' ';
0175     }
0176 
0177     v->len = p - v->data;
0178 
0179     return NGX_OK;
0180 }
0181 
0182 
0183 static ngx_int_t
0184 ngx_stream_upstream_bytes_variable(ngx_stream_session_t *s,
0185     ngx_stream_variable_value_t *v, uintptr_t data)
0186 {
0187     u_char                       *p;
0188     size_t                        len;
0189     ngx_uint_t                    i;
0190     ngx_stream_upstream_state_t  *state;
0191 
0192     v->valid = 1;
0193     v->no_cacheable = 0;
0194     v->not_found = 0;
0195 
0196     if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
0197         v->not_found = 1;
0198         return NGX_OK;
0199     }
0200 
0201     len = s->upstream_states->nelts * (NGX_OFF_T_LEN + 2);
0202 
0203     p = ngx_pnalloc(s->connection->pool, len);
0204     if (p == NULL) {
0205         return NGX_ERROR;
0206     }
0207 
0208     v->data = p;
0209 
0210     i = 0;
0211     state = s->upstream_states->elts;
0212 
0213     for ( ;; ) {
0214 
0215         if (data == 1) {
0216             p = ngx_sprintf(p, "%O", state[i].bytes_received);
0217 
0218         } else {
0219             p = ngx_sprintf(p, "%O", state[i].bytes_sent);
0220         }
0221 
0222         if (++i == s->upstream_states->nelts) {
0223             break;
0224         }
0225 
0226         *p++ = ',';
0227         *p++ = ' ';
0228     }
0229 
0230     v->len = p - v->data;
0231 
0232     return NGX_OK;
0233 }
0234 
0235 
0236 static ngx_int_t
0237 ngx_stream_upstream_response_time_variable(ngx_stream_session_t *s,
0238     ngx_stream_variable_value_t *v, uintptr_t data)
0239 {
0240     u_char                       *p;
0241     size_t                        len;
0242     ngx_uint_t                    i;
0243     ngx_msec_int_t                ms;
0244     ngx_stream_upstream_state_t  *state;
0245 
0246     v->valid = 1;
0247     v->no_cacheable = 0;
0248     v->not_found = 0;
0249 
0250     if (s->upstream_states == NULL || s->upstream_states->nelts == 0) {
0251         v->not_found = 1;
0252         return NGX_OK;
0253     }
0254 
0255     len = s->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2);
0256 
0257     p = ngx_pnalloc(s->connection->pool, len);
0258     if (p == NULL) {
0259         return NGX_ERROR;
0260     }
0261 
0262     v->data = p;
0263 
0264     i = 0;
0265     state = s->upstream_states->elts;
0266 
0267     for ( ;; ) {
0268 
0269         if (data == 1) {
0270             ms = state[i].first_byte_time;
0271 
0272         } else if (data == 2) {
0273             ms = state[i].connect_time;
0274 
0275         } else {
0276             ms = state[i].response_time;
0277         }
0278 
0279         if (ms != -1) {
0280             ms = ngx_max(ms, 0);
0281             p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
0282 
0283         } else {
0284             *p++ = '-';
0285         }
0286 
0287         if (++i == s->upstream_states->nelts) {
0288             break;
0289         }
0290 
0291         *p++ = ',';
0292         *p++ = ' ';
0293     }
0294 
0295     v->len = p - v->data;
0296 
0297     return NGX_OK;
0298 }
0299 
0300 
0301 static char *
0302 ngx_stream_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
0303 {
0304     char                            *rv;
0305     void                            *mconf;
0306     ngx_str_t                       *value;
0307     ngx_url_t                        u;
0308     ngx_uint_t                       m;
0309     ngx_conf_t                       pcf;
0310     ngx_stream_module_t             *module;
0311     ngx_stream_conf_ctx_t           *ctx, *stream_ctx;
0312     ngx_stream_upstream_srv_conf_t  *uscf;
0313 
0314     ngx_memzero(&u, sizeof(ngx_url_t));
0315 
0316     value = cf->args->elts;
0317     u.host = value[1];
0318     u.no_resolve = 1;
0319     u.no_port = 1;
0320 
0321     uscf = ngx_stream_upstream_add(cf, &u, NGX_STREAM_UPSTREAM_CREATE
0322                                            |NGX_STREAM_UPSTREAM_WEIGHT
0323                                            |NGX_STREAM_UPSTREAM_MAX_CONNS
0324                                            |NGX_STREAM_UPSTREAM_MAX_FAILS
0325                                            |NGX_STREAM_UPSTREAM_FAIL_TIMEOUT
0326                                            |NGX_STREAM_UPSTREAM_DOWN
0327                                            |NGX_STREAM_UPSTREAM_BACKUP);
0328     if (uscf == NULL) {
0329         return NGX_CONF_ERROR;
0330     }
0331 
0332 
0333     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_conf_ctx_t));
0334     if (ctx == NULL) {
0335         return NGX_CONF_ERROR;
0336     }
0337 
0338     stream_ctx = cf->ctx;
0339     ctx->main_conf = stream_ctx->main_conf;
0340 
0341     /* the upstream{}'s srv_conf */
0342 
0343     ctx->srv_conf = ngx_pcalloc(cf->pool,
0344                                 sizeof(void *) * ngx_stream_max_module);
0345     if (ctx->srv_conf == NULL) {
0346         return NGX_CONF_ERROR;
0347     }
0348 
0349     ctx->srv_conf[ngx_stream_upstream_module.ctx_index] = uscf;
0350 
0351     uscf->srv_conf = ctx->srv_conf;
0352 
0353     for (m = 0; cf->cycle->modules[m]; m++) {
0354         if (cf->cycle->modules[m]->type != NGX_STREAM_MODULE) {
0355             continue;
0356         }
0357 
0358         module = cf->cycle->modules[m]->ctx;
0359 
0360         if (module->create_srv_conf) {
0361             mconf = module->create_srv_conf(cf);
0362             if (mconf == NULL) {
0363                 return NGX_CONF_ERROR;
0364             }
0365 
0366             ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf;
0367         }
0368     }
0369 
0370     uscf->servers = ngx_array_create(cf->pool, 4,
0371                                      sizeof(ngx_stream_upstream_server_t));
0372     if (uscf->servers == NULL) {
0373         return NGX_CONF_ERROR;
0374     }
0375 
0376 
0377     /* parse inside upstream{} */
0378 
0379     pcf = *cf;
0380     cf->ctx = ctx;
0381     cf->cmd_type = NGX_STREAM_UPS_CONF;
0382 
0383     rv = ngx_conf_parse(cf, NULL);
0384 
0385     *cf = pcf;
0386 
0387     if (rv != NGX_CONF_OK) {
0388         return rv;
0389     }
0390 
0391     if (uscf->servers->nelts == 0) {
0392         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0393                            "no servers are inside upstream");
0394         return NGX_CONF_ERROR;
0395     }
0396 
0397     return rv;
0398 }
0399 
0400 
0401 static char *
0402 ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0403 {
0404     ngx_stream_upstream_srv_conf_t  *uscf = conf;
0405 
0406     time_t                         fail_timeout;
0407     ngx_str_t                     *value, s;
0408     ngx_url_t                      u;
0409     ngx_int_t                      weight, max_conns, max_fails;
0410     ngx_uint_t                     i;
0411     ngx_stream_upstream_server_t  *us;
0412 
0413     us = ngx_array_push(uscf->servers);
0414     if (us == NULL) {
0415         return NGX_CONF_ERROR;
0416     }
0417 
0418     ngx_memzero(us, sizeof(ngx_stream_upstream_server_t));
0419 
0420     value = cf->args->elts;
0421 
0422     weight = 1;
0423     max_conns = 0;
0424     max_fails = 1;
0425     fail_timeout = 10;
0426 
0427     for (i = 2; i < cf->args->nelts; i++) {
0428 
0429         if (ngx_strncmp(value[i].data, "weight=", 7) == 0) {
0430 
0431             if (!(uscf->flags & NGX_STREAM_UPSTREAM_WEIGHT)) {
0432                 goto not_supported;
0433             }
0434 
0435             weight = ngx_atoi(&value[i].data[7], value[i].len - 7);
0436 
0437             if (weight == NGX_ERROR || weight == 0) {
0438                 goto invalid;
0439             }
0440 
0441             continue;
0442         }
0443 
0444         if (ngx_strncmp(value[i].data, "max_conns=", 10) == 0) {
0445 
0446             if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_CONNS)) {
0447                 goto not_supported;
0448             }
0449 
0450             max_conns = ngx_atoi(&value[i].data[10], value[i].len - 10);
0451 
0452             if (max_conns == NGX_ERROR) {
0453                 goto invalid;
0454             }
0455 
0456             continue;
0457         }
0458 
0459         if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) {
0460 
0461             if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_FAILS)) {
0462                 goto not_supported;
0463             }
0464 
0465             max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10);
0466 
0467             if (max_fails == NGX_ERROR) {
0468                 goto invalid;
0469             }
0470 
0471             continue;
0472         }
0473 
0474         if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) {
0475 
0476             if (!(uscf->flags & NGX_STREAM_UPSTREAM_FAIL_TIMEOUT)) {
0477                 goto not_supported;
0478             }
0479 
0480             s.len = value[i].len - 13;
0481             s.data = &value[i].data[13];
0482 
0483             fail_timeout = ngx_parse_time(&s, 1);
0484 
0485             if (fail_timeout == (time_t) NGX_ERROR) {
0486                 goto invalid;
0487             }
0488 
0489             continue;
0490         }
0491 
0492         if (ngx_strcmp(value[i].data, "backup") == 0) {
0493 
0494             if (!(uscf->flags & NGX_STREAM_UPSTREAM_BACKUP)) {
0495                 goto not_supported;
0496             }
0497 
0498             us->backup = 1;
0499 
0500             continue;
0501         }
0502 
0503         if (ngx_strcmp(value[i].data, "down") == 0) {
0504 
0505             if (!(uscf->flags & NGX_STREAM_UPSTREAM_DOWN)) {
0506                 goto not_supported;
0507             }
0508 
0509             us->down = 1;
0510 
0511             continue;
0512         }
0513 
0514         goto invalid;
0515     }
0516 
0517     ngx_memzero(&u, sizeof(ngx_url_t));
0518 
0519     u.url = value[1];
0520 
0521     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
0522         if (u.err) {
0523             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0524                                "%s in upstream \"%V\"", u.err, &u.url);
0525         }
0526 
0527         return NGX_CONF_ERROR;
0528     }
0529 
0530     if (u.no_port) {
0531         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0532                            "no port in upstream \"%V\"", &u.url);
0533         return NGX_CONF_ERROR;
0534     }
0535 
0536     us->name = u.url;
0537     us->addrs = u.addrs;
0538     us->naddrs = u.naddrs;
0539     us->weight = weight;
0540     us->max_conns = max_conns;
0541     us->max_fails = max_fails;
0542     us->fail_timeout = fail_timeout;
0543 
0544     return NGX_CONF_OK;
0545 
0546 invalid:
0547 
0548     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0549                        "invalid parameter \"%V\"", &value[i]);
0550 
0551     return NGX_CONF_ERROR;
0552 
0553 not_supported:
0554 
0555     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0556                        "balancing method does not support parameter \"%V\"",
0557                        &value[i]);
0558 
0559     return NGX_CONF_ERROR;
0560 }
0561 
0562 
0563 ngx_stream_upstream_srv_conf_t *
0564 ngx_stream_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
0565 {
0566     ngx_uint_t                        i;
0567     ngx_stream_upstream_server_t     *us;
0568     ngx_stream_upstream_srv_conf_t   *uscf, **uscfp;
0569     ngx_stream_upstream_main_conf_t  *umcf;
0570 
0571     if (!(flags & NGX_STREAM_UPSTREAM_CREATE)) {
0572 
0573         if (ngx_parse_url(cf->pool, u) != NGX_OK) {
0574             if (u->err) {
0575                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0576                                    "%s in upstream \"%V\"", u->err, &u->url);
0577             }
0578 
0579             return NULL;
0580         }
0581     }
0582 
0583     umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module);
0584 
0585     uscfp = umcf->upstreams.elts;
0586 
0587     for (i = 0; i < umcf->upstreams.nelts; i++) {
0588 
0589         if (uscfp[i]->host.len != u->host.len
0590             || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len)
0591                != 0)
0592         {
0593             continue;
0594         }
0595 
0596         if ((flags & NGX_STREAM_UPSTREAM_CREATE)
0597              && (uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE))
0598         {
0599             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0600                                "duplicate upstream \"%V\"", &u->host);
0601             return NULL;
0602         }
0603 
0604         if ((uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE) && !u->no_port) {
0605             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0606                                "upstream \"%V\" may not have port %d",
0607                                &u->host, u->port);
0608             return NULL;
0609         }
0610 
0611         if ((flags & NGX_STREAM_UPSTREAM_CREATE) && !uscfp[i]->no_port) {
0612             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0613                           "upstream \"%V\" may not have port %d in %s:%ui",
0614                           &u->host, uscfp[i]->port,
0615                           uscfp[i]->file_name, uscfp[i]->line);
0616             return NULL;
0617         }
0618 
0619         if (uscfp[i]->port != u->port) {
0620             continue;
0621         }
0622 
0623         if (flags & NGX_STREAM_UPSTREAM_CREATE) {
0624             uscfp[i]->flags = flags;
0625         }
0626 
0627         return uscfp[i];
0628     }
0629 
0630     uscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_srv_conf_t));
0631     if (uscf == NULL) {
0632         return NULL;
0633     }
0634 
0635     uscf->flags = flags;
0636     uscf->host = u->host;
0637     uscf->file_name = cf->conf_file->file.name.data;
0638     uscf->line = cf->conf_file->line;
0639     uscf->port = u->port;
0640     uscf->no_port = u->no_port;
0641 
0642     if (u->naddrs == 1 && (u->port || u->family == AF_UNIX)) {
0643         uscf->servers = ngx_array_create(cf->pool, 1,
0644                                          sizeof(ngx_stream_upstream_server_t));
0645         if (uscf->servers == NULL) {
0646             return NULL;
0647         }
0648 
0649         us = ngx_array_push(uscf->servers);
0650         if (us == NULL) {
0651             return NULL;
0652         }
0653 
0654         ngx_memzero(us, sizeof(ngx_stream_upstream_server_t));
0655 
0656         us->addrs = u->addrs;
0657         us->naddrs = 1;
0658     }
0659 
0660     uscfp = ngx_array_push(&umcf->upstreams);
0661     if (uscfp == NULL) {
0662         return NULL;
0663     }
0664 
0665     *uscfp = uscf;
0666 
0667     return uscf;
0668 }
0669 
0670 
0671 static void *
0672 ngx_stream_upstream_create_main_conf(ngx_conf_t *cf)
0673 {
0674     ngx_stream_upstream_main_conf_t  *umcf;
0675 
0676     umcf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_main_conf_t));
0677     if (umcf == NULL) {
0678         return NULL;
0679     }
0680 
0681     if (ngx_array_init(&umcf->upstreams, cf->pool, 4,
0682                        sizeof(ngx_stream_upstream_srv_conf_t *))
0683         != NGX_OK)
0684     {
0685         return NULL;
0686     }
0687 
0688     return umcf;
0689 }
0690 
0691 
0692 static char *
0693 ngx_stream_upstream_init_main_conf(ngx_conf_t *cf, void *conf)
0694 {
0695     ngx_stream_upstream_main_conf_t *umcf = conf;
0696 
0697     ngx_uint_t                        i;
0698     ngx_stream_upstream_init_pt       init;
0699     ngx_stream_upstream_srv_conf_t  **uscfp;
0700 
0701     uscfp = umcf->upstreams.elts;
0702 
0703     for (i = 0; i < umcf->upstreams.nelts; i++) {
0704 
0705         init = uscfp[i]->peer.init_upstream
0706                                          ? uscfp[i]->peer.init_upstream
0707                                          : ngx_stream_upstream_init_round_robin;
0708 
0709         if (init(cf, uscfp[i]) != NGX_OK) {
0710             return NGX_CONF_ERROR;
0711         }
0712     }
0713 
0714     return NGX_CONF_OK;
0715 }