static char * ngx_http_statsd_set_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_statsd_conf_t *ulcf = conf; ngx_str_t *value; ngx_url_t u; value = cf->args->elts; if (ngx_strcmp(value[1].data, "off") == 0) { ulcf->off = 1; return NGX_CONF_OK; } ulcf->off = 0; ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; u.default_port = STATSD_DEFAULT_PORT; u.no_resolve = 0; if(ngx_parse_url(cf->pool, &u) != NGX_OK) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V: %s", &u.host, u.err); return NGX_CONF_ERROR; } ulcf->endpoint = ngx_http_statsd_add_endpoint(cf, &u.addrs[0]); if(ulcf->endpoint == NULL) { return NGX_CONF_ERROR; } return NGX_CONF_OK; }
// ngx_http_upstream.c:ngx_http_upstream_server static ngx_http_upstream_server_t * ngx_http_parse_upstream_server(const ngx_str_t * url, ngx_conf_t * cf) { ngx_int_t weight = 1; ngx_int_t max_fails = 1; time_t fail_timeout = 10; ngx_url_t u; ngx_memzero(&u, sizeof(ngx_url_t)); u.url = *url; u.default_port = 80; if (NGX_OK != ngx_parse_url(cf->pool, &u)) { return NULL; } ngx_http_upstream_server_t * us = ngx_palloc(cf->pool, sizeof(ngx_http_upstream_server_t)); ngx_memzero(us, sizeof(ngx_http_upstream_server_t)); us->name = u.url; us->addrs = u.addrs; us->naddrs = u.naddrs; us->weight = weight; us->max_fails = max_fails; us->fail_timeout = fail_timeout; return us; }
static char * ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_mysql_test_conf_t *mtcf = conf; ngx_str_t *value; ngx_url_t u; ngx_http_core_loc_conf_t *clcf; clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); clcf->handler = ngx_http_mysql_test_handler; value = cf->args->elts; ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; u.default_port = 3306; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in upstream \"%V\"", u.err, &u.url); } return NGX_CONF_ERROR; } mtcf->peers = u.addrs; mtcf->npeers = u.naddrs; return NGX_CONF_OK; }
static ngx_url_t * ngx_rtmp_notify_parse_url(ngx_conf_t *cf, ngx_str_t *url) { ngx_url_t *u; size_t add; add = 0; u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t)); if (u == NULL) { return NULL; } if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { add = 7; } u->url.len = url->len - add; u->url.data = url->data + add; u->default_port = 80; u->uri_part = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NULL; } return u; }
static char * ngx_http_tfs_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_tfs_main_conf_t *tmcf = conf; ngx_url_t u; ngx_str_t *value, *server_addr; value = cf->args->elts; server_addr = &value[1]; ngx_memzero(&u, sizeof(ngx_url_t)); u.url.len = server_addr->len; u.url.data = server_addr->data; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in tfs \"%V\"", u.err, &u.url); } return NGX_CONF_ERROR; } tmcf->ups_addr = u.addrs; return NGX_CONF_OK; }
static mrb_value ngx_stream_mrb_upstream_set_server(mrb_state *mrb, mrb_value self) { ngx_stream_mruby_upstream_context *ctx = DATA_PTR(self); ngx_url_t u; mrb_value server; ngx_stream_mruby_internal_ctx_t *ictx = mrb->ud; ngx_stream_session_t *s = ictx->s; mrb_get_args(mrb, "o", &server); ngx_memzero(&u, sizeof(ngx_url_t)); u.url.data = (u_char *)RSTRING_PTR(server); u.url.len = RSTRING_LEN(server); u.no_resolve = 1; if (ngx_parse_url(s->connection->pool, &u) != NGX_OK) { if (u.err) { mrb_raisef(mrb, E_RUNTIME_ERROR, "%S in upstream %S", mrb_str_new_cstr(mrb, u.err), server); } } ctx->target->name = u.url; ctx->target->server = u.url; ctx->target->sockaddr = u.addrs[0].sockaddr; ctx->target->socklen = u.addrs[0].socklen; return server; }
static ngx_int_t ngx_http_dyups_check_commands(ngx_array_t *arglist) { ngx_int_t rc; ngx_url_t u; ngx_str_t *value; ngx_pool_t *pool; ngx_uint_t i; ngx_array_t *line; pool = ngx_create_pool(128, ngx_cycle->log); if (pool == NULL) { return NGX_ERROR; } line = arglist->elts; for (i = 0; i < arglist->nelts; i++) { value = line[i].elts; /* TODO */ if (line[i].nelts != 2) { rc = NGX_ERROR; goto finish; } if (value[0].len == 6 && ngx_strncasecmp(value[0].data, (u_char *) "server", 6) != 0) { rc = NGX_ERROR; goto finish; } u.url = value[1]; u.default_port = 80; if (ngx_parse_url(pool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, 0, "%s in upstream \"%V\"", u.err, &u.url); } rc = NGX_ERROR; goto finish; } } rc = NGX_OK; finish: ngx_destroy_pool(pool); return rc; }
/* Parse the 'mongo' directive. */ static char * ngx_http_mongo(ngx_conf_t *cf, ngx_command_t *cmd, void *void_conf) { ngx_str_t *value; ngx_url_t u; ngx_uint_t i; ngx_uint_t start; ngx_http_mongod_server_t *mongod_server; ngx_http_gridfs_loc_conf_t *gridfs_loc_conf; gridfs_loc_conf = void_conf; value = cf->args->elts; gridfs_loc_conf->mongo = value[1]; gridfs_loc_conf->mongods = ngx_array_create(cf->pool, 7, sizeof(ngx_http_mongod_server_t)); if (gridfs_loc_conf->mongods == NULL) { return NULL; } /* If nelts is greater than 3, then the user has specified more than one * setting in the 'mongo' directive. So we assume that we're connecting * to a replica set and that the first string of the directive is the replica * set name. We also start looking for host-port pairs at position 2; otherwise, * we start at position 1. */ if( cf->args->nelts >= 3 ) { gridfs_loc_conf->replset.len = strlen( (char *)(value + 1)->data ); gridfs_loc_conf->replset.data = ngx_pstrdup( cf->pool, value + 1 ); start = 2; } else start = 1; for (i = start; i < cf->args->nelts; i++) { ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[i]; u.default_port = 27017; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in mongo \"%V\"", u.err, &u.url); } return NGX_CONF_ERROR; } mongod_server = ngx_array_push(gridfs_loc_conf->mongods); mongod_server->host = u.host; mongod_server->port = u.port; } return NGX_CONF_OK; }
void ngx_http_clojure_socket_upstream_connect_by_url(ngx_http_clojure_socket_upstream_t *u, ngx_url_t *url) { /*TODO: host name resolve by event driven*/ if (url->addrs == NULL) { if (ngx_parse_url(u->pool, url) != NGX_OK ) { ngx_http_clojure_socket_upstream_connect_handler(u, NGX_HTTP_CLOJURE_SOCKET_ERR_RESOLVE); return; } } u->resolved->host.data = url->host.data; u->resolved->host.len = url->host.len; ngx_http_clojure_socket_upstream_connect(u, (struct sockaddr *)url->sockaddr, url->socklen); }
static ngx_int_t ngx_http_scgi_eval(ngx_http_request_t *r, ngx_http_scgi_loc_conf_t * scf) { ngx_url_t url; ngx_http_upstream_t *u; ngx_memzero(&url, sizeof(ngx_url_t)); if (ngx_http_script_run(r, &url.url, scf->scgi_lengths->elts, 0, scf->scgi_values->elts) == NULL) { return NGX_ERROR; } url.no_resolve = 1; if (ngx_parse_url(r->pool, &url) != NGX_OK) { if (url.err) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s in upstream \"%V\"", url.err, &url.url); } return NGX_ERROR; } if (url.no_port) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no port in upstream \"%V\"", &url.url); return NGX_ERROR; } u = r->upstream; u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if (u->resolved == NULL) { return NGX_ERROR; } if (url.addrs && url.addrs[0].sockaddr) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; u->resolved->host = url.addrs[0].name; } else { u->resolved->host = url.host; u->resolved->port = url.port; } return NGX_OK; }
static char * ngx_rtmp_play_url(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_rtmp_play_app_conf_t *pacf = conf; ngx_str_t url; ngx_url_t *u; size_t add; ngx_str_t *value; value = cf->args->elts; if (ngx_strncasecmp(value[1].data, (u_char *) "http://", 7)) { /* local file */ pacf->root = value[1]; return NGX_CONF_OK; } /* http case */ url = value[1]; add = sizeof("http://") - 1; url.data += add; url.len -= add; u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t)); if (u == NULL) { return NGX_CONF_ERROR; } u->url.len = url.len; u->url.data = url.data; u->default_port = 80; u->uri_part = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } pacf->url = u; return NGX_CONF_OK; }
static char * ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_mail_auth_http_conf_t *ahcf = conf; ngx_str_t *value; ngx_url_t u; value = cf->args->elts; ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; u.default_port = 80; u.uri_part = 1; u.one_addr = 1; if (ngx_strncmp(u.url.data, "http://", 7) == 0) { u.url.len -= 7; u.url.data += 7; } if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in auth_http \"%V\"", u.err, &u.url); } return NGX_CONF_ERROR; } ahcf->peer = u.addrs; if (u.family != AF_UNIX) { ahcf->host_header = u.host; } else { ngx_str_set(&ahcf->host_header, "localhost"); } ahcf->uri = u.uri; if (ahcf->uri.len == 0) { ngx_str_set(&ahcf->uri, "/"); } return NGX_CONF_OK; }
static char * ngx_rtmp_notify_on_event(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_rtmp_notify_app_conf_t *nacf; ngx_str_t *url, *name; ngx_url_t *u; size_t add; ngx_str_t *value; value = cf->args->elts; name = &value[0]; url = &value[1]; add = 0; u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t)); if (u == NULL) { return NGX_CONF_ERROR; } if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { add = 7; } u->url.len = url->len - add; u->url.data = url->data + add; u->default_port = 80; u->uri_part = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } nacf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_notify_module); if (name->len == sizeof("on_play") - 1) { nacf->play_url = u; } else { /* on_publish */ nacf->publish_url = u; } return NGX_CONF_OK; }
static char* ngx_http_radius_set_radius_server( ngx_conf_t *cf, ngx_command_t *cmd, void *conf ) { ngx_http_auth_radius_main_conf_t* mconf = ngx_http_conf_get_module_main_conf( cf, ngx_http_auth_radius_module ); ngx_str_t* value = cf->args->elts; if ( cf->args->nelts != 3 && cf->args->nelts != 4 ) return "invalid value"; ngx_url_t u; ngx_memzero( &u, sizeof(ngx_url_t) ); u.url = value[1]; u.uri_part = 1; u.one_addr = 1; u.default_port = RADIUS_DEFAULT_PORT; if ( ngx_parse_url( cf->pool, &u ) != NGX_OK ) { if ( u.err ) { ngx_conf_log_error( NGX_LOG_EMERG, cf, 0, "%s ngx_http_radius_set_radius_server \"%V\"", u.err, &u.url ); } return "invalid address"; } radius_str_t secret; secret.s = value[2].data; secret.len = value[2].len; mconf->secret.s = secret.s; mconf->secret.len = secret.len; radius_str_t nas_identifier; nas_identifier.s = NULL; nas_identifier.len = 0; if ( cf->args->nelts == 4 ) { nas_identifier.s = value[3].data; nas_identifier.len = value[3].len; } radius_server_t* rs; rs = radius_add_server( u.addrs[0].sockaddr, u.addrs[0].socklen, &secret, &nas_identifier ); rs->logger = radius_logger; return NGX_CONF_OK; }
static char * ngx_http_zm_sso_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) { ngx_http_zm_sso_loc_conf_t *prev = parent; ngx_http_zm_sso_loc_conf_t *conf = child; ngx_str_t host_key; ngx_str_t ssl_client_verify_key; ngx_str_t ssl_client_s_dn_key; ngx_conf_merge_uint_value(conf->type, prev->type, NGX_ZM_SSO_CERTAUTH); ngx_conf_merge_str_value(conf->redirect_url->url, prev->redirect_url->url, "443"); ngx_conf_merge_str_value(conf->redirect_schema, prev->redirect_schema, "https"); conf->redirect_url->no_resolve = 1; conf->redirect_url->one_addr = 1; conf->redirect_url->listen = 1; /* with this option, the ngx_parse_url accepts only port case */ if (ngx_parse_url(cf->pool, conf->redirect_url) != NGX_OK) { return NGX_CONF_ERROR; } if (conf->host_index == NGX_CONF_UNSET) { ngx_str_set(&host_key, "host"); conf->host_index = ngx_http_get_variable_index(cf, &host_key); } if (conf->ssl_client_verify_index == NGX_CONF_UNSET) { ngx_str_set(&ssl_client_verify_key, "ssl_client_verify"); conf->ssl_client_verify_index = ngx_http_get_variable_index(cf, &ssl_client_verify_key); } if (conf->ssl_client_s_dn_index == NGX_CONF_UNSET) { ngx_str_set(&ssl_client_s_dn_key, "ssl_client_s_dn"); conf->ssl_client_s_dn_index = ngx_http_get_variable_index(cf, &ssl_client_s_dn_key); } return NGX_CONF_OK; }
static char * ngx_rtmp_notify_on_record_done(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_rtmp_record_app_conf_t *racf; ngx_str_t *url; ngx_url_t *u; size_t add; ngx_str_t *value; value = cf->args->elts; url = &value[1]; add = 0; u = ngx_pcalloc(cf->pool, sizeof(ngx_url_t)); if (u == NULL) { return NGX_CONF_ERROR; } if (ngx_strncasecmp(url->data, (u_char *) "http://", 7) == 0) { add = 7; } u->url.len = url->len - add; u->url.data = url->data + add; u->default_port = 80; u->uri_part = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_record_module); racf->url = u; return NGX_CONF_OK; }
/** * Parse URL conf parameter */ static char * ngx_http_gettoken_parse_url(ngx_conf_t *cf, ngx_http_gettoken_server_t *server) { ngx_str_t *value; //u_char *p; value = cf->args->elts; ngx_url_t *u = &server->parsed_url; ngx_memzero(u, sizeof(ngx_url_t)); u->host = value[1]; //u->no_resolve = 1; //u->no_port = 1; if (ngx_parse_url(cf->pool, u) != NGX_OK) { //解析uri,如果uri是IP:PORT形式则获取他们,如果是域名www.xxx.com形式,则解析域名 if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "gettoken: %s in server hostname \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } return NGX_CONF_OK; }
static char * ngx_rtmp_relay_push_pull(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value, v, n; ngx_rtmp_relay_app_conf_t *racf; ngx_rtmp_relay_target_t *target, **t; ngx_url_t *u; ngx_uint_t i; u_char *p; value = cf->args->elts; racf = ngx_rtmp_conf_get_module_app_conf(cf, ngx_rtmp_relay_module); t = ngx_array_push(value[0].data[3] == 'h' ? &racf->pushes /* push */ : &racf->pulls /* pull */ ); if (t == NULL) { return NGX_CONF_ERROR; } target = ngx_pcalloc(cf->pool, sizeof(*target)); if (target == NULL) { return NGX_CONF_ERROR; } *t = target; target->tag = &ngx_rtmp_relay_module; target->data = target; u = &target->url; u->default_port = 1935; u->uri_part = 1; u->url = value[1]; if (ngx_strncasecmp(u->url.data, (u_char *) "rtmp://", 7) == 0) { u->url.data += 7; u->url.len -= 7; } if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in url \"%V\"", u->err, &u->url); } return NGX_CONF_ERROR; } value += 2; for (i = 2; i < cf->args->nelts; ++i, ++value) { p = ngx_strlchr(value->data, value->data + value->len, '='); if (p == NULL) { return "key=value expected"; } if (p == value->data + value->len - 1) { continue; } n.data = value->data; n.len = p - value->data; v.data = p + 1; v.len = value->data + value->len - p - 1; #define NGX_RTMP_RELAY_STR_PAR(name, var) \ if (n.len == sizeof(#name) - 1 \ && ngx_strncasecmp(n.data, (u_char *)#name, n.len) == 0) \ { \ target->var = v; \ continue; \ } #define NGX_RTMP_RELAY_NUM_PAR(name, var) \ if (n.len == sizeof(#name) - 1 \ && ngx_strncasecmp(n.data, (u_char *)#name, n.len) == 0) \ { \ target->var = ngx_atoi(v.data, v.len); \ continue; \ } NGX_RTMP_RELAY_STR_PAR(app, app); NGX_RTMP_RELAY_STR_PAR(name, name); NGX_RTMP_RELAY_STR_PAR(tcUrl, tc_url); NGX_RTMP_RELAY_STR_PAR(pageUrl, page_url); NGX_RTMP_RELAY_STR_PAR(swfUrl, swf_url); NGX_RTMP_RELAY_STR_PAR(flashVer, flash_ver); NGX_RTMP_RELAY_STR_PAR(playPath, play_path); NGX_RTMP_RELAY_NUM_PAR(live, live); NGX_RTMP_RELAY_NUM_PAR(start, start); NGX_RTMP_RELAY_NUM_PAR(stop, stop); #undef NGX_RTMP_RELAY_STR_PAR #undef NGX_RTMP_RELAY_NUM_PAR return "unsuppored parameter"; } return NGX_CONF_OK; }
static char *ngx_http_upstream_resolveMK(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_upstream_srv_conf_t *uscf; ngx_http_upstream_resolveMK_srv_conf_t *urcf; ngx_http_upstream_server_t *us; time_t interval; ngx_str_t *value, domain, s; ngx_int_t max_ip; ngx_uint_t retry; ngx_http_upstream_resolveMK_peer_t *paddr; ngx_url_t u; ngx_uint_t i; interval = 10; max_ip = 20; retry = 1; domain.data = NULL; domain.len = 0; uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); /* Just For Padding, upstream { } need it */ if (uscf->servers == NULL) { uscf->servers = ngx_array_create(cf->pool, 1, sizeof(ngx_http_upstream_server_t)); if (uscf->servers == NULL) { return NGX_CONF_ERROR; } } us = ngx_array_push(uscf->servers); if (us == NULL) { return NGX_CONF_ERROR; } ngx_memzero(us, sizeof(ngx_http_upstream_server_t)); urcf = ngx_http_conf_upstream_srv_conf(uscf, ngx_http_upstream_resolveMK_module); uscf->peer.init_upstream = ngx_http_upstream_resolveMK_init; value = cf->args->elts; if (value[1].len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "domain is not given"); return NGX_CONF_ERROR; } domain.data = value[1].data; domain.len = value[1].len; if (ngx_strncmp(value[2].data, "service=", 8) != 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "service is not given"); return NGX_CONF_ERROR; } urcf->resolver_service.len = value[2].len - 8; urcf->resolver_service.data = &value[2].data[8]; for (i = 3; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "interval=", 9) == 0) { s.len = value[i].len - 9; s.data = &value[i].data[9]; interval = ngx_parse_time(&s, 1); if (interval == (time_t) NGX_ERROR) { goto invalid; } continue; } if (ngx_strncmp(value[i].data, "max_ip=", 7) == 0) { max_ip = ngx_atoi(value[i].data + 7, value[i].len - 7); if (max_ip == NGX_ERROR || max_ip < 1) { goto invalid; } continue; } if (ngx_strncmp(value[i].data, "retry_off", 9) == 0) { retry = 0; continue; } goto invalid; } urcf->peers = ngx_pcalloc(cf->pool, max_ip * sizeof(ngx_http_upstream_resolveMK_peer_t)); if (urcf->peers == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "ngx_palloc peers fail"); return NGX_CONF_ERROR; } urcf->resolver_interval = interval; urcf->resolver_domain = domain; urcf->resolver_max_ip = max_ip; urcf->upstream_retry = retry; ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in upstream \"%V\"", u.err, &u.url); } return NGX_CONF_ERROR; } urcf->resolved_num = 0; for (i = 0; i < u.naddrs ; i++) { paddr = &urcf->peers[urcf->resolved_num]; paddr->sockaddr = *(struct sockaddr*)u.addrs[i].sockaddr; paddr->socklen = u.addrs[i].socklen; paddr->name = u.addrs[i].name; urcf->resolved_num++; if (urcf->resolved_num >= urcf->resolver_max_ip) { break; } } /* urcf->resolved_index = 0 */ urcf->resolved_access = ngx_time(); return NGX_CONF_OK; invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; }
static char * ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_mail_core_srv_conf_t *cscf = conf; size_t len, off; in_port_t port; ngx_str_t *value; ngx_url_t u; ngx_uint_t i, m; struct sockaddr *sa; ngx_mail_listen_t *ls; ngx_mail_module_t *module; struct sockaddr_in *sin; ngx_mail_core_main_conf_t *cmcf; #if (NGX_HAVE_INET6) struct sockaddr_in6 *sin6; #endif value = cf->args->elts; ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; u.listen = 1; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in \"%V\" of the \"listen\" directive", u.err, &u.url); } return NGX_CONF_ERROR; } cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); ls = cmcf->listen.elts; for (i = 0; i < cmcf->listen.nelts; i++) { sa = (struct sockaddr *) ls[i].sockaddr; if (sa->sa_family != u.family) { continue; } switch (sa->sa_family) { #if (NGX_HAVE_INET6) case AF_INET6: off = offsetof(struct sockaddr_in6, sin6_addr); len = 16; sin6 = (struct sockaddr_in6 *) sa; port = ntohs(sin6->sin6_port); break; #endif #if (NGX_HAVE_UNIX_DOMAIN) case AF_UNIX: off = offsetof(struct sockaddr_un, sun_path); len = sizeof(((struct sockaddr_un *) sa)->sun_path); port = 0; break; #endif default: /* AF_INET */ off = offsetof(struct sockaddr_in, sin_addr); len = 4; sin = (struct sockaddr_in *) sa; port = ntohs(sin->sin_port); break; } if (ngx_memcmp(ls[i].sockaddr + off, u.sockaddr + off, len) != 0) { continue; } if (port != u.port) { continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate \"%V\" address and port pair", &u.url); return NGX_CONF_ERROR; } ls = ngx_array_push(&cmcf->listen); if (ls == NULL) { return NGX_CONF_ERROR; } ngx_memzero(ls, sizeof(ngx_mail_listen_t)); ngx_memcpy(ls->sockaddr, u.sockaddr, u.socklen); ls->socklen = u.socklen; ls->wildcard = u.wildcard; ls->ctx = cf->ctx; #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) ls->ipv6only = 1; #endif if (cscf->protocol == NULL) { for (m = 0; ngx_modules[m]; m++) { if (ngx_modules[m]->type != NGX_MAIL_MODULE) { continue; } module = ngx_modules[m]->ctx; if (module->protocol == NULL) { continue; } for (i = 0; module->protocol->port[i]; i++) { if (module->protocol->port[i] == u.port) { cscf->protocol = module->protocol; break; } } } } for (i = 2; i < cf->args->nelts; i++) { if (ngx_strcmp(value[i].data, "bind") == 0) { ls->bind = 1; continue; } if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) struct sockaddr *sa; u_char buf[NGX_SOCKADDR_STRLEN]; sa = (struct sockaddr *) ls->sockaddr; if (sa->sa_family == AF_INET6) { if (ngx_strcmp(&value[i].data[10], "n") == 0) { ls->ipv6only = 1; } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) { ls->ipv6only = 0; } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid ipv6only flags \"%s\"", &value[i].data[9]); return NGX_CONF_ERROR; } ls->bind = 1; } else { len = ngx_sock_ntop(sa, ls->socklen, buf, NGX_SOCKADDR_STRLEN, 1); ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "ipv6only is not supported " "on addr \"%*s\", ignored", len, buf); } continue; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "bind ipv6only is not supported " "on this platform"); return NGX_CONF_ERROR; #endif } if (ngx_strcmp(value[i].data, "ssl") == 0) { #if (NGX_MAIL_SSL) ls->ssl = 1; continue; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the \"ssl\" parameter requires " "ngx_mail_ssl_module"); return NGX_CONF_ERROR; #endif } if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) { if (ngx_strcmp(&value[i].data[13], "on") == 0) { ls->so_keepalive = 1; } else if (ngx_strcmp(&value[i].data[13], "off") == 0) { ls->so_keepalive = 2; } else { #if (NGX_HAVE_KEEPALIVE_TUNABLE) u_char *p, *end; ngx_str_t s; end = value[i].data + value[i].len; s.data = value[i].data + 13; p = ngx_strlchr(s.data, end, ':'); if (p == NULL) { p = end; } if (p > s.data) { s.len = p - s.data; ls->tcp_keepidle = ngx_parse_time(&s, 1); if (ls->tcp_keepidle == (time_t) NGX_ERROR) { goto invalid_so_keepalive; } } s.data = (p < end) ? (p + 1) : end; p = ngx_strlchr(s.data, end, ':'); if (p == NULL) { p = end; } if (p > s.data) { s.len = p - s.data; ls->tcp_keepintvl = ngx_parse_time(&s, 1); if (ls->tcp_keepintvl == (time_t) NGX_ERROR) { goto invalid_so_keepalive; } } s.data = (p < end) ? (p + 1) : end; if (s.data < end) { s.len = end - s.data; ls->tcp_keepcnt = ngx_atoi(s.data, s.len); if (ls->tcp_keepcnt == NGX_ERROR) { goto invalid_so_keepalive; } } if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0 && ls->tcp_keepcnt == 0) { goto invalid_so_keepalive; } ls->so_keepalive = 1; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the \"so_keepalive\" parameter accepts " "only \"on\" or \"off\" on this platform"); return NGX_CONF_ERROR; #endif } ls->bind = 1; continue; #if (NGX_HAVE_KEEPALIVE_TUNABLE) invalid_so_keepalive: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid so_keepalive value: \"%s\"", &value[i].data[13]); return NGX_CONF_ERROR; #endif } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the invalid \"%V\" parameter", &value[i]); return NGX_CONF_ERROR; } return NGX_CONF_OK; }
static void ngx_rtmp_auto_push_reconnect(ngx_event_t *ev) { ngx_rtmp_session_t *s = ev->data; ngx_rtmp_auto_push_conf_t *apcf; ngx_rtmp_auto_push_ctx_t *ctx; ngx_int_t *slot; ngx_int_t n; ngx_rtmp_relay_target_t at; u_char path[sizeof("unix:") + NGX_MAX_PATH]; u_char flash_ver[sizeof("APSH ,") + NGX_INT_T_LEN * 2]; u_char play_path[NGX_RTMP_MAX_NAME]; ngx_str_t name; u_char *p; ngx_str_t *u; ngx_pid_t pid; ngx_int_t npushed; ngx_core_conf_t *ccf; ngx_file_info_t fi; ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "auto_push: reconnect"); apcf = (ngx_rtmp_auto_push_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, ngx_rtmp_auto_push_module); ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_auto_push_module); if (ctx == NULL) { return; } name.data = ctx->name; name.len = ngx_strlen(name.data); ngx_memzero(&at, sizeof(at)); ngx_str_set(&at.page_url, "nginx-auto-push"); at.tag = &ngx_rtmp_auto_push_module; if (ctx->args[0]) { at.play_path.data = play_path; at.play_path.len = ngx_snprintf(play_path, sizeof(play_path), "%s?%s", ctx->name, ctx->args) - play_path; } slot = ctx->slots; npushed = 0; for (n = 0; n < NGX_MAX_PROCESSES; ++n, ++slot) { if (n == ngx_process_slot) { continue; } pid = ngx_processes[n].pid; if (pid == 0 || pid == NGX_INVALID_PID) { continue; } if (*slot) { npushed++; continue; } at.data = &ngx_processes[n]; ngx_memzero(&at.url, sizeof(at.url)); u = &at.url.url; p = ngx_snprintf(path, sizeof(path) - 1, "unix:%V/" NGX_RTMP_AUTO_PUSH_SOCKNAME ".%i", &apcf->socket_dir, n); *p = 0; if (ngx_file_info(path + sizeof("unix:") - 1, &fi) != NGX_OK) { ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "auto_push: " ngx_file_info_n " failed: " "slot=%i pid=%P socket='%s'" "url='%V' name='%s'", n, pid, path, u, ctx->name); continue; } u->data = path; u->len = p - path; if (ngx_parse_url(s->connection->pool, &at.url) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "auto_push: auto-push parse_url failed " "url='%V' name='%s'", u, ctx->name); continue; } p = ngx_snprintf(flash_ver, sizeof(flash_ver) - 1, "APSH %i,%i", (ngx_int_t) ngx_process_slot, (ngx_int_t) ngx_pid); at.flash_ver.data = flash_ver; at.flash_ver.len = p - flash_ver; ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "auto_push: connect slot=%i pid=%P socket='%s' name='%s'", n, pid, path, ctx->name); if (ngx_rtmp_relay_push(s, &name, &at) == NGX_OK) { *slot = 1; npushed++; continue; } ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "auto_push: connect failed: slot=%i pid=%P socket='%s'" "url='%V' name='%s'", n, pid, path, u, ctx->name); } ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, ngx_core_module); ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "auto_push: pushed=%i total=%i failed=%i", npushed, ccf->worker_processes, ccf->worker_processes - 1 - npushed); if (ccf->worker_processes == npushed + 1) { return; } /* several workers failed */ slot = ctx->slots; for (n = 0; n < NGX_MAX_PROCESSES; ++n, ++slot) { pid = ngx_processes[n].pid; if (n == ngx_process_slot || *slot == 1 || pid == 0 || pid == NGX_INVALID_PID) { continue; } ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "auto_push: connect failed: slot=%i pid=%P name='%s'", n, pid, ctx->name); } if (!ctx->push_evt.timer_set) { ngx_add_timer(&ctx->push_evt, apcf->push_reconnect); } }
static int ngx_http_lua_socket_udp_setpeername(lua_State *L) { ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; ngx_str_t host; int port; ngx_resolver_ctx_t *rctx, temp; ngx_http_core_loc_conf_t *clcf; int saved_top; int n; u_char *p; size_t len; ngx_url_t url; ngx_int_t rc; ngx_http_lua_loc_conf_t *llcf; ngx_udp_connection_t *uc; int timeout; ngx_http_lua_co_ctx_t *coctx; ngx_http_lua_socket_udp_upstream_t *u; /* * TODO: we should probably accept an extra argument to setpeername() * to allow the user bind the datagram unix domain socket himself, * which is necessary for systems without autobind support. */ n = lua_gettop(L); if (n != 2 && n != 3) { return luaL_error(L, "ngx.socket.udp setpeername: expecting 2 or 3 " "arguments (including the object), but seen %d", n); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "no request found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); luaL_checktype(L, 1, LUA_TTABLE); p = (u_char *) luaL_checklstring(L, 2, &len); host.data = ngx_palloc(r->pool, len + 1); if (host.data == NULL) { return luaL_error(L, "out of memory"); } host.len = len; ngx_memcpy(host.data, p, len); host.data[len] = '\0'; if (n == 3) { port = luaL_checkinteger(L, 3); if (port < 0 || port > 65536) { lua_pushnil(L); lua_pushfstring(L, "bad port number: %d", port); return 2; } } else { /* n == 2 */ port = 0; } lua_rawgeti(L, 1, SOCKET_CTX_INDEX); u = lua_touserdata(L, -1); lua_pop(L, 1); if (u) { if (u->waiting) { lua_pushnil(L); lua_pushliteral(L, "socket busy"); return 2; } if (u->udp_connection.connection) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket reconnect without shutting down"); ngx_http_lua_socket_udp_finalize(r, u); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua reuse socket upstream ctx"); } else { u = lua_newuserdata(L, sizeof(ngx_http_lua_socket_udp_upstream_t)); if (u == NULL) { return luaL_error(L, "out of memory"); } #if 1 lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */ lua_pushcfunction(L, ngx_http_lua_socket_udp_upstream_destroy); lua_setfield(L, -2, "__gc"); lua_setmetatable(L, -2); #endif lua_rawseti(L, 1, SOCKET_CTX_INDEX); } ngx_memzero(u, sizeof(ngx_http_lua_socket_udp_upstream_t)); u->request = r; /* set the controlling request */ llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); u->conf = llcf; uc = &u->udp_connection; uc->log = *r->connection->log; dd("lua peer connection log: %p", &uc->log); lua_rawgeti(L, 1, SOCKET_TIMEOUT_INDEX); timeout = (ngx_int_t) lua_tointeger(L, -1); lua_pop(L, 1); if (timeout > 0) { u->read_timeout = (ngx_msec_t) timeout; } else { u->read_timeout = u->conf->read_timeout; } ngx_memzero(&url, sizeof(ngx_url_t)); url.url.len = host.len; url.url.data = host.data; url.default_port = port; url.no_resolve = 1; if (ngx_parse_url(r->pool, &url) != NGX_OK) { lua_pushnil(L); if (url.err) { lua_pushfstring(L, "failed to parse host name \"%s\": %s", host.data, url.err); } else { lua_pushfstring(L, "failed to parse host name \"%s\"", host.data); } return 2; } u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if (u->resolved == NULL) { return luaL_error(L, "out of memory"); } if (url.addrs && url.addrs[0].sockaddr) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket network address given directly"); u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; u->resolved->host = url.addrs[0].name; } else { u->resolved->host = host; u->resolved->port = (in_port_t) port; } if (u->resolved->sockaddr) { rc = ngx_http_lua_socket_resolve_retval_handler(r, u, L); if (rc == NGX_AGAIN) { return lua_yield(L, 0); } return rc; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); temp.name = host; rctx = ngx_resolve_start(clcf->resolver, &temp); if (rctx == NULL) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "failed to start the resolver"); return 2; } if (rctx == NGX_NO_RESOLVER) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushfstring(L, "no resolver defined to resolve \"%s\"", host.data); return 2; } rctx->name = host; rctx->type = NGX_RESOLVE_A; rctx->handler = ngx_http_lua_socket_resolve_handler; rctx->data = u; rctx->timeout = clcf->resolver_timeout; u->co_ctx = ctx->cur_co_ctx; u->resolved->ctx = rctx; saved_top = lua_gettop(L); coctx = ctx->cur_co_ctx; coctx->cleanup = ngx_http_lua_udp_resolve_cleanup; if (ngx_resolve_name(rctx) != NGX_OK) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket fail to run resolver immediately"); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; u->resolved->ctx = NULL; lua_pushnil(L); lua_pushfstring(L, "%s could not be resolved", host.data); return 2; } if (u->waiting == 1) { /* resolved and already connecting */ return lua_yield(L, 0); } n = lua_gettop(L) - saved_top; if (n) { /* errors occurred during resolving or connecting * or already connected */ return n; } /* still resolving */ u->waiting = 1; u->prepare_retvals = ngx_http_lua_socket_resolve_retval_handler; coctx->data = u; if (ctx->entered_content_phase) { r->write_event_handler = ngx_http_lua_content_wev_handler; } else { r->write_event_handler = ngx_http_core_run_phases; } return lua_yield(L, 0); }
static ngx_int_t ngx_rtmp_notify_publish_handle(ngx_rtmp_session_t *s, void *arg, ngx_chain_t *in) { ngx_rtmp_publish_t *v = arg; ngx_int_t rc; ngx_str_t local_name; ngx_rtmp_relay_target_t target; ngx_url_t *u; ngx_rtmp_notify_app_conf_t *nacf; u_char name[NGX_RTMP_MAX_NAME]; static ngx_str_t location = ngx_string("location"); rc = ngx_rtmp_notify_parse_http_retcode(s, in); if (rc == NGX_ERROR) { ngx_rtmp_notify_clear_flag(s, NGX_RTMP_NOTIFY_PUBLISHING); return NGX_ERROR; } if (rc != NGX_AGAIN) { goto next; } /* HTTP 3xx */ ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0, "notify: publish redirect received"); rc = ngx_rtmp_notify_parse_http_header(s, in, &location, name, sizeof(name) - 1); if (rc <= 0) { goto next; } if (ngx_strncasecmp(name, (u_char *) "rtmp://", 7)) { *ngx_cpymem(v->name, name, rc) = 0; ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, "notify: publish redirect to '%s'", v->name); goto next; } /* push */ nacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_notify_module); if (nacf->relay_redirect) { ngx_rtmp_notify_set_name(v->name, NGX_RTMP_MAX_NAME, name, (size_t) rc); } ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, "notify: push '%s' to '%*s'", v->name, rc, name); local_name.data = v->name; local_name.len = ngx_strlen(v->name); ngx_memzero(&target, sizeof(target)); u = &target.url; u->url = local_name; u->url.data = name + 7; u->url.len = rc - 7; u->default_port = 1935; u->uri_part = 1; u->no_resolve = 1; /* want ip here */ if (ngx_parse_url(s->connection->pool, u) != NGX_OK) { ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, "notify: push failed '%V'", &local_name); return NGX_ERROR; } ngx_rtmp_relay_push(s, &local_name, &target); next: return next_publish(s, v); }
static ngx_int_t ngx_http_proxy_connect_eval(ngx_http_request_t *r, ngx_http_proxy_connect_ctx_t *ctx, ngx_http_proxy_connect_loc_conf_t *plcf) { u_char *p; ngx_url_t url; ngx_http_upstream_t *u; u = r->upstream; u->schema.data = (u_char*)"CONNECT"; u->schema.len = sizeof("CONNECT") - 1; ngx_memzero(&url, sizeof(ngx_url_t)); url.url.len = r->host_end - r->host_start + (r->port_start ? r->port_end - r->host_end : 0); url.url.data = r->host_start; url.default_port = 443; url.uri_part = 1; url.no_resolve = 1; if (ngx_parse_url(r->pool, &url) != NGX_OK) { if (url.err) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s in upstream \"%V\"", url.err, &url.url); } return NGX_ERROR; } if (url.uri.len) { if (url.uri.data[0] == '?') { p = ngx_pnalloc(r->pool, url.uri.len + 1); if (p == NULL) { return NGX_ERROR; } *p++ = '/'; ngx_memcpy(p, url.uri.data, url.uri.len); url.uri.len++; url.uri.data = p - 1; } } u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if (u->resolved == NULL) { return NGX_ERROR; } if (url.addrs && url.addrs[0].sockaddr) { u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; u->resolved->host = url.addrs[0].name; } else { u->resolved->host = url.host; u->resolved->port = (in_port_t) (url.no_port ? 443 : url.port); u->resolved->no_port = url.no_port; } return NGX_OK; }
static char * ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_mail_core_srv_conf_t *cscf = conf; ngx_str_t *value; ngx_url_t u; ngx_uint_t i, m; ngx_mail_listen_t *ls; ngx_mail_module_t *module; ngx_mail_core_main_conf_t *cmcf; cscf->listen = 1; value = cf->args->elts; ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; u.listen = 1; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in \"%V\" of the \"listen\" directive", u.err, &u.url); } return NGX_CONF_ERROR; } cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); ls = cmcf->listen.elts; for (i = 0; i < cmcf->listen.nelts; i++) { if (ngx_cmp_sockaddr(&ls[i].sockaddr.sockaddr, ls[i].socklen, (struct sockaddr *) &u.sockaddr, u.socklen, 1) != NGX_OK) { continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate \"%V\" address and port pair", &u.url); return NGX_CONF_ERROR; } ls = ngx_array_push(&cmcf->listen); if (ls == NULL) { return NGX_CONF_ERROR; } ngx_memzero(ls, sizeof(ngx_mail_listen_t)); ngx_memcpy(&ls->sockaddr.sockaddr, &u.sockaddr, u.socklen); ls->socklen = u.socklen; ls->backlog = NGX_LISTEN_BACKLOG; ls->wildcard = u.wildcard; ls->ctx = cf->ctx; #if (NGX_HAVE_INET6) ls->ipv6only = 1; #endif if (cscf->protocol == NULL) { for (m = 0; cf->cycle->modules[m]; m++) { if (cf->cycle->modules[m]->type != NGX_MAIL_MODULE) { continue; } module = cf->cycle->modules[m]->ctx; if (module->protocol == NULL) { continue; } for (i = 0; module->protocol->port[i]; i++) { if (module->protocol->port[i] == u.port) { cscf->protocol = module->protocol; break; } } } } for (i = 2; i < cf->args->nelts; i++) { if (ngx_strcmp(value[i].data, "bind") == 0) { ls->bind = 1; continue; } if (ngx_strncmp(value[i].data, "backlog=", 8) == 0) { ls->backlog = ngx_atoi(value[i].data + 8, value[i].len - 8); ls->bind = 1; if (ls->backlog == NGX_ERROR || ls->backlog == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid backlog \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) { #if (NGX_HAVE_INET6 && defined IPV6_V6ONLY) size_t len; u_char buf[NGX_SOCKADDR_STRLEN]; if (ls->sockaddr.sockaddr.sa_family == AF_INET6) { if (ngx_strcmp(&value[i].data[10], "n") == 0) { ls->ipv6only = 1; } else if (ngx_strcmp(&value[i].data[10], "ff") == 0) { ls->ipv6only = 0; } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid ipv6only flags \"%s\"", &value[i].data[9]); return NGX_CONF_ERROR; } ls->bind = 1; } else { len = ngx_sock_ntop(&ls->sockaddr.sockaddr, ls->socklen, buf, NGX_SOCKADDR_STRLEN, 1); ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "ipv6only is not supported " "on addr \"%*s\", ignored", len, buf); } continue; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "bind ipv6only is not supported " "on this platform"); return NGX_CONF_ERROR; #endif } if (ngx_strcmp(value[i].data, "ssl") == 0) { #if (NGX_MAIL_SSL) ls->ssl = 1; continue; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the \"ssl\" parameter requires " "ngx_mail_ssl_module"); return NGX_CONF_ERROR; #endif } if (ngx_strncmp(value[i].data, "so_keepalive=", 13) == 0) { if (ngx_strcmp(&value[i].data[13], "on") == 0) { ls->so_keepalive = 1; } else if (ngx_strcmp(&value[i].data[13], "off") == 0) { ls->so_keepalive = 2; } else { #if (NGX_HAVE_KEEPALIVE_TUNABLE) u_char *p, *end; ngx_str_t s; end = value[i].data + value[i].len; s.data = value[i].data + 13; p = ngx_strlchr(s.data, end, ':'); if (p == NULL) { p = end; } if (p > s.data) { s.len = p - s.data; ls->tcp_keepidle = ngx_parse_time(&s, 1); if (ls->tcp_keepidle == (time_t) NGX_ERROR) { goto invalid_so_keepalive; } } s.data = (p < end) ? (p + 1) : end; p = ngx_strlchr(s.data, end, ':'); if (p == NULL) { p = end; } if (p > s.data) { s.len = p - s.data; ls->tcp_keepintvl = ngx_parse_time(&s, 1); if (ls->tcp_keepintvl == (time_t) NGX_ERROR) { goto invalid_so_keepalive; } } s.data = (p < end) ? (p + 1) : end; if (s.data < end) { s.len = end - s.data; ls->tcp_keepcnt = ngx_atoi(s.data, s.len); if (ls->tcp_keepcnt == NGX_ERROR) { goto invalid_so_keepalive; } } if (ls->tcp_keepidle == 0 && ls->tcp_keepintvl == 0 && ls->tcp_keepcnt == 0) { goto invalid_so_keepalive; } ls->so_keepalive = 1; #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the \"so_keepalive\" parameter accepts " "only \"on\" or \"off\" on this platform"); return NGX_CONF_ERROR; #endif } ls->bind = 1; continue; #if (NGX_HAVE_KEEPALIVE_TUNABLE) invalid_so_keepalive: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid so_keepalive value: \"%s\"", &value[i].data[13]); return NGX_CONF_ERROR; #endif } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the invalid \"%V\" parameter", &value[i]); return NGX_CONF_ERROR; } return NGX_CONF_OK; }
/** * @brief nginx module's set server * * We set the server configuration here. We should introduce a valid url, to the * connection (it will be prepended with tcp://), the type of connection (zmq). * After this, we have two numbers, the first is the number of threads created by * the ZMQ context and the last one is the queue limit for this setting. * * @code{.conf} * log_zmq_server 127.0.0.1:5555 zmq 10 10000; * @endcode * * @param cf A ngx_conf_t pointer to the main nginx configurion * @param cmd A pointer to ngx_commant_t that defines the configuration line * @param conf A pointer to the configuration received * @return A char pointer which represents the status NGX_CONF_ERROR | NGX_CONF_OK * @warning It's important to rearrange this to permit MORE2 arguments and not TAKE4 */ static char * ngx_http_log_zmq_set_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_log_zmq_main_conf_t *bkmc; ngx_http_log_zmq_loc_conf_t *llcf = conf; ngx_http_log_zmq_element_conf_t *lecf; ngx_http_log_zmq_loc_element_conf_t *lelcf; ngx_str_t *value; const unsigned char *kind; ngx_int_t iothreads; ngx_int_t qlen; ngx_url_t u; ngx_log_zmq_server_t *endpoint; char *connection; size_t connlen; size_t zmq_hdlen; bkmc = ngx_http_conf_get_module_main_conf(cf, ngx_http_log_zmq_module); if (cf->cmd_type != NGX_HTTP_MAIN_CONF) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the \"log_zmq_server\" directive can only used in \"http\" context"); return NGX_CONF_ERROR; } if (bkmc == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no \"log_zmq\" main configuration defined"); return NGX_CONF_ERROR; } /* value[0] variable name * value[1] definition name * value[2] server/target * value[3] protocol type * value[4] number of threads * value[5] queue len */ value = cf->args->elts; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): definition \"%V\"", &value[1]); lecf = ngx_http_log_zmq_create_definition(cf, bkmc, &value[1]); if (NULL == lecf) { return NGX_CONF_ERROR; } /* set the location logs to main configuration logs */ llcf->logs_definition = (ngx_array_t *) bkmc->logs; if (lecf->sset == 1) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": \"%V\" was initializated before", &value[1]); return NGX_CONF_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): loc definition \"%V\"", &value[1]); lelcf = ngx_http_log_zmq_create_location_element(cf, llcf, &value[1]); if (NULL == lelcf) { return NGX_CONF_ERROR; } /* create ZMQ context structure */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): create context"); lecf->ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_zmq_ctx_t)); if (NULL == lecf->ctx) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": error creating context \"%V\"", &value[1]); return NGX_CONF_ERROR; } lecf->ctx->log = cf->cycle->log; /* update definition name and cycle log*/ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): set definition name"); lecf->name = ngx_palloc(cf->pool, sizeof(ngx_str_t)); if (lecf->name == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": error setting name \"%V\"", &value[1]); return NGX_CONF_ERROR; } lecf->name->data = ngx_palloc(cf->pool, value[1].len); lecf->name->len = value[1].len; ngx_memcpy(lecf->name->data, value[1].data, value[1].len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): initialize element \"%V\"", &value[1]); lecf->log = cf->cycle->log; lecf->off = 0; /* set the type of protocol TCP|IPC|INPROC */ kind = value[3].data; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): server kind \"%V\"", &value[3]); endpoint = ngx_pcalloc(cf->pool, sizeof(ngx_log_zmq_server_t)); if (endpoint == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": error creating endpoint \"%V\"", &value[1]); return NGX_CONF_ERROR; } if (0 == ngx_strcmp(kind, ZMQ_TCP_KEY)) { endpoint->kind = TCP; } else if (0 == ngx_strcmp(kind, ZMQ_IPC_KEY)) { endpoint->kind = IPC; } else if (0 == ngx_strcmp(kind, ZMQ_INPROC_KEY)) { endpoint->kind = INPROC; } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": invalid ZMQ connection type: %s \"%V\"", kind, &value[1]); return NGX_CONF_ERROR; } /* set the number of threads associated with this context */ iothreads = ngx_atoi(value[4].data, value[4].len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): iothreads \"%V\"", &value[4]); if (iothreads == NGX_ERROR || iothreads <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": invalid I/O threads %d \"%V\"", iothreads, &value[1]); return NGX_CONF_ERROR; } lecf->iothreads = iothreads; /* set the queue size associated with this context */ qlen = ngx_atoi(value[5].data, value[5].len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): queue length \"%V\"", &value[5]); if (qlen == NGX_ERROR || qlen < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": invalid queue size %d \"%V\"", qlen, &value[1]); } lecf->qlen = qlen; /* if the protocol used is TCP, parse it and use nginx parse_url to validate the input */ if (endpoint->kind == TCP) { u.url = value[2]; u.default_port = __get_default_port(endpoint->kind); u.no_resolve = 0; u.listen = 1; if(ngx_parse_url(cf->pool, &u) != NGX_OK) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": invalid server: %s \"%V\"", u.err, &value[1]); return NGX_CONF_ERROR; } endpoint->peer_addr = u.addrs[0]; } else { u.url = value[2]; } /* create a connection based on the protocol type */ switch (endpoint->kind) { case TCP: zmq_hdlen = ZMQ_TCP_HLEN; connlen = u.url.len + zmq_hdlen; connection = (char *) ngx_pcalloc(cf->pool, connlen + 1); ngx_memcpy(connection, ZMQ_TCP_HANDLER, zmq_hdlen); ngx_memcpy(&connection[zmq_hdlen], u.url.data, u.url.len); break; case IPC: zmq_hdlen = ZMQ_IPC_HLEN; connlen = u.url.len + zmq_hdlen; connection = (char *) ngx_pcalloc(cf->pool, connlen + 1); ngx_memcpy(connection, ZMQ_IPC_HANDLER, zmq_hdlen); ngx_memcpy(&connection[zmq_hdlen], u.url.data, u.url.len); break; case INPROC: zmq_hdlen = ZMQ_INPROC_HLEN; connlen = u.url.len + zmq_hdlen; connection = (char *) ngx_pcalloc(cf->pool, connlen + 1); ngx_memcpy(connection, ZMQ_INPROC_HANDLER, zmq_hdlen); ngx_memcpy(&connection[zmq_hdlen], u.url.data, u.url.len); break; default: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": invalid endpoint type \"%V\"", &value[1]); return NGX_CONF_ERROR; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server(): connection %s", connection); if (NULL == connection) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"log_zmq_server\": error creating connection \"%V\"", &value[1]); return NGX_CONF_ERROR; } /* create the final connection endpoint to be used on socket connection */ endpoint->connection = ngx_palloc(cf->pool, sizeof(ngx_str_t)); endpoint->connection->data = ngx_palloc(cf->pool, connlen); endpoint->connection->len = connlen; ngx_memcpy(endpoint->connection->data, connection, connlen); lecf->server = endpoint; /* set the server as done */ lecf->sset = 1; /* by default, the configuration for this location is unmuted */ lelcf->element = (ngx_http_log_zmq_element_conf_t *) lecf; lelcf->off = 0; /* by default, the configuration is unmuted */ llcf->off = 0; ngx_pfree(cf->pool, connection); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "log_zmq: set_server() return OK \"%V\"", &value[1]); return NGX_CONF_OK; }
ngx_stream_upstream_srv_conf_t * ngx_stream_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags) { ngx_uint_t i; ngx_stream_upstream_server_t *us; ngx_stream_upstream_srv_conf_t *uscf, **uscfp; ngx_stream_upstream_main_conf_t *umcf; if (!(flags & NGX_STREAM_UPSTREAM_CREATE)) { if (ngx_parse_url(cf->pool, u) != NGX_OK) { if (u->err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in upstream \"%V\"", u->err, &u->url); } return NULL; } } umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module); uscfp = umcf->upstreams.elts; for (i = 0; i < umcf->upstreams.nelts; i++) { if (uscfp[i]->host.len != u->host.len || ngx_strncasecmp(uscfp[i]->host.data, u->host.data, u->host.len) != 0) { continue; } if ((flags & NGX_STREAM_UPSTREAM_CREATE) && (uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate upstream \"%V\"", &u->host); return NULL; } if ((uscfp[i]->flags & NGX_STREAM_UPSTREAM_CREATE) && !u->no_port) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "upstream \"%V\" may not have port %d", &u->host, u->port); return NULL; } if ((flags & NGX_STREAM_UPSTREAM_CREATE) && !uscfp[i]->no_port) { ngx_log_error(NGX_LOG_WARN, cf->log, 0, "upstream \"%V\" may not have port %d in %s:%ui", &u->host, uscfp[i]->port, uscfp[i]->file_name, uscfp[i]->line); return NULL; } if (uscfp[i]->port != u->port) { continue; } if (flags & NGX_STREAM_UPSTREAM_CREATE) { uscfp[i]->flags = flags; } return uscfp[i]; } uscf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_srv_conf_t)); if (uscf == NULL) { return NULL; } uscf->flags = flags; uscf->host = u->host; uscf->file_name = cf->conf_file->file.name.data; uscf->line = cf->conf_file->line; uscf->port = u->port; uscf->no_port = u->no_port; if (u->naddrs == 1) { uscf->servers = ngx_array_create(cf->pool, 1, sizeof(ngx_stream_upstream_server_t)); if (uscf->servers == NULL) { return NULL; } us = ngx_array_push(uscf->servers); if (us == NULL) { return NULL; } ngx_memzero(us, sizeof(ngx_stream_upstream_server_t)); us->addrs = u->addrs; us->naddrs = 1; } uscfp = ngx_array_push(&umcf->upstreams); if (uscfp == NULL) { return NULL; } *uscfp = uscf; return uscf; }
ngx_rtmpt_proxy_session_t *ngx_rtmpt_proxy_create_session(ngx_http_request_t *r) { ngx_rtmpt_proxy_session_t *session; ngx_peer_connection_t *pc; ngx_rtmpt_proxy_loc_conf_t *plcf; ngx_pool_t *pool = NULL; ngx_url_t url; int rc; plcf = ngx_http_get_module_loc_conf(r, ngx_rtmpt_proxy_module); if (!plcf) { goto error; } pool = ngx_create_pool(4096, plcf->log); if (pool == NULL) { ngx_log_error(NGX_LOG_ERR, plcf->log, 0, "rtmpt/session: cannot create pool for session"); goto error; } session = (ngx_rtmpt_proxy_session_t *) ngx_pcalloc(pool, sizeof(ngx_rtmpt_proxy_session_t)); if (session == NULL) { ngx_log_error(NGX_LOG_ERR, plcf->log, 0, "rtmpt/session: cannot allocate memory for session"); goto error; } session->name.data=NULL; session->name.len=0; ngx_str_set(&session->name, "1234567890123456"); session->name.data = ngx_pstrdup(pool, &session->name); session_name_create(session->name.data,session->name.len); session->log = plcf->log; session->pool = pool; session->sequence = 0; session->on_finish_send = NULL; session->chain_from_http_request = NULL; session->chain_from_nginx = NULL; session->out_pool = NULL; session->interval_check_time=0; session->interval_check_att=0; session->interval_check_count=0; session->interval_position=1; session->created_at = ngx_cached_time->sec; session->http_requests_count = 0; session->bytes_from_http = session->bytes_to_http = 0; session->create_request_ip.data=ngx_pstrdup(pool,&r->connection->addr_text); session->create_request_ip.len=r->connection->addr_text.len; bzero(session->waiting_requests,NGX_RTMPT_PROXY_REQUESTS_DELAY_SIZE*sizeof(ngx_http_request_t *)); session->in_process = 0; put_session_in_hash(session); pc = ngx_pcalloc(pool, sizeof(ngx_peer_connection_t)); if (pc == NULL) { ngx_log_error(NGX_LOG_ERR, plcf->log, 0, "rtmpt/session: cannot allocate for peer connection"); goto error; } ngx_memzero(&url, sizeof(ngx_url_t)); url.url.data = plcf->target.data; url.url.len = plcf->target.len; url.default_port = 1935; url.uri_part = 1; if (ngx_parse_url(pool, &url) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, plcf->log, 0, "rtmpt/session: error [%s] failed to parse server name: %V", url.err, &url.url); goto error; } session->target_url.data=ngx_pstrdup(pool,&url.url); session->target_url.len=url.url.len; ngx_memzero(pc, sizeof(ngx_peer_connection_t)); pc->log = session->log; pc->get = ngx_rtmpt_proxy_session_get_peer; pc->free = ngx_rtmpt_proxy_session_free_peer; pc->sockaddr = url.addrs[0].sockaddr; pc->socklen = url.addrs[0].socklen; pc->name = &url.addrs[0].name; rc = ngx_event_connect_peer(pc); if (rc != NGX_OK && rc != NGX_AGAIN ) { ngx_log_error(NGX_LOG_ERR, plcf->log, 0, "rtmpt/session: error in connect peer"); goto error; } pc->connection->data = session; pc->connection->read->handler = ngx_rtmpt_read_from_rtmp; pc->connection->write->handler = ngx_rtmpt_send_chain_to_rtmp; pc->connection->idle = 0; pc->connection->log = session->log; pc->connection->pool = session->pool; pc->connection->pool->log = session->log; pc->connection->read->log = session->log; pc->connection->write->log = session->log; session->connection = pc->connection; return session; error: if (pool) { ngx_destroy_pool(pool); } return NULL; }
/* * Based on: ngx_http_upstream.c/ngx_http_upstream_server * Copyright (C) Igor Sysoev */ char * ngx_postgres_conf_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value = cf->args->elts; ngx_postgres_upstream_srv_conf_t *pgscf = conf; ngx_postgres_upstream_server_t *pgs; ngx_http_upstream_srv_conf_t *uscf; ngx_url_t u; ngx_uint_t i; dd("entering"); uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); if (pgscf->servers == NULL) { pgscf->servers = ngx_array_create(cf->pool, 4, sizeof(ngx_postgres_upstream_server_t)); if (pgscf->servers == NULL) { dd("returning NGX_CONF_ERROR"); return NGX_CONF_ERROR; } uscf->servers = pgscf->servers; } pgs = ngx_array_push(pgscf->servers); if (pgs == NULL) { dd("returning NGX_CONF_ERROR"); return NGX_CONF_ERROR; } ngx_memzero(pgs, sizeof(ngx_postgres_upstream_server_t)); /* parse the first name:port argument */ ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; u.default_port = 5432; /* PostgreSQL default */ if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "postgres: %s in upstream \"%V\"", u.err, &u.url); } dd("returning NGX_CONF_ERROR"); return NGX_CONF_ERROR; } pgs->addrs = u.addrs; pgs->naddrs = u.naddrs; pgs->port = u.port; /* parse various options */ for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "dbname=", sizeof("dbname=") - 1) == 0) { pgs->dbname.len = value[i].len - (sizeof("dbname=") - 1); pgs->dbname.data = &value[i].data[sizeof("dbname=") - 1]; continue; } if (ngx_strncmp(value[i].data, "user="******"user="******"user="******"user="******"password="******"password="******"password="******"password="******"postgres: invalid parameter \"%V\" in" " \"postgres_server\"", &value[i]); dd("returning NGX_CONF_ERROR"); return NGX_CONF_ERROR; } uscf->peer.init_upstream = ngx_postgres_upstream_init; dd("returning NGX_CONF_OK"); return NGX_CONF_OK; }
static char * ngx_stream_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_stream_upstream_srv_conf_t *uscf = conf; time_t fail_timeout; ngx_str_t *value, s; ngx_url_t u; ngx_int_t weight, max_fails; ngx_uint_t i; ngx_stream_upstream_server_t *us; us = ngx_array_push(uscf->servers); if (us == NULL) { return NGX_CONF_ERROR; } ngx_memzero(us, sizeof(ngx_stream_upstream_server_t)); value = cf->args->elts; weight = 1; max_fails = 1; fail_timeout = 10; for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "weight=", 7) == 0) { if (!(uscf->flags & NGX_STREAM_UPSTREAM_WEIGHT)) { goto not_supported; } weight = ngx_atoi(&value[i].data[7], value[i].len - 7); if (weight == NGX_ERROR || weight == 0) { goto invalid; } continue; } if (ngx_strncmp(value[i].data, "max_fails=", 10) == 0) { if (!(uscf->flags & NGX_STREAM_UPSTREAM_MAX_FAILS)) { goto not_supported; } max_fails = ngx_atoi(&value[i].data[10], value[i].len - 10); if (max_fails == NGX_ERROR) { goto invalid; } continue; } if (ngx_strncmp(value[i].data, "fail_timeout=", 13) == 0) { if (!(uscf->flags & NGX_STREAM_UPSTREAM_FAIL_TIMEOUT)) { goto not_supported; } s.len = value[i].len - 13; s.data = &value[i].data[13]; fail_timeout = ngx_parse_time(&s, 1); if (fail_timeout == (time_t) NGX_ERROR) { goto invalid; } continue; } if (ngx_strcmp(value[i].data, "backup") == 0) { if (!(uscf->flags & NGX_STREAM_UPSTREAM_BACKUP)) { goto not_supported; } us->backup = 1; continue; } if (ngx_strcmp(value[i].data, "down") == 0) { if (!(uscf->flags & NGX_STREAM_UPSTREAM_DOWN)) { goto not_supported; } us->down = 1; continue; } goto invalid; } ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[1]; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in upstream \"%V\"", u.err, &u.url); } return NGX_CONF_ERROR; } if (u.no_port) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no port in upstream \"%V\"", &u.url); return NGX_CONF_ERROR; } us->name = u.url; us->addrs = u.addrs; us->naddrs = u.naddrs; us->weight = weight; us->max_fails = max_fails; us->fail_timeout = fail_timeout; return NGX_CONF_OK; invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; not_supported: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "balancing method does not support parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; }