Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.11 ]​[ nginx-1.14.2 ]​

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_event.h>
0011 #include <ngx_mail.h>
0012 
0013 
0014 static void *ngx_mail_core_create_main_conf(ngx_conf_t *cf);
0015 static void *ngx_mail_core_create_srv_conf(ngx_conf_t *cf);
0016 static char *ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent,
0017     void *child);
0018 static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
0019     void *conf);
0020 static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
0021     void *conf);
0022 static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd,
0023     void *conf);
0024 static char *ngx_mail_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd,
0025     void *conf);
0026 static char *ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd,
0027     void *conf);
0028 
0029 
0030 static ngx_command_t  ngx_mail_core_commands[] = {
0031 
0032     { ngx_string("server"),
0033       NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
0034       ngx_mail_core_server,
0035       0,
0036       0,
0037       NULL },
0038 
0039     { ngx_string("listen"),
0040       NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
0041       ngx_mail_core_listen,
0042       NGX_MAIL_SRV_CONF_OFFSET,
0043       0,
0044       NULL },
0045 
0046     { ngx_string("protocol"),
0047       NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0048       ngx_mail_core_protocol,
0049       NGX_MAIL_SRV_CONF_OFFSET,
0050       0,
0051       NULL },
0052 
0053     { ngx_string("timeout"),
0054       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0055       ngx_conf_set_msec_slot,
0056       NGX_MAIL_SRV_CONF_OFFSET,
0057       offsetof(ngx_mail_core_srv_conf_t, timeout),
0058       NULL },
0059 
0060     { ngx_string("server_name"),
0061       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0062       ngx_conf_set_str_slot,
0063       NGX_MAIL_SRV_CONF_OFFSET,
0064       offsetof(ngx_mail_core_srv_conf_t, server_name),
0065       NULL },
0066 
0067     { ngx_string("error_log"),
0068       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
0069       ngx_mail_core_error_log,
0070       NGX_MAIL_SRV_CONF_OFFSET,
0071       0,
0072       NULL },
0073 
0074     { ngx_string("resolver"),
0075       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
0076       ngx_mail_core_resolver,
0077       NGX_MAIL_SRV_CONF_OFFSET,
0078       0,
0079       NULL },
0080 
0081     { ngx_string("resolver_timeout"),
0082       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
0083       ngx_conf_set_msec_slot,
0084       NGX_MAIL_SRV_CONF_OFFSET,
0085       offsetof(ngx_mail_core_srv_conf_t, resolver_timeout),
0086       NULL },
0087 
0088       ngx_null_command
0089 };
0090 
0091 
0092 static ngx_mail_module_t  ngx_mail_core_module_ctx = {
0093     NULL,                                  /* protocol */
0094 
0095     ngx_mail_core_create_main_conf,        /* create main configuration */
0096     NULL,                                  /* init main configuration */
0097 
0098     ngx_mail_core_create_srv_conf,         /* create server configuration */
0099     ngx_mail_core_merge_srv_conf           /* merge server configuration */
0100 };
0101 
0102 
0103 ngx_module_t  ngx_mail_core_module = {
0104     NGX_MODULE_V1,
0105     &ngx_mail_core_module_ctx,             /* module context */
0106     ngx_mail_core_commands,                /* module directives */
0107     NGX_MAIL_MODULE,                       /* module type */
0108     NULL,                                  /* init master */
0109     NULL,                                  /* init module */
0110     NULL,                                  /* init process */
0111     NULL,                                  /* init thread */
0112     NULL,                                  /* exit thread */
0113     NULL,                                  /* exit process */
0114     NULL,                                  /* exit master */
0115     NGX_MODULE_V1_PADDING
0116 };
0117 
0118 
0119 static void *
0120 ngx_mail_core_create_main_conf(ngx_conf_t *cf)
0121 {
0122     ngx_mail_core_main_conf_t  *cmcf;
0123 
0124     cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t));
0125     if (cmcf == NULL) {
0126         return NULL;
0127     }
0128 
0129     if (ngx_array_init(&cmcf->servers, cf->pool, 4,
0130                        sizeof(ngx_mail_core_srv_conf_t *))
0131         != NGX_OK)
0132     {
0133         return NULL;
0134     }
0135 
0136     if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t))
0137         != NGX_OK)
0138     {
0139         return NULL;
0140     }
0141 
0142     return cmcf;
0143 }
0144 
0145 
0146 static void *
0147 ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
0148 {
0149     ngx_mail_core_srv_conf_t  *cscf;
0150 
0151     cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t));
0152     if (cscf == NULL) {
0153         return NULL;
0154     }
0155 
0156     /*
0157      * set by ngx_pcalloc():
0158      *
0159      *     cscf->protocol = NULL;
0160      *     cscf->error_log = NULL;
0161      */
0162 
0163     cscf->timeout = NGX_CONF_UNSET_MSEC;
0164     cscf->resolver_timeout = NGX_CONF_UNSET_MSEC;
0165 
0166     cscf->resolver = NGX_CONF_UNSET_PTR;
0167 
0168     cscf->file_name = cf->conf_file->file.name.data;
0169     cscf->line = cf->conf_file->line;
0170 
0171     return cscf;
0172 }
0173 
0174 
0175 static char *
0176 ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
0177 {
0178     ngx_mail_core_srv_conf_t *prev = parent;
0179     ngx_mail_core_srv_conf_t *conf = child;
0180 
0181     ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
0182     ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout,
0183                               30000);
0184 
0185 
0186     ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
0187 
0188     if (conf->server_name.len == 0) {
0189         conf->server_name = cf->cycle->hostname;
0190     }
0191 
0192     if (conf->protocol == NULL) {
0193         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0194                       "unknown mail protocol for server in %s:%ui",
0195                       conf->file_name, conf->line);
0196         return NGX_CONF_ERROR;
0197     }
0198 
0199     if (conf->error_log == NULL) {
0200         if (prev->error_log) {
0201             conf->error_log = prev->error_log;
0202         } else {
0203             conf->error_log = &cf->cycle->new_log;
0204         }
0205     }
0206 
0207     ngx_conf_merge_ptr_value(conf->resolver, prev->resolver, NULL);
0208 
0209     return NGX_CONF_OK;
0210 }
0211 
0212 
0213 static char *
0214 ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0215 {
0216     char                       *rv;
0217     void                       *mconf;
0218     ngx_uint_t                  m;
0219     ngx_conf_t                  pcf;
0220     ngx_mail_module_t          *module;
0221     ngx_mail_conf_ctx_t        *ctx, *mail_ctx;
0222     ngx_mail_core_srv_conf_t   *cscf, **cscfp;
0223     ngx_mail_core_main_conf_t  *cmcf;
0224 
0225     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
0226     if (ctx == NULL) {
0227         return NGX_CONF_ERROR;
0228     }
0229 
0230     mail_ctx = cf->ctx;
0231     ctx->main_conf = mail_ctx->main_conf;
0232 
0233     /* the server{}'s srv_conf */
0234 
0235     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);
0236     if (ctx->srv_conf == NULL) {
0237         return NGX_CONF_ERROR;
0238     }
0239 
0240     for (m = 0; cf->cycle->modules[m]; m++) {
0241         if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) {
0242             continue;
0243         }
0244 
0245         module = cf->cycle->modules[m]->ctx;
0246 
0247         if (module->create_srv_conf) {
0248             mconf = module->create_srv_conf(cf);
0249             if (mconf == NULL) {
0250                 return NGX_CONF_ERROR;
0251             }
0252 
0253             ctx->srv_conf[cf->cycle->modules[m]->ctx_index] = mconf;
0254         }
0255     }
0256 
0257     /* the server configuration context */
0258 
0259     cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
0260     cscf->ctx = ctx;
0261 
0262     cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
0263 
0264     cscfp = ngx_array_push(&cmcf->servers);
0265     if (cscfp == NULL) {
0266         return NGX_CONF_ERROR;
0267     }
0268 
0269     *cscfp = cscf;
0270 
0271 
0272     /* parse inside server{} */
0273 
0274     pcf = *cf;
0275     cf->ctx = ctx;
0276     cf->cmd_type = NGX_MAIL_SRV_CONF;
0277 
0278     rv = ngx_conf_parse(cf, NULL);
0279 
0280     *cf = pcf;
0281 
0282     if (rv == NGX_CONF_OK && !cscf->listen) {
0283         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0284                       "no \"listen\" is defined for server in %s:%ui",
0285                       cscf->file_name, cscf->line);
0286         return NGX_CONF_ERROR;
0287     }
0288 
0289     return rv;
0290 }
0291 
0292 
0293 static char *
0294 ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0295 {
0296     ngx_mail_core_srv_conf_t  *cscf = conf;
0297 
0298     ngx_str_t                  *value, size;
0299     ngx_url_t                   u;
0300     ngx_uint_t                  i, n, m;
0301     ngx_mail_listen_t          *ls, *als;
0302     ngx_mail_module_t          *module;
0303     ngx_mail_core_main_conf_t  *cmcf;
0304 
0305     cscf->listen = 1;
0306 
0307     value = cf->args->elts;
0308 
0309     ngx_memzero(&u, sizeof(ngx_url_t));
0310 
0311     u.url = value[1];
0312     u.listen = 1;
0313 
0314     if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
0315         if (u.err) {
0316             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0317                                "%s in \"%V\" of the \"listen\" directive",
0318                                u.err, &u.url);
0319         }
0320 
0321         return NGX_CONF_ERROR;
0322     }
0323 
0324     cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
0325 
0326     ls = ngx_array_push_n(&cmcf->listen, u.naddrs);
0327     if (ls == NULL) {
0328         return NGX_CONF_ERROR;
0329     }
0330 
0331     ngx_memzero(ls, sizeof(ngx_mail_listen_t));
0332 
0333     ls->backlog = NGX_LISTEN_BACKLOG;
0334     ls->rcvbuf = -1;
0335     ls->sndbuf = -1;
0336     ls->ctx = cf->ctx;
0337 
0338 #if (NGX_HAVE_INET6)
0339     ls->ipv6only = 1;
0340 #endif
0341 
0342     if (cscf->protocol == NULL) {
0343         for (m = 0; cf->cycle->modules[m]; m++) {
0344             if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) {
0345                 continue;
0346             }
0347 
0348             module = cf->cycle->modules[m]->ctx;
0349 
0350             if (module->protocol == NULL) {
0351                 continue;
0352             }
0353 
0354             for (i = 0; module->protocol->port[i]; i++) {
0355                 if (module->protocol->port[i] == u.port) {
0356                     cscf->protocol = module->protocol;
0357                     break;
0358                 }
0359             }
0360         }
0361     }
0362 
0363     for (i = 2; i < cf->args->nelts; i++) {
0364 
0365         if (ngx_strcmp(value[i].data, "bind") == 0) {
0366             ls->bind = 1;
0367             continue;
0368         }
0369 
0370         if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) {
0371             ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8);
0372             ls->bind = 1;
0373 
0374             if (ls->backlog == NGX_ERROR || ls->backlog == 0) {
0375                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0376                                    "invalid backlog \"%V\"", &value[i]);
0377                 return NGX_CONF_ERROR;
0378             }
0379 
0380             continue;
0381         }
0382 
0383         if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) {
0384             size.len = value[i].len - 7;
0385             size.data = value[i].data + 7;
0386 
0387             ls->rcvbuf = ngx_parse_size(&size);
0388             ls->bind = 1;
0389 
0390             if (ls->rcvbuf == NGX_ERROR) {
0391                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0392                                    "invalid rcvbuf \"%V\"", &value[i]);
0393                 return NGX_CONF_ERROR;
0394             }
0395 
0396             continue;
0397         }
0398 
0399         if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) {
0400             size.len = value[i].len - 7;
0401             size.data = value[i].data + 7;
0402 
0403             ls->sndbuf = ngx_parse_size(&size);
0404             ls->bind = 1;
0405 
0406             if (ls->sndbuf == NGX_ERROR) {
0407                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0408                                    "invalid sndbuf \"%V\"", &value[i]);
0409                 return NGX_CONF_ERROR;
0410             }
0411 
0412             continue;
0413         }
0414 
0415         if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
0416 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
0417             if (ngx_strcmp(&value[i].data[10], "n") == 0) {
0418                 ls->ipv6only = 1;
0419 
0420             } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
0421                 ls->ipv6only = 0;
0422 
0423             } else {
0424                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0425                                    "invalid ipv6only flags \"%s\"",
0426                                    &value[i].data[9]);
0427                 return NGX_CONF_ERROR;
0428             }
0429 
0430             ls->bind = 1;
0431             continue;
0432 #else
0433             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0434                                "bind ipv6only is not supported "
0435                                "on this platform");
0436             return NGX_CONF_ERROR;
0437 #endif
0438         }
0439 
0440         if (ngx_strcmp(value[i].data, "ssl") == 0) {
0441 #if (NGX_MAIL_SSL)
0442             ngx_mail_ssl_conf_t  *sslcf;
0443 
0444             sslcf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_ssl_module);
0445 
0446             sslcf->listen = 1;
0447             sslcf->file = cf->conf_file->file.name.data;
0448             sslcf->line = cf->conf_file->line;
0449 
0450             ls->ssl = 1;
0451 
0452             continue;
0453 #else
0454             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0455                                "the \"ssl\" parameter requires "
0456                                "ngx_mail_ssl_module");
0457             return NGX_CONF_ERROR;
0458 #endif
0459         }
0460 
0461         if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) {
0462 
0463             if (ngx_strcmp(&value[i].data[13], "on") == 0) {
0464                 ls->so_keepalive = 1;
0465 
0466             } else if (ngx_strcmp(&value[i].data[13], "off") == 0) {
0467                 ls->so_keepalive = 2;
0468 
0469             } else {
0470 
0471 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
0472                 u_char     *p, *end;
0473                 ngx_str_t   s;
0474 
0475                 end = value[i].data + value[i].len;
0476                 s.data = value[i].data + 13;
0477 
0478                 p = ngx_strlchr(s.data, end, ':');
0479                 if (p == NULL) {
0480                     p = end;
0481                 }
0482 
0483                 if (p > s.data) {
0484                     s.len = p - s.data;
0485 
0486                     ls->tcp_keepidle = ngx_parse_time(&s, 1);
0487                     if (ls->tcp_keepidle == (time_t) NGX_ERROR) {
0488                         goto invalid_so_keepalive;
0489                     }
0490                 }
0491 
0492                 s.data = (p < end) ? (p + 1) : end;
0493 
0494                 p = ngx_strlchr(s.data, end, ':');
0495                 if (p == NULL) {
0496                     p = end;
0497                 }
0498 
0499                 if (p > s.data) {
0500                     s.len = p - s.data;
0501 
0502                     ls->tcp_keepintvl = ngx_parse_time(&s, 1);
0503                     if (ls->tcp_keepintvl == (time_t) NGX_ERROR) {
0504                         goto invalid_so_keepalive;
0505                     }
0506                 }
0507 
0508                 s.data = (p < end) ? (p + 1) : end;
0509 
0510                 if (s.data < end) {
0511                     s.len = end - s.data;
0512 
0513                     ls->tcp_keepcnt = ngx_atoi(s.data, s.len);
0514                     if (ls->tcp_keepcnt == NGX_ERROR) {
0515                         goto invalid_so_keepalive;
0516                     }
0517                 }
0518 
0519                 if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0
0520                     && ls->tcp_keepcnt == 0)
0521                 {
0522                     goto invalid_so_keepalive;
0523                 }
0524 
0525                 ls->so_keepalive = 1;
0526 
0527 #else
0528 
0529                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0530                                    "the \"so_keepalive\" parameter accepts "
0531                                    "only \"on\" or \"off\" on this platform");
0532                 return NGX_CONF_ERROR;
0533 
0534 #endif
0535             }
0536 
0537             ls->bind = 1;
0538 
0539             continue;
0540 
0541 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
0542         invalid_so_keepalive:
0543 
0544             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0545                                "invalid so_keepalive value: \"%s\"",
0546                                &value[i].data[13]);
0547             return NGX_CONF_ERROR;
0548 #endif
0549         }
0550 
0551         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0552                            "the invalid \"%V\" parameter", &value[i]);
0553         return NGX_CONF_ERROR;
0554     }
0555 
0556     als = cmcf->listen.elts;
0557 
0558     for (n = 0; n < u.naddrs; n++) {
0559         ls[n] = ls[0];
0560 
0561         ls[n].sockaddr = u.addrs[n].sockaddr;
0562         ls[n].socklen = u.addrs[n].socklen;
0563         ls[n].addr_text = u.addrs[n].name;
0564         ls[n].wildcard = ngx_inet_wildcard(ls[n].sockaddr);
0565 
0566         for (i = 0; i < cmcf->listen.nelts - u.naddrs + n; i++) {
0567 
0568             if (ngx_cmp_sockaddr(als[i].sockaddr, als[i].socklen,
0569                                  ls[n].sockaddr, ls[n].socklen, 1)
0570                 != NGX_OK)
0571             {
0572                 continue;
0573             }
0574 
0575             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0576                                "duplicate \"%V\" address and port pair",
0577                                &ls[n].addr_text);
0578             return NGX_CONF_ERROR;
0579         }
0580     }
0581 
0582     return NGX_CONF_OK;
0583 }
0584 
0585 
0586 static char *
0587 ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0588 {
0589     ngx_mail_core_srv_conf_t  *cscf = conf;
0590 
0591     ngx_str_t          *value;
0592     ngx_uint_t          m;
0593     ngx_mail_module_t  *module;
0594 
0595     value = cf->args->elts;
0596 
0597     for (m = 0; cf->cycle->modules[m]; m++) {
0598         if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) {
0599             continue;
0600         }
0601 
0602         module = cf->cycle->modules[m]->ctx;
0603 
0604         if (module->protocol
0605             && ngx_strcmp(module->protocol->name.data, value[1].data) == 0)
0606         {
0607             cscf->protocol = module->protocol;
0608 
0609             return NGX_CONF_OK;
0610         }
0611     }
0612 
0613     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0614                        "unknown protocol \"%V\"", &value[1]);
0615     return NGX_CONF_ERROR;
0616 }
0617 
0618 
0619 static char *
0620 ngx_mail_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0621 {
0622     ngx_mail_core_srv_conf_t  *cscf = conf;
0623 
0624     return ngx_log_set_log(cf, &cscf->error_log);
0625 }
0626 
0627 
0628 static char *
0629 ngx_mail_core_resolver(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0630 {
0631     ngx_mail_core_srv_conf_t  *cscf = conf;
0632 
0633     ngx_str_t  *value;
0634 
0635     value = cf->args->elts;
0636 
0637     if (cscf->resolver != NGX_CONF_UNSET_PTR) {
0638         return "is duplicate";
0639     }
0640 
0641     if (ngx_strcmp(value[1].data, "off") == 0) {
0642         cscf->resolver = NULL;
0643         return NGX_CONF_OK;
0644     }
0645 
0646     cscf->resolver = ngx_resolver_create(cf, &value[1], cf->args->nelts - 1);
0647     if (cscf->resolver == NULL) {
0648         return NGX_CONF_ERROR;
0649     }
0650 
0651     return NGX_CONF_OK;
0652 }
0653 
0654 
0655 char *
0656 ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0657 {
0658     char  *p = conf;
0659 
0660     ngx_str_t    *c, *value;
0661     ngx_uint_t    i;
0662     ngx_array_t  *a;
0663 
0664     a = (ngx_array_t *) (p + cmd->offset);
0665 
0666     value = cf->args->elts;
0667 
0668     for (i = 1; i < cf->args->nelts; i++) {
0669         c = ngx_array_push(a);
0670         if (c == NULL) {
0671             return NGX_CONF_ERROR;
0672         }
0673 
0674         *c = value[i];
0675     }
0676 
0677     return NGX_CONF_OK;
0678 }