Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.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, m;
0301     ngx_mail_listen_t          *ls;
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 = cmcf->listen.elts;
0327 
0328     for (i = 0; i < cmcf->listen.nelts; i++) {
0329 
0330         if (ngx_cmp_sockaddr(&ls[i].sockaddr.sockaddr, ls[i].socklen,
0331                              (struct sockaddr *) &u.sockaddr, u.socklen, 1)
0332             != NGX_OK)
0333         {
0334             continue;
0335         }
0336 
0337         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0338                            "duplicate \"%V\" address and port pair", &u.url);
0339         return NGX_CONF_ERROR;
0340     }
0341 
0342     ls = ngx_array_push(&cmcf->listen);
0343     if (ls == NULL) {
0344         return NGX_CONF_ERROR;
0345     }
0346 
0347     ngx_memzero(ls, sizeof(ngx_mail_listen_t));
0348 
0349     ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen);
0350 
0351     ls->socklen = u.socklen;
0352     ls->backlog = NGX_LISTEN_BACKLOG;
0353     ls->rcvbuf = -1;
0354     ls->sndbuf = -1;
0355     ls->wildcard = u.wildcard;
0356     ls->ctx = cf->ctx;
0357 
0358 #if (NGX_HAVE_INET6)
0359     ls->ipv6only = 1;
0360 #endif
0361 
0362     if (cscf->protocol == NULL) {
0363         for (m = 0; cf->cycle->modules[m]; m++) {
0364             if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) {
0365                 continue;
0366             }
0367 
0368             module = cf->cycle->modules[m]->ctx;
0369 
0370             if (module->protocol == NULL) {
0371                 continue;
0372             }
0373 
0374             for (i = 0; module->protocol->port[i]; i++) {
0375                 if (module->protocol->port[i] == u.port) {
0376                     cscf->protocol = module->protocol;
0377                     break;
0378                 }
0379             }
0380         }
0381     }
0382 
0383     for (i = 2; i < cf->args->nelts; i++) {
0384 
0385         if (ngx_strcmp(value[i].data, "bind") == 0) {
0386             ls->bind = 1;
0387             continue;
0388         }
0389 
0390         if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) {
0391             ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8);
0392             ls->bind = 1;
0393 
0394             if (ls->backlog == NGX_ERROR || ls->backlog == 0) {
0395                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0396                                    "invalid backlog \"%V\"", &value[i]);
0397                 return NGX_CONF_ERROR;
0398             }
0399 
0400             continue;
0401         }
0402 
0403         if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) {
0404             size.len = value[i].len - 7;
0405             size.data = value[i].data + 7;
0406 
0407             ls->rcvbuf = ngx_parse_size(&size);
0408             ls->bind = 1;
0409 
0410             if (ls->rcvbuf == NGX_ERROR) {
0411                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0412                                    "invalid rcvbuf \"%V\"", &value[i]);
0413                 return NGX_CONF_ERROR;
0414             }
0415 
0416             continue;
0417         }
0418 
0419         if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) {
0420             size.len = value[i].len - 7;
0421             size.data = value[i].data + 7;
0422 
0423             ls->sndbuf = ngx_parse_size(&size);
0424             ls->bind = 1;
0425 
0426             if (ls->sndbuf == NGX_ERROR) {
0427                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0428                                    "invalid sndbuf \"%V\"", &value[i]);
0429                 return NGX_CONF_ERROR;
0430             }
0431 
0432             continue;
0433         }
0434 
0435         if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
0436 #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
0437             size_t  len;
0438             u_char  buf[NGX_SOCKADDR_STRLEN];
0439 
0440             if (ls->sockaddr.sockaddr.sa_family == AF_INET6) {
0441 
0442                 if (ngx_strcmp(&value[i].data[10], "n") == 0) {
0443                     ls->ipv6only = 1;
0444 
0445                 } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) {
0446                     ls->ipv6only = 0;
0447 
0448                 } else {
0449                     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0450                                        "invalid ipv6only flags \"%s\"",
0451                                        &value[i].data[9]);
0452                     return NGX_CONF_ERROR;
0453                 }
0454 
0455                 ls->bind = 1;
0456 
0457             } else {
0458                 len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf,
0459                                     NGX_SOCKADDR_STRLEN, 1);
0460 
0461                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0462                                    "ipv6only is not supported "
0463                                    "on addr \"%*s\", ignored", len, buf);
0464             }
0465 
0466             continue;
0467 #else
0468             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0469                                "bind ipv6only is not supported "
0470                                "on this platform");
0471             return NGX_CONF_ERROR;
0472 #endif
0473         }
0474 
0475         if (ngx_strcmp(value[i].data, "ssl") == 0) {
0476 #if (NGX_MAIL_SSL)
0477             ls->ssl = 1;
0478             continue;
0479 #else
0480             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0481                                "the \"ssl\" parameter requires "
0482                                "ngx_mail_ssl_module");
0483             return NGX_CONF_ERROR;
0484 #endif
0485         }
0486 
0487         if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) {
0488 
0489             if (ngx_strcmp(&value[i].data[13], "on") == 0) {
0490                 ls->so_keepalive = 1;
0491 
0492             } else if (ngx_strcmp(&value[i].data[13], "off") == 0) {
0493                 ls->so_keepalive = 2;
0494 
0495             } else {
0496 
0497 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
0498                 u_char     *p, *end;
0499                 ngx_str_t   s;
0500 
0501                 end = value[i].data + value[i].len;
0502                 s.data = value[i].data + 13;
0503 
0504                 p = ngx_strlchr(s.data, end, ':');
0505                 if (p == NULL) {
0506                     p = end;
0507                 }
0508 
0509                 if (p > s.data) {
0510                     s.len = p - s.data;
0511 
0512                     ls->tcp_keepidle = ngx_parse_time(&s, 1);
0513                     if (ls->tcp_keepidle == (time_t) NGX_ERROR) {
0514                         goto invalid_so_keepalive;
0515                     }
0516                 }
0517 
0518                 s.data = (p < end) ? (p + 1) : end;
0519 
0520                 p = ngx_strlchr(s.data, end, ':');
0521                 if (p == NULL) {
0522                     p = end;
0523                 }
0524 
0525                 if (p > s.data) {
0526                     s.len = p - s.data;
0527 
0528                     ls->tcp_keepintvl = ngx_parse_time(&s, 1);
0529                     if (ls->tcp_keepintvl == (time_t) NGX_ERROR) {
0530                         goto invalid_so_keepalive;
0531                     }
0532                 }
0533 
0534                 s.data = (p < end) ? (p + 1) : end;
0535 
0536                 if (s.data < end) {
0537                     s.len = end - s.data;
0538 
0539                     ls->tcp_keepcnt = ngx_atoi(s.data, s.len);
0540                     if (ls->tcp_keepcnt == NGX_ERROR) {
0541                         goto invalid_so_keepalive;
0542                     }
0543                 }
0544 
0545                 if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0
0546                     && ls->tcp_keepcnt == 0)
0547                 {
0548                     goto invalid_so_keepalive;
0549                 }
0550 
0551                 ls->so_keepalive = 1;
0552 
0553 #else
0554 
0555                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0556                                    "the \"so_keepalive\" parameter accepts "
0557                                    "only \"on\" or \"off\" on this platform");
0558                 return NGX_CONF_ERROR;
0559 
0560 #endif
0561             }
0562 
0563             ls->bind = 1;
0564 
0565             continue;
0566 
0567 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
0568         invalid_so_keepalive:
0569 
0570             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0571                                "invalid so_keepalive value: \"%s\"",
0572                                &value[i].data[13]);
0573             return NGX_CONF_ERROR;
0574 #endif
0575         }
0576 
0577         ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0578                            "the invalid \"%V\" parameter", &value[i]);
0579         return NGX_CONF_ERROR;
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 }