Example #1
0
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;
}
Example #2
0
// 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;
}
Example #5
0
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;
}
Example #20
0
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;
}
Example #25
0
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;
}
Example #27
0
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;
}
Example #30
0
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;
}