Exemplo n.º 1
0
ngx_int_t
ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
    ngx_str_t *default_type)
{
    ngx_hash_key_t  *type;

    *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
    if (*types == NULL) {
        return NGX_ERROR;
    }

    while (default_type->len) {

        type = ngx_array_push(*types);
        if (type == NULL) {
            return NGX_ERROR;
        }

        type->key = *default_type;
        type->key_hash = ngx_hash_key(default_type->data,
                                      default_type->len);
        type->value = (void *) 4;

        default_type++;
    }

    return NGX_OK;
}
Exemplo n.º 2
0
uint32_t dvt_cache_label_value_id_from_name(dvt_cache_t *cache, uint32_t label_id, ngx_str_t *name)
{
  ngx_uint_t key_hash = ngx_hash_key(name->data, name->len);
  ngx_hash_t *sh = &(((ngx_hash_t *)cache->label_value_ids->elts)[label_id]);
  int64_t r = (uint64_t)ngx_hash_find(sh, key_hash, name->data, name->len) - ARBITRARY_OFFSET_TO_AVOID_PTR_EQ_NULL;
  return (uint32_t)r;
}
Exemplo n.º 3
0
static ngx_str_t *
sc_for_req_get_header_vaule_by_hash(ngx_list_part_t *part,
        u_char *lowcase_key, size_t len)
{
    ngx_uint_t       i, hash;
    ngx_table_elt_t *header;


    hash = ngx_hash_key(lowcase_key, len);

    header = part->elts;
    for (i = 0; /* void */; i++) {

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }

            part = part->next;
            header = part->elts;
            i = 0;
        }

        if (header[i].hash == hash) {
            return &header->value;
        }
    }

    return NULL;
}
static ngx_tcp_virtual_server_t * 
ngx_tcp_websocket_find_virtual_server(ngx_tcp_session_t *s, 
    ngx_tcp_websocket_ctx_t *ctx)
{
    ngx_uint_t                 hash, i;
    ngx_tcp_core_main_conf_t  *cmcf;
    ngx_tcp_virtual_server_t  *vs;

    cmcf = ngx_tcp_get_module_main_conf(s, ngx_tcp_core_module);

    if (ctx->host.len == 0) {
        return NULL;
    }

    hash = ngx_hash_key(ctx->host.data, ctx->host.len);

    vs = cmcf->virtual_servers.elts;
    for (i = 0; i < cmcf->virtual_servers.nelts; i++) {

        if (vs[i].hash != hash) {
            continue;
        }

        if ((vs[i].name.len != ctx->host.len)
                || ngx_memcmp(vs[i].name.data, ctx->host.data,
                              ctx->host.len) != 0){
            continue;
        }

        return &vs[i];
    }

    return NULL;
}
static ngx_int_t
ngx_rtmp_play_leave(ngx_rtmp_session_t *s)
{
    ngx_rtmp_play_ctx_t        *ctx, **pctx;
    ngx_rtmp_play_app_conf_t   *pacf;
    ngx_uint_t                  h;

    ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
                   "play: leave");

    pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module);

    ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
    if (ctx == NULL || !ctx->joined) {
        return NGX_ERROR;
    }

    h = ngx_hash_key(ctx->name, ngx_strlen(ctx->name));
    pctx = &pacf->ctx[h % pacf->nbuckets];

    while (*pctx && *pctx != ctx) {
        pctx = &(*pctx)->next;
    }

    if (*pctx == NULL) {
        return NGX_ERROR;
    }

    *pctx = (*pctx)->next;
    ctx->joined = 0;

    return NGX_OK;
}
Exemplo n.º 6
0
static ngx_int_t 
ngx_tcp_add_virtual_servers(ngx_conf_t *cf, ngx_tcp_core_main_conf_t *cmcf,
    ngx_tcp_listen_t *listen)
{
    ngx_tcp_core_srv_conf_t   *cscf;
    ngx_tcp_virtual_server_t  *vs;

    cscf = listen->conf;
    if (cscf == NULL || cscf->server_name.len == 0) {
        return NGX_OK;
    }

    vs = ngx_array_push(&cmcf->virtual_servers);
    if (vs == NULL) {
        return NGX_ERROR;
    }

    vs->name.len = cscf->server_name.len;
    vs->name.data = cscf->server_name.data;
    vs->hash = ngx_hash_key(vs->name.data, vs->name.len);
    vs->listen = listen;
    vs->ctx = listen->ctx;

    return NGX_OK;
}
static ngx_int_t
ngx_rtmp_play_join(ngx_rtmp_session_t *s)
{
    ngx_rtmp_play_ctx_t        *ctx, **pctx;
    ngx_rtmp_play_app_conf_t   *pacf;
    ngx_uint_t                  h;

    ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
                   "play: join");

    pacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_play_module);

    ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_play_module);
    if (ctx == NULL || ctx->joined) {
        return NGX_ERROR;
    }

    h = ngx_hash_key(ctx->name, ngx_strlen(ctx->name));
    pctx = &pacf->ctx[h % pacf->nbuckets];

    while (*pctx) {
        if (!ngx_strncmp((*pctx)->name, ctx->name, NGX_RTMP_MAX_NAME)) {
            break;
        }
        pctx = &(*pctx)->next;
    }

    ctx->next = *pctx;
    *pctx = ctx;
    ctx->joined = 1;

    return NGX_OK;
}
static ngx_int_t
ngx_http_secure_cookie_md5_number(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data)
{
    u_char                          *last;
    ngx_str_t                        number, val;
    ngx_uint_t                       hash;
    ngx_http_secure_cookie_conf_t   *sclcf;

    sclcf = ngx_http_get_module_loc_conf(r, ngx_http_secure_cookie_module);
    if (sclcf == NULL) {
        goto not_found;
    }

    if (sclcf->md5_number == NULL) {
        goto not_found;
    }

    if (ngx_http_complex_value(r, sclcf->md5_number, &val) != NGX_OK) {
        goto not_found;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "secure cookie md5 number base string: \"%V\"", &val);

    if (val.len == 0) {
        goto not_found;
    }

    hash = ngx_hash_key(val.data, val.len);

    number.len = 32;
    number.data = ngx_pcalloc(r->pool, number.len);
    if (number.data == NULL) {
        goto not_found;
    }

    last = ngx_snprintf(number.data, number.len, "%ud", hash);
    number.len = last - number.data;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "secure cookie md5 number: \"%V\"", &number);

    v->len = number.len;
    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;
    v->data = number.data;

    return NGX_OK;

not_found:

    v->not_found = 1;

    return NGX_OK;
}
Exemplo n.º 9
0
static jlong JNICALL jni_ngx_http_clojure_mem_get_variable(JNIEnv *env, jclass cls,  jlong r, jlong nname, jlong varlenPtr) {
	ngx_http_request_t *req = (ngx_http_request_t *) r;
	ngx_str_t *name = (ngx_str_t *)nname;
	ngx_http_variable_value_t *vp = ngx_http_get_variable(req, name, ngx_hash_key(name->data, name->len));
	if (vp->not_found) {
		return 0;
	}
	*((u_int *)varlenPtr) = vp->len;
	return (uintptr_t)vp;
}
static ngx_int_t
ngx_rtmp_relay_create(ngx_rtmp_session_t *s, ngx_str_t *name,
        ngx_rtmp_relay_target_t *target,
        ngx_rtmp_relay_create_ctx_pt create_publish_ctx,
        ngx_rtmp_relay_create_ctx_pt create_play_ctx)
{
    ngx_rtmp_relay_app_conf_t      *racf;
    ngx_rtmp_relay_ctx_t           *publish_ctx, *play_ctx, **cctx;
    ngx_uint_t                      hash;


    racf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_relay_module);
    if (racf == NULL) {
        return NGX_ERROR;
    }

    play_ctx = create_play_ctx(s, name, target);
    if (play_ctx == NULL) {
        return NGX_ERROR;
    }

    hash = ngx_hash_key(name->data, name->len);
    cctx = &racf->ctx[hash % racf->nbuckets];
    for (; *cctx; cctx = &(*cctx)->next) {
        if ((*cctx)->name.len == name->len
            && !ngx_memcmp(name->data, (*cctx)->name.data, 
                name->len))
        {
            break;
        }
    }

    if (*cctx) {
        play_ctx->publish = (*cctx)->publish;
        play_ctx->next = (*cctx)->play;
        (*cctx)->play = play_ctx;
        return NGX_OK;
    }

    publish_ctx = create_publish_ctx(s, name, target);
    if (publish_ctx == NULL) {
        ngx_rtmp_finalize_session(play_ctx->session);
        return NGX_ERROR;
    }

    publish_ctx->publish = publish_ctx;
    publish_ctx->play = play_ctx;
    play_ctx->publish = publish_ctx;
    *cctx = publish_ctx;

    return NGX_OK;
}
Exemplo n.º 11
0
static ngx_int_t nchan_process_legacy_channel_id(ngx_http_request_t *r, nchan_loc_conf_t *cf, ngx_str_t **ret_id) {
  static ngx_str_t            channel_id_var_name = ngx_string("push_channel_id");
  ngx_uint_t                  key = ngx_hash_key(channel_id_var_name.data, channel_id_var_name.len);
  ngx_http_variable_value_t  *vv = NULL;
  ngx_str_t                  *group = &cf->channel_group;
  ngx_str_t                   tmpid;
  ngx_str_t                  *id;
  size_t                      sz;
  u_char                     *cur;
  nchan_request_ctx_t        *ctx = ngx_http_get_module_ctx(r, nchan_module);
  
  ctx->channel_id_count = 0;
  
  vv = ngx_http_get_variable(r, &channel_id_var_name, key);
  if (vv == NULL || vv->not_found || vv->len == 0) {
    //ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "nchan: the legacy $push_channel_id variable is not set");
    return NGX_ABORT;
  }
  else {
    tmpid.len = vv->len;
    tmpid.data = vv->data;
  }
  
  if(validate_id(r, &tmpid, cf) != NGX_OK) {
    *ret_id = NULL;
    return NGX_DECLINED;
  }
  
  sz = group->len + 1 + tmpid.len;
  if((id = ngx_palloc(r->pool, sizeof(*id) + sz)) == NULL) {
    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "nchan: can't allocate space for legacy channel id");
    *ret_id = NULL;
    return NGX_ERROR;
  }
  id->len = sz;
  id->data = (u_char *)&id[1];
  cur = id->data;
  
  ngx_memcpy(cur, group->data, group->len);
  cur += group->len;
  cur[0]='/';
  cur++;
  ngx_memcpy(cur, tmpid.data, tmpid.len);
  
  ctx->channel_id_count = 1;
  ctx->channel_id[0] = *id;
  
  *ret_id = id;
  return NGX_OK;
}
static ngx_rtmpt_proxy_session_t *get_session_from_hash(u_char *name, ngx_uint_t size) {

   ngx_rtmpt_proxy_session_t    **sessions, *ts; 
   
   int hash=ngx_hash_key(name,size)%RTMPT_HASHMAX;

   sessions = ngx_rtmpt_proxy_sessions_global; 
   
  
   for (ts=sessions[hash];ts;ts=ts->next) {
     if (ts->name.len==size && ngx_strncmp(ts->name.data,name,size)==0) {
        return ts;
     }
   }
   return NULL;
}
Exemplo n.º 13
0
static int
ngx_http_modsecurity_save_headers_in_visitor(void *data, const char *key, const char *value)
{
    ngx_http_request_t         *r = data;
    ngx_table_elt_t            *h;
    ngx_http_header_t          *hh;
    ngx_http_core_main_conf_t  *cmcf;

    h = ngx_list_push(&r->headers_in.headers);
    if (h == NULL) {
        return 0;
    }

    h->key.data = (u_char *)key;
    h->key.len = ngx_strlen(key);

    h->value.data = (u_char *)value;
    h->value.len = ngx_strlen(value);

    h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);

    if (h->lowcase_key == NULL) {
        return 0;
    }

    ngx_strlow(h->lowcase_key, h->key.data, h->key.len);

    h->hash = ngx_hash_key(h->lowcase_key, h->key.len);

    cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

    hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
                       h->lowcase_key, h->key.len);

    if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
        return 0;
    }

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "ModSecurity: save headers in: \"%V: %V\"",
                   &h->key, &h->value);

    return 1;
}
static void put_session_in_hash(ngx_rtmpt_proxy_session_t *session) {

   ngx_rtmpt_proxy_session_t    **sessions, *ts=NULL, *cs=NULL;
   
   int hash=ngx_hash_key(session->name.data,session->name.len)%RTMPT_HASHMAX;
   
   sessions = ngx_rtmpt_proxy_sessions_global; 
	
   if (!sessions[hash]) {
      sessions[hash]=session;
      return;
   }
   for (ts=sessions[hash];ts;ts=ts->next) {
     cs=ts;
   }
   
   cs->next=session;
   session->prev=cs;
}
static const char *
ngx_rtmp_control_walk_app(ngx_http_request_t *r,
    ngx_rtmp_core_app_conf_t *cacf)
{
    size_t                     len;
    ngx_str_t                  name;
    const char                *s;
    ngx_uint_t                 n;
    ngx_rtmp_live_stream_t    *ls;
    ngx_rtmp_live_app_conf_t  *lacf;

    lacf = cacf->app_conf[ngx_rtmp_live_module.ctx_index];

    if (ngx_http_arg(r, (u_char *) "name", sizeof("name") - 1, &name) != NGX_OK)
    {
        for (n = 0; n < (ngx_uint_t) lacf->nbuckets; ++n) {
            for (ls = lacf->streams[n]; ls; ls = ls->next) {
                s = ngx_rtmp_control_walk_stream(r, ls);
                if (s != NGX_CONF_OK) {
                    return s;
                }
            }
        }

        return NGX_CONF_OK;
    }

    for (ls = lacf->streams[ngx_hash_key(name.data, name.len) % lacf->nbuckets];
         ls; ls = ls->next)
    {
        len = ngx_strlen(ls->name);
        if (name.len != len || ngx_strncmp(name.data, ls->name, name.len)) {
            continue;
        }

        s = ngx_rtmp_control_walk_stream(r, ls);
        if (s != NGX_CONF_OK) {
            return s;
        }
    }

    return NGX_CONF_OK;
}
Exemplo n.º 16
0
static int
ngx_http_modsecurity_save_headers_out_visitor(void *data, const char *key, const char *value)
{
    ngx_http_request_t             *r = data;
    ngx_table_elt_t                *h, he;
    ngx_http_upstream_header_t     *hh;
    ngx_http_upstream_main_conf_t  *umcf;

    umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);

    h = &he;

    h->key.data = (u_char *)key;
    h->key.len = ngx_strlen(key);

    h->value.data = (u_char *)value;
    h->value.len = ngx_strlen(value);

    h->lowcase_key = ngx_palloc(r->pool, h->key.len);
    if (h->lowcase_key == NULL) {
        return 0;
    }

    ngx_strlow(h->lowcase_key, h->key.data, h->key.len);

    h->hash = ngx_hash_key(h->lowcase_key, h->key.len);

    hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
                       h->lowcase_key, h->key.len);

    if (hh) {
        /* copy all */
        if (hh->copy_handler(r, h, hh->conf) != NGX_OK) {
            return 0;
        }
    }

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "ModSecurity: save headers out: \"%V: %V\"",
                   &h->key, &h->value);

    return 1;
}
Exemplo n.º 17
0
static void 
request_known_headers_calc_hash (void)
{
    static ngx_int_t         is_calc_request_hash = 0;
    request_known_headers_t *header;

    if (is_calc_request_hash) {
        return;
    }

    is_calc_request_hash = 1;

    header = request_known_headers;

    while (header->name.len != 0) {
        header->hash = ngx_hash_key(header->name.data, header->name.len);

        header++;
    }
}
static void remove_session_from_hash(u_char *name, ngx_uint_t size) {
    ngx_rtmpt_proxy_session_t    **sessions, *ts=NULL;
	
    int hash=ngx_hash_key(name,size)%RTMPT_HASHMAX;
	
	sessions = ngx_rtmpt_proxy_sessions_global; 
	
    for (ts=sessions[hash];ts;ts=ts->next) {
     if (ts->name.len==size && ngx_strncmp(ts->name.data,name,size)==0) {
        
        if (ts->next) {
           ts->next->prev=ts->prev;
        }
        if (ts->prev) {
           ts->prev->next=ts->next;
        }
        if (ts == sessions[hash]) {
           sessions[hash]=ts->next;
        }
        return;
     }
   }
   return;
}
Exemplo n.º 19
0
static ngx_int_t
ngx_http_find_virtual_server(ngx_connection_t *c,
    ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
    ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp)
{
    ngx_http_core_srv_conf_t  *cscf;

    if (virtual_names == NULL) {
        return NGX_DECLINED;
    }

    cscf = ngx_hash_find_combined(&virtual_names->names,
                                  ngx_hash_key(host->data, host->len),
                                  host->data, host->len);

    if (cscf) {
        *cscfp = cscf;
        return NGX_OK;
    }

#if (NGX_PCRE)

    if (host->len && virtual_names->nregex) {
        ngx_int_t                n;
        ngx_uint_t               i;
        ngx_http_server_name_t  *sn;

        sn = virtual_names->regex;

#if (NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME)

        if (r == NULL) {
            ngx_http_connection_t  *hc;

            for (i = 0; i < virtual_names->nregex; i++) {

                n = ngx_regex_exec(sn[i].regex->regex, host, NULL, 0);

                if (n == NGX_REGEX_NO_MATCHED) {
                    continue;
                }

                if (n >= 0) {
                    hc = c->data;
                    hc->ssl_servername_regex = sn[i].regex;

                    *cscfp = sn[i].server;
                    return NGX_OK;
                }

                ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                              ngx_regex_exec_n " failed: %i "
                              "on \"%V\" using \"%V\"",
                              n, host, &sn[i].regex->name);

                return NGX_ERROR;
            }

            return NGX_DECLINED;
        }

#endif /* NGX_HTTP_SSL && defined SSL_CTRL_SET_TLSEXT_HOSTNAME */

        for (i = 0; i < virtual_names->nregex; i++) {

            n = ngx_http_regex_exec(r, sn[i].regex, host);

            if (n == NGX_DECLINED) {
                continue;
            }

            if (n == NGX_OK) {
                *cscfp = sn[i].server;
                return NGX_OK;
            }

            return NGX_ERROR;
        }
    }

#endif /* NGX_PCRE */

    return NGX_DECLINED;
}
Exemplo n.º 20
0
static ngx_inline ngx_int_t
ngx_http_modsecurity_load_headers_out(ngx_http_request_t *r)
{

    ngx_http_modsecurity_ctx_t  *ctx;
    char                        *data;
    request_rec                 *req;
    u_char                      *content_type;
    ngx_uint_t                   content_type_len;
    ngx_http_variable_value_t   *vv;
    ngx_list_part_t             *part;
    ngx_table_elt_t             *h;
    ngx_uint_t                   i;
    char                        *key, *value;
    u_char                      *buf = NULL;
    size_t                       size = 0;

    ctx = ngx_http_get_module_ctx(r, ngx_http_modsecurity);
    req = ctx->req;

    req->status = r->headers_out.status;
    req->status_line = (char *)ngx_pstrdup0(r->pool, &r->headers_out.status_line);

    if (r->headers_out.charset.len) {

        content_type_len = r->headers_out.content_type.len
                           + r->headers_out.charset.len
                           + ngx_strlen("; charset=") + 1;

        content_type = ngx_palloc(r->pool, content_type_len);

        if (content_type == NULL) {
            return NGX_ERROR;
        }

        ngx_snprintf(content_type, content_type_len,
                     "%V; charset=%V%Z",
                     &r->headers_out.content_type,
                     &r->headers_out.charset);

        r->headers_out.content_type.data = content_type;
        r->headers_out.content_type.len = content_type_len;
    }

    /* deep copy */
    part = &r->headers_out.headers.part;
    h = part->elts;

    for (i = 0; ; i++) {
        if (i >= part->nelts) {
            if (part->next == NULL)
                break;

            part = part->next;
            h = part->elts;
            i = 0;
        }
        size += h[i].key.len + h[i].value.len + 2;

        buf = ngx_palloc(r->pool, size);

        if (buf == NULL) {
            return NGX_ERROR;
        }

        key = (char *)buf;
        buf = ngx_cpymem(buf, h[i].key.data, h[i].key.len);
        *buf++ = '\0';

        value = (char *)buf;
        buf = ngx_cpymem(buf, h[i].value.data, h[i].value.len);
        *buf++ = '\0';

        apr_table_addn(req->headers_out, key, value);
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "ModSecurity: load headers out: \"%V: %V\"",
                       &h[i].key, &h[i].value);

    }

    for (i = 0; special_headers_out[i].name; i++) {

        vv = ngx_http_get_variable(r, &special_headers_out[i].variable_name,
                                   ngx_hash_key(special_headers_out[i].variable_name.data,
                                                special_headers_out[i].variable_name.len));

        if (vv && !vv->not_found) {

            data = ngx_palloc(r->pool, vv->len + 1);
            if (data == NULL) {
                return NGX_ERROR;
            }

            ngx_memcpy(data,vv->data, vv->len);
            data[vv->len] = '\0';

            apr_table_setn(req->headers_out, special_headers_out[i].name, data);
            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "ModSecurity: load headers out: \"%s: %s\"",
                           special_headers_out[i].name, data);
        }
    }

    req->content_type = apr_table_get(ctx->req->headers_out, "Content-Type");
    req->content_encoding = apr_table_get(ctx->req->headers_out, "Content-Encoding");

    data = (char *)apr_table_get(ctx->req->headers_out, "Content-Languages");

    if(data != NULL)
    {
        ctx->req->content_languages = apr_array_make(ctx->req->pool, 1, sizeof(const char *));
        *(const char **)apr_array_push(ctx->req->content_languages) = data;
    }

    /* req->chunked = r->chunked; may be useless */
    req->clength = r->headers_out.content_length_n;
    req->mtime = apr_time_make(r->headers_out.last_modified_time, 0);

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "ModSecurity: load headers out done");

    return NGX_OK;
}
static ngx_int_t
ngx_rtmp_control_record(ngx_http_request_t *r, ngx_str_t *method)
{
    ngx_rtmp_record_app_conf_t     *racf;
    ngx_rtmp_core_main_conf_t      *cmcf;
    ngx_rtmp_core_srv_conf_t      **pcscf, *cscf;
    ngx_rtmp_core_app_conf_t      **pcacf, *cacf;
    ngx_rtmp_live_app_conf_t       *lacf;
    ngx_rtmp_live_stream_t         *ls;
    ngx_rtmp_live_ctx_t            *lctx;
    ngx_rtmp_session_t             *s;
    ngx_chain_t                     cl;
    ngx_uint_t                      sn, rn, n;
    ngx_str_t                       srv, app, rec, name, path;
    ngx_str_t                       msg;
    ngx_buf_t                      *b;
    ngx_int_t                       rc;
    size_t                          len;

    sn = 0;
    if (ngx_http_arg(r, (u_char *) "srv", sizeof("srv") - 1, &srv) == NGX_OK) {
        sn = ngx_atoi(srv.data, srv.len);
    }

    if (ngx_http_arg(r, (u_char *) "app", sizeof("app") - 1, &app) != NGX_OK) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      "rtmp_control: app not specified");
        ngx_str_set(&msg, "Application not specified");
        goto error;
    }

    ngx_memzero(&rec, sizeof(rec));
    ngx_http_arg(r, (u_char *) "rec", sizeof("rec") - 1, &rec);

    ngx_memzero(&name, sizeof(name));
    ngx_http_arg(r, (u_char *) "name", sizeof("name") - 1, &name);

    cmcf = ngx_rtmp_core_main_conf;
    if (cmcf == NULL) {
        ngx_str_set(&msg, "Missing main RTMP conf");
        goto error;
    }

    /* find server */
    if (sn >= cmcf->servers.nelts) {
        ngx_str_set(&msg, "Server index out of range");
        goto error;
    }

    pcscf = cmcf->servers.elts;
    pcscf += sn;
    cscf = *pcscf;

    /* find application */
    pcacf = cscf->applications.elts;
    cacf = NULL;

    for (n = 0; n < cscf->applications.nelts; ++n, ++pcacf) {
        if ((*pcacf)->name.len == app.len &&
            ngx_strncmp((*pcacf)->name.data, app.data, app.len) == 0)
        {
            cacf = *pcacf;
            break;
        }
    }

    if (cacf == NULL) {
        ngx_str_set(&msg, "Application not found");
        goto error;
    }

    lacf = cacf->app_conf[ngx_rtmp_live_module.ctx_index];
    racf = cacf->app_conf[ngx_rtmp_record_module.ctx_index];

    /* find live stream by name */
    for (ls = lacf->streams[ngx_hash_key(name.data, name.len) % lacf->nbuckets];
         ls; ls = ls->next) 
    {
        len = ngx_strlen(ls->name);

        if (name.len == len && ngx_strncmp(name.data, ls->name, name.len)
                                == 0)
        {
            break;
        }
    }

    if (ls == NULL) {
        ngx_str_set(&msg, "Live stream not found");
        goto error;
    }

    /* find publisher context */
    for (lctx = ls->ctx; lctx; lctx = lctx->next) {
        if (lctx->flags & NGX_RTMP_LIVE_PUBLISHING) {
            break;
        }
    }

    if (lctx == NULL) {
        ngx_str_set(&msg, "No publisher");
        goto error;
    }

    s = lctx->session;

    /* find recorder */
    rn = ngx_rtmp_record_find(racf, &rec);
    if (rn == NGX_CONF_UNSET_UINT) {
        ngx_str_set(&msg, "Recorder not found");
        goto error;
    }

    ngx_memzero(&path, sizeof(path));

    if (method->len == sizeof("start") - 1 &&
        ngx_strncmp(method->data, "start", method->len) == 0)
    {
        rc = ngx_rtmp_record_open(s, rn, &path);

    } else if (method->len == sizeof("stop") - 1 &&
               ngx_strncmp(method->data, "stop", method->len) == 0)
    {
        rc = ngx_rtmp_record_close(s, rn, &path);

    } else {
        ngx_str_set(&msg, "Undefined method");
        goto error;
    }

    if (rc == NGX_ERROR) {
        ngx_str_set(&msg, "Recorder error");
        goto error;
    }

    if (rc == NGX_AGAIN) {
        /* already opened/closed */
        ngx_str_null(&path);
        r->header_only = 1;
    }

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = path.len;

    b = ngx_create_temp_buf(r->pool, path.len);
    if (b == NULL) {
        return NGX_ERROR;
    }

    ngx_memzero(&cl, sizeof(cl));
    cl.buf = b;

    b->last = ngx_cpymem(b->pos, path.data, path.len);
    b->last_buf = 1;
    
    ngx_http_send_header(r);

    return ngx_http_output_filter(r, &cl);

error:
    r->headers_out.status = NGX_HTTP_BAD_REQUEST;
    r->headers_out.content_length_n = msg.len;

    b = ngx_calloc_buf(r->pool);
    if (b == NULL) {
        return NGX_ERROR;
    }

    ngx_memzero(&cl, sizeof(cl));
    cl.buf = b;

    b->start = b->pos = msg.data;
    b->end = b->last = msg.data + msg.len;
    b->memory = 1;
    b->last_buf = 1;

    ngx_http_send_header(r);

    return ngx_http_output_filter(r, &cl);
}
Exemplo n.º 22
0
char *
ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    char  *p = conf;

    ngx_array_t     **types;
    ngx_str_t        *value, *default_type;
    ngx_uint_t        i, n, hash;
    ngx_hash_key_t   *type;

    types = (ngx_array_t **) (p + cmd->offset);

    if (*types == (void *) -1) {
        return NGX_CONF_OK;
    }

    default_type = cmd->post;

    if (*types == NULL) {
        *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
        if (*types == NULL) {
            return NGX_CONF_ERROR;
        }

        if (default_type) {
            type = ngx_array_push(*types);
            if (type == NULL) {
                return NGX_CONF_ERROR;
            }

            type->key = *default_type;
            type->key_hash = ngx_hash_key(default_type->data,
                                          default_type->len);
            type->value = (void *) 4;
        }
    }

    value = cf->args->elts;

    for (i = 1; i < cf->args->nelts; i++) {

        if (value[i].len == 1 && value[i].data[0] == '*') {
            *types = (void *) -1;
            return NGX_CONF_OK;
        }

        hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
        value[i].data[value[i].len] = '\0';

        type = (*types)->elts;
        for (n = 0; n < (*types)->nelts; n++) {

            if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
                ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                                   "duplicate MIME type \"%V\"", &value[i]);
                continue;
            }
        }

        type = ngx_array_push(*types);
        if (type == NULL) {
            return NGX_CONF_ERROR;
        }

        type->key = value[i];
        type->key_hash = hash;
        type->value = (void *) 4;
    }

    return NGX_CONF_OK;
}
Exemplo n.º 23
0
/*----------------------------------------------------------------------------*/
ngx_int_t rp_bazaar_cmd_handler(ngx_http_request_t *r)
{
    ngx_http_rp_loc_conf_t *lc;
    rp_bazaar_ctx_t *ctx;
    size_t i = 0;

    ctx = ngx_pcalloc(r->pool, sizeof(rp_bazaar_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }
    ctx->redirect = ngx_pcalloc(r->pool, c_redirect_len);
    if (ctx->redirect == NULL) {
        return NGX_ERROR;
    }
    ctx->json_root = NULL;
    ctx->finalize_on_post_handler = 0;
    ctx->in_buffer = NULL;
    ctx->in_buffer_len = 0;
    ctx->in_status = 0;
    ngx_http_set_ctx(r, ctx, ngx_http_rp_module);

    lc = ngx_http_get_module_loc_conf(r, ngx_http_rp_module);

    /* Just test local directory here - we would need to check it for almost
     * all calls anyway
     */
    if(lc->bazaar_dir.data == NULL) {
        fprintf(stderr, "Bazaar local directory not found\n");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    ctx->json_root = cJSON_CreateObject(r->pool);
    if(ctx->json_root == NULL) {
        fprintf(stderr, "Cannot allocate cJSON object\n");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    /* Bazaar commands */
    for(i = 0; bazaar_cmds[i].name != NULL; i++) {

        ngx_str_t arg_name = { strlen(bazaar_cmds[i].name),
                               (u_char *)bazaar_cmds[i].name };
        ngx_uint_t arg_key = ngx_hash_key(arg_name.data, arg_name.len);
        ngx_http_variable_value_t *arg_val = NULL;

        int rc;
        char **arg_argv = NULL;
        int    arg_argc = 0;

        arg_val = ngx_http_get_variable(r, &arg_name, arg_key);

        /* check validity of the specified http variables
         * note: not all attributes of arg_value are set within ngx_http_get_variable, thus
         * the order of the following checks are important otherwise it could come to the usage
         * of uninitialized value what would lead to invalid processing
         */
        if (!arg_val)                continue;
        if (arg_val->not_found == 1) continue;
        if (arg_val->valid == 0)     continue;

        arg_val->data[arg_val->len] = '\0';
        arg_argc = rp_module_cmd_parse_args((const char *)arg_val->data,
                                            arg_val->len,
                                            &arg_argv);

        fprintf(stderr, "Calling application: %s\n", &bazaar_cmds[i].name[4]);

        /* Install/Remove special case */
        if ( !strncmp(&bazaar_cmds[i].name[4], "install", 7) ||
             !strncmp(&bazaar_cmds[i].name[4], "remove",  6) ) {
            if(arg_argv) {
                for(i = 0; i < (size_t)arg_argc; i++) {
                    if(arg_argv[i]) {
                        free(arg_argv[i]);
                        arg_argv[i] = NULL;
                    }
                }
                free(arg_argv);
            }
            return rp_bazaar_install(r);
        }

        if((rc = bazaar_cmds[i].func(r, &ctx->json_root, arg_argc, arg_argv)) < 0) {
            /* error - fill the output buffer and send it back */
            fprintf(stderr, "Application %s failed: %d\n",
                     bazaar_cmds[i].name, rc);
        }

        if(arg_argv) {
            for(i = 0; i < (size_t)arg_argc; i++) {
                if(arg_argv[i]) {
                    free(arg_argv[i]);
                    arg_argv[i] = NULL;
                }
            }
            free(arg_argv);
        }

        /* Prepare response header & body */
        return rp_module_send_response(r, &ctx->json_root);
    }

    int ret = 0;

    /* Unknown command response */
    if (i >= sizeof(bazaar_cmds)/sizeof(rp_module_cmd_t)) {
        rp_module_cmd_error(&ctx->json_root, "Unknown command.", NULL, r->pool);
        return rp_module_send_response(r, &ctx->json_root);
    }

    /* Default Bazaar entry point - list of applications with versions */
    cJSON *json_tok = NULL;

    char *host = (char *)r->headers_in.server.data;
    char mac[18];
    sprintf(mac, "00:00:00:00:00:00");
    if (rp_bazaar_get_mac("/sys/class/net/eth0/address", mac)) {
        fprintf(stderr, "Cannot obtain MAC address.\n");
    }

    static unsigned long long dna = 0;
    if (!dna || dna == 1) {
		if (rp_bazaar_get_dna(&dna)) {
			fprintf(stderr, "Cannot obtain DNA number.\n");
		}
	}
    char dna_s[64];
    sprintf(dna_s, "%016llx", dna);

    /* Get Ecosystem version */
    char ecoversion[64];
    sprintf(ecoversion, "unknown");
    cJSON *ecoinfo = NULL;
    if (!get_info(&ecoinfo, (const char *)lc->bazaar_dir.data,
                  "", r->pool)) {
        fprintf(stderr, "Cannot obtain Ecosystem version.\n");
    } else {
        if (ecoinfo != NULL) {

            cJSON *j_ver = cJSON_GetObjectItem(ecoinfo, "version");
            if(j_ver == NULL) {
                fprintf(stderr, "Cannot get version from ecoinfo JSON.\n");
            } else {
                strncpy(ecoversion, j_ver->valuestring, sizeof ecoversion);
                cJSON_Delete(j_ver, r->pool);
            }

            cJSON_Delete(ecoinfo, r->pool);
        }
    }

    /* Populate JSON */
    cJSON_AddItemToObject(ctx->json_root, "version",
                          cJSON_CreateString(ecoversion, r->pool),
                          r->pool);

    cJSON_AddItemToObject(ctx->json_root, "dna",
                          cJSON_CreateString(dna_s, r->pool), r->pool);

    cJSON_AddItemToObject(ctx->json_root, "mac",
                          cJSON_CreateString(mac, r->pool), r->pool);

    // TODO: Serial number?

    cJSON_AddItemToObject(ctx->json_root, "host",
                          cJSON_CreateString(host, r->pool),
                          r->pool);

    cJSON *apps_root;
    cJSON_AddItemToObject(ctx->json_root, "apps",
                          apps_root=cJSON_CreateObject(r->pool), r->pool);
    if(apps_root == NULL) {
        fprintf(stderr, "Can not allocate cJSON object\n");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    fprintf(stderr, "Making list of apps\n");

    /* Add the non-verbose list of apps */
    rp_bazaar_app_get_local_list((const char *)lc->bazaar_dir.data,
                                 &apps_root, r->pool, 0);

    /* Issue a POST with JSON defined above to Bazaar server */
    char *js = cJSON_Print(ctx->json_root, r->pool);
    cJSON_Minify(js);

    fprintf(stderr, "Bazaar handshake:\n%s", js);

    char *jse = NULL;
    char *jsp = NULL;
    char *bazaar_dv = NULL;
    const char *c_payload = "payload=";
    const char *c_device = "/device";

    jse = url_encode(js);

    jsp = malloc(strlen(jse) + strlen(c_payload) + 1);
    if (!jsp) {
        fprintf(stderr, "Cannot malloc() payload.\n");
        ret = NGX_HTTP_INTERNAL_SERVER_ERROR;
        goto out;
    }
    sprintf(jsp, "%s%s", c_payload, jse);

    bazaar_dv = (char *)malloc(strlen((char *)lc->bazaar_server.data) +
                               strlen(c_device) + 1);
    if (!bazaar_dv) {
        fprintf(stderr, "Cannot malloc() device.\n");
        ret = NGX_HTTP_INTERNAL_SERVER_ERROR;
        goto out;
    }
    sprintf(bazaar_dv, "%s%s", lc->bazaar_server.data, c_device);
    fprintf(stderr, "post bazaar_dv %s\n", bazaar_dv);

    post_resp_t resp = { NULL, 0 };
    if (post(jsp, bazaar_dv, &resp)) {
        if (resp.data) free(resp.data);
        /* Redirect to Bazaar access error */
        fprintf(stderr, "Cannot access %s.\n", bazaar_dv);
        snprintf(ctx->redirect, c_redirect_len,
                 "http://%s/error_bazaar_access.html", host);
        goto out;
    }

    /* Get token from POST response */
    if (resp.data) {

        fprintf(stderr,"Bazaar handshake response:\n%s", resp.data);

        json_tok = cJSON_Parse(resp.data, r->pool);
        if (!json_tok) {
            /* Redirect to Bazaar protocol error */
            fprintf(stderr,"No JSON found in the following response:\n\"%s\"\n", resp.data);
            snprintf(ctx->redirect, c_redirect_len,
                     "http://%s/error_bazaar_proto.html", host);
        } else {

            cJSON *jtok = cJSON_GetObjectItem(json_tok, "token");

            if (!jtok) {
                /* Redirect to Bazaar protocol error */
                fprintf(stderr, "No token found in the following JSON:\n\"%s\"\n", resp.data);
                snprintf(ctx->redirect, c_redirect_len,
                         "http://%s/error_bazaar_proto.html", host);
            } else {
                /* Redirect to Bazaar with token */
                snprintf(ctx->redirect, c_redirect_len, "%s/token/%s",
                        lc->bazaar_server.data, jtok->valuestring);
                /* Store token for session control */
                strncpy(g_token, jtok->valuestring, c_token_len);
                g_token[c_token_len - 1] = '\0';
            }
        }

        free(resp.data);
    }

 out:
    if (jsp) free(jsp);
    if (jse) free(jse);
    if (bazaar_dv) free(bazaar_dv);
    //TODO: Is ctx->json_root handled by the pool deallocator?
    //if (ctx->json_root) cJSON_Delete(ctx->json_root, r->pool);
    if (json_tok) cJSON_Delete(json_tok, r->pool);

    if (ret) return ret;

    fprintf(stderr, "Redirecting to: %s\n", ctx->redirect);
    return rp_module_redirect(r, ctx->redirect);
}
static ngx_int_t
ngx_rtmp_relay_delete_stream(ngx_rtmp_session_t *s, ngx_rtmp_delete_stream_t *v)
{
    ngx_rtmp_relay_app_conf_t          *racf;
    ngx_rtmp_relay_ctx_t               *ctx, **cctx;
    ngx_uint_t                          hash;

    racf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_relay_module);

    ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_relay_module);
    if (ctx == NULL || ctx->publish == NULL) {
        goto next;
    }

    /* play end disconnect? */
    if (ctx->publish != ctx) {
        for (cctx = &ctx->publish->play; *cctx; cctx = &(*cctx)->next) {
            if (*cctx == ctx) {
                *cctx = ctx->next;
                break;
            }
        }

        ngx_log_debug2(NGX_LOG_DEBUG_RTMP, ctx->session->connection->log, 0, 
                "relay: play disconnect app='%V' name='%V'",
                &ctx->app, &ctx->name);

        /* push reconnect */
        if (ctx->relay && ctx->tag == &ngx_rtmp_relay_module && 
            !ctx->publish->push_evt.timer_set) 
        {
            ngx_add_timer(&ctx->publish->push_evt, racf->push_reconnect);
        }

#ifdef NGX_DEBUG
        {
            ngx_uint_t  n = 0;
            for (cctx = &ctx->publish->play; *cctx; cctx = &(*cctx)->next, ++n);
            ngx_log_debug3(NGX_LOG_DEBUG_RTMP, ctx->session->connection->log, 0, 
                "relay: play left after disconnect app='%V' name='%V': %ui",
                &ctx->app, &ctx->name, n);
        }
#endif

        if (ctx->publish->play == NULL && ctx->publish->relay) {
            ngx_log_debug2(NGX_LOG_DEBUG_RTMP, 
                 ctx->publish->session->connection->log, 0, 
                "relay: publish disconnect empty app='%V' name='%V'",
                &ctx->app, &ctx->name);
            ngx_rtmp_finalize_session(ctx->publish->session);
        }

        ctx->publish = NULL;

        goto next;
    }

    /* publish end disconnect */
    ngx_log_debug2(NGX_LOG_DEBUG_RTMP, ctx->session->connection->log, 0, 
            "relay: publish disconnect app='%V' name='%V'",
            &ctx->app, &ctx->name);

    if (ctx->push_evt.timer_set) {
        ngx_del_timer(&ctx->push_evt);
    }

    for (cctx = &ctx->play; *cctx; cctx = &(*cctx)->next) {
        (*cctx)->publish = NULL;
        ngx_log_debug2(NGX_LOG_DEBUG_RTMP, (*cctx)->session->connection->log, 
            0, "relay: play disconnect orphan app='%V' name='%V'",
            &(*cctx)->app, &(*cctx)->name);
        ngx_rtmp_finalize_session((*cctx)->session);
    }
    ctx->publish = NULL;

    hash = ngx_hash_key(ctx->name.data, ctx->name.len);
    cctx = &racf->ctx[hash % racf->nbuckets];
    for (; *cctx && *cctx != ctx; cctx = &(*cctx)->next);
    if (*cctx) {
        *cctx = ctx->next;
    }

next:
    return next_delete_stream(s, v);
}
static ngx_int_t
ngx_http_auth_request_handler(ngx_http_request_t *r)
{
    ngx_uint_t                    i;
    ngx_int_t                     rc;
    ngx_list_part_t               *part;
    ngx_table_elt_t               *h, *hi;
    ngx_http_request_t            *sr;
    ngx_http_post_subrequest_t    *ps;
    ngx_http_auth_request_ctx_t   *ctx;
    ngx_http_auth_request_conf_t  *arcf;

    arcf = ngx_http_get_module_loc_conf(r, ngx_http_shibboleth_module);

    if (arcf->uri.len == 0) {
        return NGX_DECLINED;
    }

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "shib request handler");

    ctx = ngx_http_get_module_ctx(r, ngx_http_shibboleth_module);

    if (ctx != NULL) {
        if (!ctx->done) {
            return NGX_AGAIN;
        }

        /*
         * as soon as we are done - explicitly set variables to make
         * sure they will be available after internal redirects
         */

        if (ngx_http_auth_request_set_variables(r, arcf, ctx) != NGX_OK) {
            return NGX_ERROR;
        }

        /*
         * Handle the subrequest
         * as per the FastCGI authorizer specification.
         */
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "shib request authorizer handler");
        sr = ctx->subrequest;

        if (ctx->status == NGX_HTTP_OK) {
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "shib request authorizer allows access");

            if (arcf->use_headers) {
                /*
                 * 200 response may include headers prefixed with `Variable-`,
                 * copy these into main request headers
                 */
                part = &sr->headers_out.headers.part;
                h = part->elts;

                for (i = 0; /* void */; i++) {

                    if (i >= part->nelts) {
                        if (part->next == NULL) {
                            break;
                        }

                        part = part->next;
                        h = part->elts;
                        i = 0;
                    }

                    if (h[i].hash == 0) {
                        continue;
                    }

                    if (h[i].key.len >= 9 &&
                        ngx_strncasecmp(h[i].key.data, (u_char *) "Variable-", 9) == 0) {
                        /* copy header into original request */
                        hi = ngx_list_push(&r->headers_in.headers);

                        if (hi == NULL) {
                            return NGX_HTTP_INTERNAL_SERVER_ERROR;
                        }

                        /* Strip the Variable- prefix */
                        hi->key.len = h[i].key.len - 9;
                        hi->key.data = h[i].key.data + 9;
                        hi->hash = ngx_hash_key(hi->key.data, hi->key.len);
                        hi->value = h[i].value;

                        hi->lowcase_key = ngx_pnalloc(r->pool, hi->key.len);
                        if (hi->lowcase_key == NULL) {
                            return NGX_HTTP_INTERNAL_SERVER_ERROR;
                        }
                        ngx_strlow(hi->lowcase_key, hi->key.data, hi->key.len);

                        ngx_log_debug2(
                                NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                                "shib request authorizer copied header: \"%V: %V\"",
                                &hi->key, &hi->value);
                    }
                }

            } else {
                ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "shib request authorizer not using headers");
            }


            return NGX_OK;
        }

        /*
         * Unconditionally return subrequest response status, headers
         * and content as per FastCGI spec (section 6.3).
         *
         * The subrequest response body cannot be returned as Nginx does not
         * currently support NGX_HTTP_SUBREQUEST_IN_MEMORY.
         */
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "shib request authorizer returning sub-response");

        /* copy status */
        r->headers_out.status = sr->headers_out.status;

        /* copy headers */
        part = &sr->headers_out.headers.part;
        h = part->elts;

        for (i = 0; /* void */; i++) {

            if (i >= part->nelts) {
                if (part->next == NULL) {
                    break;
                }

                part = part->next;
                h = part->elts;
                i = 0;
            }

            rc = ngx_http_set_output_header(r, h[i].key, h[i].value);
            if (rc == NGX_ERROR) {
                return NGX_ERROR;
            }

            ngx_log_debug2(
              NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
              "shib request authorizer returning header: \"%V: %V\"",
              &h[i].key, &h[i].value);
        }

        return ctx->status;
    }

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_auth_request_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ps = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
    if (ps == NULL) {
        return NGX_ERROR;
    }

    ps->handler = ngx_http_auth_request_done;
    ps->data = ctx;

    if (ngx_http_subrequest(r, &arcf->uri, NULL, &sr, ps,
                            NGX_HTTP_SUBREQUEST_WAITED)
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    /*
     * allocate fake request body to avoid attempts to read it and to make
     * sure real body file (if already read) won't be closed by upstream
     */

    sr->request_body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
    if (sr->request_body == NULL) {
        return NGX_ERROR;
    }

    /* 
     * true FastCGI authorizers should always return the subrequest 
     * response body but the Nginx FastCGI handler does not support
     * NGX_HTTP_SUBREQUEST_IN_MEMORY at present.
     */
    sr->header_only = 1;

    ctx->subrequest = sr;

    ngx_http_set_ctx(r, ctx, ngx_http_shibboleth_module);

    return NGX_AGAIN;
}
static ngx_int_t
ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_shib_request_header_val_t *hv,
    ngx_str_t *value, ngx_table_elt_t **output_header,
    unsigned no_create)
{
    ngx_table_elt_t             *h;
    ngx_list_part_t             *part;
    ngx_uint_t                   i;
    unsigned                     matched = 0;

#if 1
    if (r->headers_out.location
        && r->headers_out.location->value.len
        && r->headers_out.location->value.data[0] == '/')
    {
        /* XXX ngx_http_core_find_config_phase, for example,
         * may not initialize the "key" and "hash" fields
         * for a nasty optimization purpose, and
         * we have to work-around it here */

        r->headers_out.location->hash = ngx_hash_key((u_char *) "location", 8);
        ngx_str_set(&r->headers_out.location->key, "Location");
    }
#endif

    part = &r->headers_out.headers.part;
    h = part->elts;

    for (i = 0; /* void */; i++) {

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }

            part = part->next;
            h = part->elts;
            i = 0;
        }

        if (h[i].hash != 0
            && h[i].key.len == hv->key.len
            && ngx_strncasecmp(hv->key.data, h[i].key.data, h[i].key.len) == 0)
        {

            if (value->len == 0 || matched) {

                h[i].value.len = 0;
                h[i].hash = 0;

            } else {
                h[i].value = *value;
                h[i].hash = hv->hash;
            }

            if (output_header) {
                *output_header = &h[i];
            }

            /* return NGX_OK; */
            matched = 1;
        }
    }

    if (matched) {
        return NGX_OK;
    }

    if (no_create && value->len == 0) {
        return NGX_OK;
    }

    /* XXX we still need to create header slot even if the value
     * is empty because some builtin headers like Last-Modified
     * relies on this to get cleared */

    h = ngx_list_push(&r->headers_out.headers);

    if (h == NULL) {
        return NGX_ERROR;
    }

    if (value->len == 0) {
        h->hash = 0;

    } else {
        h->hash = hv->hash;
    }

    h->key = hv->key;
    h->value = *value;

    h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
    if (h->lowcase_key == NULL) {
        return NGX_ERROR;
    }

    ngx_strlow(h->lowcase_key, h->key.data, h->key.len);

    if (output_header) {
        *output_header = h;
    }

    return NGX_OK;
}
Exemplo n.º 27
0
uint32_t dvt_cache_label_id_from_name(dvt_cache_t *cache, ngx_str_t *name)
{
  ngx_uint_t key_hash = ngx_hash_key(name->data, name->len);
  int64_t r = (uint64_t)ngx_hash_find(cache->label_ids, key_hash, name->data, name->len);
  return (uint32_t) r - ARBITRARY_OFFSET_TO_AVOID_PTR_EQ_NULL;
}
Exemplo n.º 28
0
dvt_cache_t *dvt_cache_init(ngx_pool_t *pool)
{
  dvt_cache_t *cache = ngx_palloc(pool, sizeof(dvt_cache_t));

  cache->label_and_value_summary_json = NGX_CONF_UNSET_PTR;
  cache->label_names = NGX_CONF_UNSET_PTR;
  cache->label_ids = NGX_CONF_UNSET_PTR;
  cache->label_value_names = NGX_CONF_UNSET_PTR;
  cache->label_value_ids = NGX_CONF_UNSET_PTR;

  uint64_t i, j;
  ngx_str_t *jsn = NGX_CONF_UNSET_PTR;
  ngx_array_t* series_collection;
  ngx_array_t* lavs; // labels and values
  ngx_str_t *current_str;
  ngx_array_t *hash_elts;
  ngx_hash_key_t *el;
  ngx_array_t **ael;
  ngx_hash_init_t hash_spec;

  // ### json summary.
  series_collection = load_test_exposition(pool);
  if (series_collection)
  {
    lavs = lavs_from_series_set(series_collection, pool);
    jsn = lavs_to_json(lavs, pool, pool);
  }
  cache->label_and_value_summary_json = jsn;

  // ### label_id -> label_names array
  cache->label_names = ngx_array_create(pool, 32, sizeof(ngx_str_t));
  for (i=0; i<lavs->nelts; ++i)
  {
    current_str = ngx_array_push(cache->label_names);
    *current_str = ((dvt_label_summary_info_t *)lavs->elts)[i].label_name;
  }

  // ### label_name -> label_id hash
  hash_elts = ngx_array_create(pool, 32, sizeof(ngx_hash_key_t));
  for (i=0; i<cache->label_names->nelts; ++i)
  {
    el = ngx_array_push(hash_elts);
    el->key = ((ngx_str_t *)cache->label_names->elts)[i];
    el->key_hash = ngx_hash_key(el->key.data, el->key.len);
    el->value = (void *)(i + ARBITRARY_OFFSET_TO_AVOID_PTR_EQ_NULL);
  }
  cache->label_ids = ngx_palloc(pool, sizeof(ngx_hash_t));
  hash_spec.hash = cache->label_ids;
  hash_spec.key = ngx_hash_key;
  hash_spec.max_size = 1024;
  hash_spec.bucket_size = ngx_align(64, ngx_cacheline_size);
  hash_spec.name = "label_ids";
  hash_spec.pool = pool;
  if (ngx_hash_init(&hash_spec, hash_elts->elts, hash_elts->nelts) != NGX_OK) {
    return NGX_CONF_ERROR;
  }

  // ### label_value_names
  cache->label_value_names = ngx_array_create(
    pool, cache->label_names->nelts, sizeof(ngx_array_t *));
  for (i=0; i<cache->label_names->nelts; ++i)
  {
    dvt_label_summary_info_t *labsum =
        &(((dvt_label_summary_info_t *)lavs->elts)[i]);
    ael = ngx_array_push(cache->label_value_names);
    *ael = ngx_array_create(
      pool, labsum->label_values->nelts, sizeof(ngx_str_t *));
    for (j=0; j<labsum->label_values->nelts; ++j)
    {
      dvt_label_value_summary_info_t* labval_info
        = &((dvt_label_value_summary_info_t *)labsum->label_values->elts)[j];
      ngx_str_t *lval
        = &labval_info->label_value_name;
      ngx_str_t **p = ngx_array_push(*ael);
      *p = lval;
    }
  }

  // ### label_value_ids
  cache->label_value_ids = ngx_array_create(
    pool, cache->label_names->nelts, sizeof(ngx_hash_t));
  for (i=0; i<cache->label_names->nelts; ++i)
  {
    hash_elts = ngx_array_create(pool, 32, sizeof(ngx_hash_key_t));
    ngx_array_t *value_names
      = ((ngx_array_t **)cache->label_value_names->elts)[i];
    for (j=0; j<value_names->nelts; ++j)
    {
      el = ngx_array_push(hash_elts);
      el->key = *((ngx_str_t **)value_names->elts)[j];
      el->key_hash = ngx_hash_key(el->key.data, el->key.len);
      el->value = (void *)(j + ARBITRARY_OFFSET_TO_AVOID_PTR_EQ_NULL);
    }

    ngx_hash_t *hel = ngx_array_push(cache->label_value_ids);
    hash_spec.hash = hel;
    hash_spec.key = ngx_hash_key;
    hash_spec.max_size = 1024;
    hash_spec.bucket_size = ngx_align(64, ngx_cacheline_size);
    hash_spec.name = "label_value_ids";
    hash_spec.pool = pool;
    if (ngx_hash_init(&hash_spec, hash_elts->elts, hash_elts->nelts) != NGX_OK) {
      return NGX_CONF_ERROR;
    }
  }

  // TODO: some sort of partitioning.
  // Probably binary.
  // Goal is to keep as balanced as possible.
  // ### all series
  ngx_array_init(&cache->all_series, pool, 128, sizeof(uint32_t *));
  for (i=0; i<series_collection->nelts; ++i)
  {
    ngx_array_t *series_kvps = ((ngx_array_t **)series_collection->elts)[i];
    uint32_t **loc = ngx_array_push(&cache->all_series);
    *loc = dvt_series_spec_from_kv_array(cache, series_kvps, pool);
    dbg_ngx(dvt_series_spec_to_text(cache, *loc, pool), pool);
  }

  return cache;
}
Exemplo n.º 29
0
//get the index
static ngx_http_dclass_kvdata_str *ngx_http_dclass_index(ngx_http_request_t *r)
{
    ngx_uint_t i;
    u_char *hfield=NULL;
    ngx_uint_t key;
    ngx_str_t str;
    ngx_http_variable_value_t *val;
    const dclass_keyvalue *kvd;
    ngx_list_part_t *part;
    ngx_table_elt_t *header;
    ngx_http_dclass_conf_t  *cf;
    ngx_http_dclass_kvdata_str *kvs;
    
    cf = ngx_http_get_module_loc_conf(r,ngx_http_dclass_module);
    
    if(!cf->enable || !cf->head[0])
        return NULL;
    
    ngx_str_set(&str,"dclass_ptr");
    
    key=ngx_hash_key(str.data,str.len);
    val=ngx_http_get_variable(r, &str, key);
    
    if(val && val->valid && val->data && !ngx_rstrncmp((u_char*)"ptr",val->data,3))
    {
        kvs=(ngx_http_dclass_kvdata_str*)val->data;
        
        ngx_log_error(NGX_HTTP_DCLASS_LOGLEVEL,r->connection->log,0,"dClass: classify cache: '%s'",kvs->kvd[0]->id);
        
        return kvs;
    }
    
    if(!*cf->hfield.data)
    {
        if(r->headers_in.user_agent)
            hfield = r->headers_in.user_agent->value.data;
    }
    else
    {
        part=&r->headers_in.headers.part;
        header=part->elts;
        for (i=0;;i++)
        {
            if(i>=part->nelts)
            {
                if(part->next==NULL)
                    break;
                part=part->next;
                header=part->elts;
                i=0;
            }
            if(!ngx_strcasecmp(cf->hfield.data,header[i].key.data))
            {
                hfield=header[i].value.data;
                break;
            }
        }
    }
    
    if(hfield==NULL)
        return NULL;
    
    kvs=(ngx_http_dclass_kvdata_str*)ngx_pcalloc(r->pool,sizeof(ngx_http_dclass_kvdata_str));
    
    if(kvs==NULL)
        return NULL;
    
    for(i=0;i<NGX_HTTP_DCLASS_INDEXES && cf->head[i];i++)
    {
        kvd=dclass_classify(cf->head[i],(char*)hfield);

        kvs->kvd[i]=kvd;
        ngx_cpystrn(kvs->data,(u_char*)"ptr",4);

        ngx_log_error(NGX_HTTP_DCLASS_LOGLEVEL,r->connection->log,0,"dClass: classify %d: '%s' => '%s'",i,hfield,kvd->id);
    }
    
    return kvs;
}
Exemplo n.º 30
0
ngx_int_t
ngx_hash_add_key(ngx_hash_keys_arrays_t *ha, ngx_str_t *key, void *value,
    ngx_uint_t flags)
{
    size_t           len;
    u_char          *p;
    ngx_str_t       *name;
    ngx_uint_t       i, k, n, skip, last;
    ngx_array_t     *keys, *hwc;
    ngx_hash_key_t  *hk;

    last = key->len;

    if (flags & NGX_HASH_WILDCARD_KEY) {

        /*
         * supported wildcards:
         *     "*.example.com", ".example.com", and "www.example.*"
         */

        n = 0;

        for (i = 0; i < key->len; i++) {

            if (key->data[i] == '*') {
                if (++n > 1) {
                    return NGX_DECLINED;
                }
            }

            if (key->data[i] == '.' && key->data[i + 1] == '.') {
                return NGX_DECLINED;
            }
        }

        if (key->len > 1 && key->data[0] == '.') {
            skip = 1;
            goto wildcard;
        }

        if (key->len > 2) {

            if (key->data[0] == '*' && key->data[1] == '.') {
                skip = 2;
                goto wildcard;
            }

            if (key->data[i - 2] == '.' && key->data[i - 1] == '*') {
                skip = 0;
                last -= 2;
                goto wildcard;
            }
        }

        if (n) {
            return NGX_DECLINED;
        }
    }

    /* exact hash */

    k = 0;

    for (i = 0; i < last; i++) {
        if (!(flags & NGX_HASH_READONLY_KEY)) {
            key->data[i] = ngx_tolower(key->data[i]);
        }
        k = ngx_hash(k, key->data[i]);
    }

    k %= ha->hsize;

    /* check conflicts in exact hash */

    name = ha->keys_hash[k].elts;

    if (name) {
        for (i = 0; i < ha->keys_hash[k].nelts; i++) {
            if (last != name[i].len) {
                continue;
            }

            if (ngx_strncmp(key->data, name[i].data, last) == 0) {
                return NGX_BUSY;
            }
        }

    } else {
        if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
                           sizeof(ngx_str_t))
            != NGX_OK)
        {
            return NGX_ERROR;
        }
    }

    name = ngx_array_push(&ha->keys_hash[k]);
    if (name == NULL) {
        return NGX_ERROR;
    }

    *name = *key;

    hk = ngx_array_push(&ha->keys);
    if (hk == NULL) {
        return NGX_ERROR;
    }

    hk->key = *key;
    hk->key_hash = ngx_hash_key(key->data, last);
    hk->value = value;

    return NGX_OK;


wildcard:

    /* wildcard hash */

    k = ngx_hash_strlow(&key->data[skip], &key->data[skip], last - skip);

    k %= ha->hsize;

    if (skip == 1) {

        /* check conflicts in exact hash for ".example.com" */

        name = ha->keys_hash[k].elts;

        if (name) {
            len = last - skip;

            for (i = 0; i < ha->keys_hash[k].nelts; i++) {
                if (len != name[i].len) {
                    continue;
                }

                if (ngx_strncmp(&key->data[1], name[i].data, len) == 0) {
                    return NGX_BUSY;
                }
            }

        } else {
            if (ngx_array_init(&ha->keys_hash[k], ha->temp_pool, 4,
                               sizeof(ngx_str_t))
                != NGX_OK)
            {
                return NGX_ERROR;
            }
        }

        name = ngx_array_push(&ha->keys_hash[k]);
        if (name == NULL) {
            return NGX_ERROR;
        }

        name->len = last - 1;
        name->data = ngx_pnalloc(ha->temp_pool, name->len);
        if (name->data == NULL) {
            return NGX_ERROR;
        }

        ngx_memcpy(name->data, &key->data[1], name->len);
    }


    if (skip) {

        /*
         * convert "*.example.com" to "com.example.\0"
         *      and ".example.com" to "com.example\0"
         */

        p = ngx_pnalloc(ha->temp_pool, last);
        if (p == NULL) {
            return NGX_ERROR;
        }

        len = 0;
        n = 0;

        for (i = last - 1; i; i--) {
            if (key->data[i] == '.') {
                ngx_memcpy(&p[n], &key->data[i + 1], len);
                n += len;
                p[n++] = '.';
                len = 0;
                continue;
            }

            len++;
        }

        if (len) {
            ngx_memcpy(&p[n], &key->data[1], len);
            n += len;
        }

        p[n] = '\0';

        hwc = &ha->dns_wc_head;
        keys = &ha->dns_wc_head_hash[k];

    } else {

        /* convert "www.example.*" to "www.example\0" */

        last++;

        p = ngx_pnalloc(ha->temp_pool, last);
        if (p == NULL) {
            return NGX_ERROR;
        }

        ngx_cpystrn(p, key->data, last);

        hwc = &ha->dns_wc_tail;
        keys = &ha->dns_wc_tail_hash[k];
    }


    /* check conflicts in wildcard hash */

    name = keys->elts;

    if (name) {
        len = last - skip;

        for (i = 0; i < keys->nelts; i++) {
            if (len != name[i].len) {
                continue;
            }

            if (ngx_strncmp(key->data + skip, name[i].data, len) == 0) {
                return NGX_BUSY;
            }
        }

    } else {
        if (ngx_array_init(keys, ha->temp_pool, 4, sizeof(ngx_str_t)) != NGX_OK)
        {
            return NGX_ERROR;
        }
    }

    name = ngx_array_push(keys);
    if (name == NULL) {
        return NGX_ERROR;
    }

    name->len = last - skip;
    name->data = ngx_pnalloc(ha->temp_pool, name->len);
    if (name->data == NULL) {
        return NGX_ERROR;
    }

    ngx_memcpy(name->data, key->data + skip, name->len);


    /* add to wildcard hash */

    hk = ngx_array_push(hwc);
    if (hk == NULL) {
        return NGX_ERROR;
    }

    hk->key.len = last - 1;
    hk->key.data = p;
    hk->key_hash = 0;
    hk->value = value;

    return NGX_OK;
}