示例#1
0
static ngx_int_t ngx_http_shmtest_counter_inc_int(ngx_http_request_t *r)
{
	ngx_int_t rc = NGX_HTTP_OK;
	ngx_str_t key = ngx_null_string;
	ngx_str_t szn = ngx_null_string;
	ngx_int_t n = 1;
	int64_t cur = 0;
	
	if(ngx_http_arg(r, (u_char*)"key", 3, &key)!=NGX_OK){
		NLOG_ERROR("get arg 'key' failed!");
		return NGX_HTTP_BAD_REQUEST;
	}

	if(ngx_http_arg(r, (u_char*)"n", 1, &szn)==NGX_OK){
		n = ngx_atoi(szn.data, szn.len);
	}

	shmtest_main_conf_t* smcf;
	smcf = ngx_http_get_module_main_conf(r, ngx_http_shmtest_module);
	if(smcf == NULL){
		NLOG_ERROR("get module ngx_http_shmtest_module's main conf failed!");
		return NGX_HTTP_INTERNAL_SERVER_ERROR;
	}

	ngx_shm_zone_t* zone = smcf->shmap;
	u_char* rsp = ngx_pcalloc(r->connection->pool, 256);
	int rsp_len = 0;

	rc = ngx_shmap_inc_int(zone, &key, n,0, &cur);

	
	if(rc == 0){
		rsp_len = ngx_sprintf(rsp, "inc_int(key=%V,n=%l)=%l\n",
						&key,n, cur)-rsp;
	}else{
		rsp_len = ngx_sprintf(rsp, "inc_int(key=%V,n=%l) failed!\n", &key,n)-rsp;
	}

	ngx_chain_t* chain = ngx_http_shmtest_resp(r, (char*)rsp, rsp_len);
	if(chain != NULL){
	    r->headers_out.content_length_n = rsp_len;
	}else{
		r->headers_out.content_length_n = 0;
	}

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        
    }else{
    	rc = ngx_http_output_filter(r, chain);
    }

	return rc;	
}
static ngx_int_t ngx_http_calc_handler(ngx_http_request_t *r)
{
	ngx_int_t rc;
	ngx_buf_t *b;
	ngx_chain_t out;
	u_char ngx_string[1024]={0};
	ngx_uint_t content_length = 0;
	
	ngx_str_t arg1;
	ngx_str_t arg2;
	ngx_int_t ans;

	ngx_http_arg(r,(u_char *)"arg1",4,&arg1);
	ngx_http_arg(r,(u_char *)"arg2",4,&arg2);
	ans = ngx_atoi(arg1.data,arg1.len)+ngx_atoi(arg2.data,arg2.len);

	ngx_sprintf(ngx_string,"%V + %V = %d",&arg1,&arg2,ans);
	content_length = ngx_strlen(ngx_string);

	if (!(r->method & (NGX_HTTP_GET | NGX_HTTP_HEAD))){
		return NGX_HTTP_NOT_ALLOWED;
	}

	rc = ngx_http_discard_request_body(r);
	if (rc != NGX_OK) {
		return rc;
	}

	ngx_str_t type = ngx_string("text/html");
	r->headers_out.status = NGX_HTTP_OK;
	r->headers_out.content_length_n = content_length;
	r->headers_out.content_type = type;

	/* HTTP框架提供的发送HTTP头部的方法 */
	/* 返回NGX_ERROR或返回值大于0就表示不正常 */
	rc = ngx_http_send_header(r);
	if (rc == NGX_ERROR || rc > NGX_OK || r->header_only){
		return rc;
	}

	b = ngx_pcalloc(r->pool,sizeof(ngx_buf_t));
	if(b==NULL){
		return NGX_HTTP_INTERNAL_SERVER_ERROR;
	}

	b->pos = ngx_string;
	b->last = ngx_string+content_length;
	b->memory = 1;
	b->last_buf = 1;

	out.buf = b;
	out.next = NULL;

	return ngx_http_output_filter(r,&out);
}
static ngx_int_t
ngx_http_conhash_test_del(ngx_http_request_t *r, ngx_conhash_t *conhash, ngx_chain_t *out)
{
    ngx_str_t                            value;
    ngx_int_t                            rc;
    ngx_buf_t                           *b;
    
    rc = ngx_http_arg(r, (u_char *) VALUE_STR, sizeof(VALUE_STR) - 1, &value);
    if (rc != NGX_OK) {
        return rc;
    }
    
    b = ngx_create_temp_buf(r->pool, 1024);
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    rc = ngx_conhash_del_node(conhash, value.data, value.len);
    if (rc == NGX_OK) {
        b->last = ngx_sprintf(b->last, "Delete node successfully!" CRLF);
    }
    
    if (rc == NGX_DECLINED) {
        b->last = ngx_sprintf(b->last, "The node does not exists!" CRLF);
        rc = NGX_OK;
    }
    
    b->last_buf = 1;
    out->buf = b;
    
    return rc;
}
示例#4
0
static ngx_int_t
ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v,
    uintptr_t data)
{
    ngx_str_t *name = (ngx_str_t *) data;

    u_char     *arg;
    size_t      len;
    ngx_str_t   value;

    len = name->len - (sizeof("arg_") - 1);
    arg = name->data + sizeof("arg_") - 1;

    if (ngx_http_arg(r, arg, len, &value) != NGX_OK) {
        v->not_found = 1;
        return NGX_OK;
    }

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

    return NGX_OK;
}
static const char *
ngx_rtmp_control_walk_server(ngx_http_request_t *r,
    ngx_rtmp_core_srv_conf_t *cscf,
    ngx_rtmp_core_app_conf_t ***pcacf_rtrn)
{
    ngx_str_t                   app;
    ngx_uint_t                  n;
    const char                 *s;
    ngx_rtmp_core_app_conf_t  **pcacf;

    if (ngx_http_arg(r, (u_char *) "app", sizeof("app") - 1, &app) != NGX_OK) {
        app.len = 0;
    }

    pcacf = cscf->applications.elts;

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

        *pcacf_rtrn = (ngx_rtmp_core_app_conf_t **)(*pcacf)->app_conf;
        s = ngx_rtmp_control_walk_app(r, *pcacf);
        if (s != NGX_CONF_OK) {
            return s;
        }
    }

    return NGX_CONF_OK;
}
static ngx_int_t
ngx_http_conhash_test_search(ngx_http_request_t *r, ngx_conhash_t *conhash, ngx_chain_t *out)
{
    ngx_str_t                            value;
    ngx_int_t                            rc;
    size_t                               len;
    ngx_buf_t                           *b;
    ngx_rbtree_key_t                     key;
    ngx_http_conhash_test_node_name_t    node;

    rc = ngx_http_arg(r, (u_char *) VALUE_STR, sizeof(VALUE_STR) - 1, &value);
    if (rc != NGX_OK) {
        return rc;
    }
    
    ngx_memzero(&node, sizeof(ngx_http_conhash_test_node_name_t));
    node.pool = r->pool;
    
    rc = ngx_conhash_lookup_node(conhash, value.data, value.len, ngx_http_conhash_test_get_data, &node);
    if (rc != NGX_OK) {
        b = ngx_create_temp_buf(r->pool, 1024);
        if (b == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        
        b->last = ngx_sprintf(b->last, "The node tree is empty!" CRLF);
        
        goto done;
    }
    
    if (node.vname.data == NULL || node.name.data == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    len = value.len + sizeof(BRACKET_L) - 1 + NGX_OFF_T_LEN + sizeof(PROMPT_STR) - 1 + 
          node.name.len + sizeof(BRACKET_L) - 1 + node.vname.len + 
          sizeof(COMMA_STR) - 1 + NGX_OFF_T_LEN + sizeof(BRACKET_R) - 1 + sizeof(CRLF) - 1;
    
    b = ngx_create_temp_buf(r->pool, len);
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    key = conhash->hash_func(value.data, value.len);
    
    b->last = ngx_sprintf(b->last, "%V" BRACKET_L "%ui" PROMPT_STR "%V" BRACKET_L "%V" COMMA_STR "%ui"\
                BRACKET_R CRLF, &value, key, &node.name, &node.vname, node.key);

done:

    b->last_buf = 1;
    out->buf = b;
    
    return NGX_OK;
}
static ngx_int_t 
ngx_http_weixin_auth_handler(ngx_http_request_t *r)
{
    ngx_buf_t       *b;
    ngx_chain_t      out;
    ngx_int_t        rc;
    ngx_str_t        echostr;
    
    if (!(r->method & NGX_HTTP_GET)) {
        return NGX_DECLINED;
    }
    
    if (!r->args.len) {
        return NGX_DECLINED;
    }
   
    if (ngx_http_arg(r, (u_char *) "echostr", 7, &echostr) != NGX_OK) {
        return NGX_DECLINED;
    }
    
    rc = ngx_http_weixin_auth(r);
    if (rc != NGX_OK && rc != NGX_DECLINED) {
        return rc;
    }
    
    if (rc == NGX_DECLINED) {
        return NGX_HTTP_FORBIDDEN;
    }
    
    b = ngx_create_temp_buf(r->pool, echostr.len);
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
    
    b->last = ngx_cpymem(b->last, echostr.data, echostr.len);
    b->last_buf = 1;
    
    out.buf = b;
    out.next = NULL;
    
    r->headers_out.status = NGX_HTTP_OK;
    ngx_str_set(&r->headers_out.content_type, "text/plain");
    r->headers_out.content_length_n = echostr.len;
    
    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }
    
    return ngx_http_output_filter(r, &out);
}
static ngx_int_t
ngx_http_trim_header_filter(ngx_http_request_t *r)
{
    ngx_int_t                  rc;
    ngx_str_t                  flag;
    ngx_http_trim_ctx_t       *ctx;
    ngx_http_trim_loc_conf_t  *conf;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_trim_filter_module);

    if (!conf->trim_enable
        || r->headers_out.status != NGX_HTTP_OK
        || (r->method & NGX_HTTP_HEAD)
        || r->headers_out.content_length_n == 0
        || (r->headers_out.content_encoding
            && r->headers_out.content_encoding->value.len)
        || ngx_http_test_content_type(r, &conf->types) == NULL)
    {
        return ngx_http_next_header_filter(r);
    }

    rc = ngx_http_arg(r, (u_char *) NGX_HTTP_TRIM_FLAG,
                      sizeof(NGX_HTTP_TRIM_FLAG) - 1, &flag);

    if(rc == NGX_OK
       && flag.len == sizeof("off") - 1
       && ngx_strncmp(flag.data, "off", sizeof("off") - 1) == 0)
    {
        return ngx_http_next_header_filter(r);
    }

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

    ctx->prev = ' ';
    ctx->first_line = 1;

    ngx_http_set_ctx(r, ctx, ngx_http_trim_filter_module);

    r->main_filter_need_in_memory = 1;

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    return ngx_http_next_header_filter(r);
}
static const char *
ngx_rtmp_control_walk(ngx_http_request_t *r, ngx_rtmp_control_handler_t h,
    ngx_flag_t per_session)
{
    ngx_rtmp_core_main_conf_t  *cmcf = ngx_rtmp_core_main_conf;

    ngx_str_t                   srv;
    ngx_uint_t                  sn, n;
    const char                 *msg;
    ngx_rtmp_session_t        **s;
    ngx_rtmp_control_ctx_t     *ctx;
    ngx_rtmp_core_srv_conf_t  **pcscf;
    ngx_rtmp_core_app_conf_t  **pcacf = NULL;

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

    if (sn >= cmcf->servers.nelts) {
        return "Server index out of range";
    }

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

    msg = ngx_rtmp_control_walk_server(r, *pcscf, &pcacf);
    if (msg != NGX_CONF_OK) {
        return msg;
    }

    ctx = ngx_http_get_module_ctx(r, ngx_rtmp_control_module);

    if (!per_session) {
        return h(r, NULL, *pcscf, pcacf);
    }

    s = ctx->sessions.elts;
    for (n = 0; n < ctx->sessions.nelts; n++) {
        msg = h(r, s[n], *pcscf, pcacf);
        if (msg != NGX_CONF_OK) {
            return msg;
        }
    }

    return NGX_CONF_OK;
}
示例#10
0
static njs_ret_t
ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value, void *obj,
    uintptr_t data)
{
    nxt_str_t           *v;
    ngx_str_t            arg;
    ngx_http_request_t  *r;

    r = (ngx_http_request_t *) obj;
    v = (nxt_str_t *) data;

    if (ngx_http_arg(r, v->start, v->length, &arg) == NGX_OK) {
        return njs_string_create(vm, value, arg.data, arg.len, 0);
    }

    return njs_string_create(vm, value, NULL, 0, 0);
}
static const char *
ngx_rtmp_control_record_handler(ngx_http_request_t *r, ngx_rtmp_session_t *s,
    ngx_rtmp_core_srv_conf_t *cscf,
    ngx_rtmp_core_app_conf_t **cacf)
{
    ngx_int_t                    rc;
    ngx_str_t                    rec;
    ngx_uint_t                   rn;
    ngx_rtmp_control_ctx_t      *ctx;
    ngx_rtmp_record_app_conf_t  *racf;

    *cacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_core_module);
    racf = (*cacf)->app_conf[ngx_rtmp_record_module.ctx_index];

    if (ngx_http_arg(r, (u_char *) "rec", sizeof("rec") - 1, &rec) != NGX_OK) {
        rec.len = 0;
    }

    rn = ngx_rtmp_record_find(racf, &rec);
    if (rn == NGX_CONF_UNSET_UINT) {
        return "Recorder not found";
    }

    ctx = ngx_http_get_module_ctx(r, ngx_rtmp_control_module);

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

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

    } else {
        return "Undefined method";
    }

    if (rc == NGX_ERROR) {
        return "Recorder error";
    }

    return NGX_CONF_OK;
}
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;
}
//解析url中的参数,主要处理 http get 请求
inline ngx_str_t ngx_parser_http_request(ngx_http_request_t *r) {
	 ngx_str_t value;
	  // args is data=xxxxx
	 // 第二个参数是HTTP GET的key名,key名的长度,第四个参数是想存这个value的变量的指针
	 if (NGX_OK != ngx_http_arg(r, (u_char*)"data", 4, &value)) {
		 ngx_str_t res = ngx_null_string;
		 return res;
	 }
	 
	 ngx_str_t sentence;
	 u_char* dst, *src;
	 dst = (u_char*)ngx_pcalloc(r->pool, 1024);//解码后字词空间
	 src = value.data;
	 sentence.data = dst;
	 // 解析url 编码
	 ngx_unescape_uri(&dst, &src, value.len, 0);
	 sentence.len = dst - sentence.data;
	 //ngx_log_error(NGX_LOG_EMERG, r->connection->log, 0, " data=%s", sentence.data);
	 return sentence; 
}
static ngx_int_t
ngx_http_get_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v,
    uintptr_t data)
{
    ngx_str_t *name = (ngx_str_t *) data;
    ngx_str_t   value;

    if (ngx_http_arg(r, name->data, name->len, &value) != NGX_OK) {
        v->not_found = 1;
        return NGX_OK;
    }

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

    return NGX_OK;
}
static ngx_int_t
ngx_http_autoindex_jsonp_callback(ngx_http_request_t *r, ngx_str_t *callback)
{
    u_char      *p, c, ch;
    ngx_uint_t   i;

    if (ngx_http_arg(r, (u_char *) "callback", 8, callback) != NGX_OK) {
        callback->len = 0;
        return NGX_OK;
    }

    if (callback->len > 128) {
        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                      "client sent too long callback name: \"%V\"", callback);
        return NGX_DECLINED;
    }

    p = callback->data;

    for (i = 0; i < callback->len; i++) {
        ch = p[i];

        c = (u_char) (ch | 0x20);
        if (c >= 'a' && c <= 'z') {
            continue;
        }

        if ((ch >= '0' && ch <= '9') || ch == '_' || ch == '.') {
            continue;
        }

        ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                      "client sent invalid callback name: \"%V\"", callback);

        return NGX_DECLINED;
    }

    return NGX_OK;
}
示例#16
0
static ngx_int_t
ngx_http_pi_handler(ngx_http_request_t *r)
{
    ngx_int_t                      rc;
    ngx_buf_t                     *b;
    ngx_chain_t                    out;
    ngx_str_t                      aval;
    ngx_uint_t                     n;
    ngx_http_pi_loc_conf_t        *plcf;
    ngx_uint_t                     k;
    u_char                        *pb, *buf;

    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
        return NGX_HTTP_NOT_ALLOWED;
    }

    rc = ngx_http_discard_request_body(r);
    if (rc != NGX_OK) {
        return rc;
    }
 
    ngx_str_set(&r->headers_out.content_type, "text/plain");

    if (r->method == NGX_HTTP_HEAD) {
        r->headers_out.status = NGX_HTTP_OK;
        rc = ngx_http_send_header(r);
        if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
            return rc;
        }
    }

    plcf = ngx_http_get_module_loc_conf(r, ngx_http_pi_module);

    n = 2;                      /* first two digits "14" */
    rc = ngx_http_arg(r, (u_char*) "n", 1, &aval);
    if (rc == NGX_OK) {
        rc = ngx_atoi(aval.data, aval.len);
        if (rc != NGX_ERROR) {
            n = (ngx_uint_t) rc;
            if (n > plcf->size) n = plcf->size;
        }
    }
    n += 2;

    buf = ngx_palloc(r->pool, n);
    buf[0] = '3', buf[1] = '.';
    pb = buf + 2;

    for (k = 0; k < n/2+1; k++) {
        pb = ngx_sprintf(pb, "%d%d", (plcf->buf[k]&0xf0)>>4, plcf->buf[k]&0xf);
    }

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

    out.buf = b;
    out.next = NULL;

    b->pos = buf;
    b->last = b->pos + n;
    b->memory = 1;
    b->last_buf = 1;
    b->last_in_chain = 1;
    
    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = b->last - b->pos;

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }
 
    return ngx_http_output_filter(r, &out);
}
static ngx_int_t
ngx_http_xss_header_filter(ngx_http_request_t *r)
{
    ngx_http_xss_ctx_t          *ctx;
    ngx_http_xss_conf_t         *conf;
    ngx_str_t                    callback;
    u_char                      *p, *src, *dst;

    if (r->headers_out.status != NGX_HTTP_OK || r != r->main) {
        dd("skipped: status not 200 or in subrequest");
        return ngx_http_next_header_filter(r);
    }

    conf = ngx_http_get_module_loc_conf(r, ngx_http_xss_filter_module);

    if ( ! conf->get_enabled || r->method != NGX_HTTP_GET) {
        dd("skipped: get_enabled disabled or the current method is not GET");
        return ngx_http_next_header_filter(r);
    }

    if (conf->callback_arg.len == 0) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "xss: xss_get is enabled but no xss_callback_arg specified");

        return ngx_http_next_header_filter(r);
    }

    if (ngx_http_test_content_type(r, &conf->input_types) == NULL) {
        dd("skipped: content type test not passed");
        return ngx_http_next_header_filter(r);
    }

    if (ngx_http_arg(r, conf->callback_arg.data, conf->callback_arg.len,
                &callback) != NGX_OK)
    {
        dd("skipped: no callback arg found in the current request: %.*s",
                conf->callback_arg.len, conf->callback_arg.data);

        return ngx_http_next_header_filter(r);
    }

    p = ngx_palloc(r->pool, callback.len);
    if (p == NULL) {
        return NGX_ERROR;
    }

    src = callback.data; dst = p;

    ngx_unescape_uri(&dst, &src, callback.len,
            NGX_UNESCAPE_URI_COMPONENT);

    if (src != callback.data + callback.len) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "xss: unescape uri: input data not consumed completely");

        return NGX_ERROR;
    }

    callback.data = p;
    callback.len = dst - p;

    if (ngx_http_xss_test_callback((char *) callback.data, callback.len)
            != NGX_OK)
    {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "xss: bad callback argument: \"%V\"", &callback);

        return ngx_http_next_header_filter(r);
    }

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

    /*
     * set by ngx_pcalloc():
     *
     *     ctx->callback = { 0, NULL };
     *     conf->before_body_sent = 0;
     */

    ctx->callback = callback;

    ngx_http_set_ctx(r, ctx, ngx_http_xss_filter_module);

    r->headers_out.content_type = conf->output_type;
    r->headers_out.content_type_len = conf->output_type.len;

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    return ngx_http_next_header_filter(r);
}
示例#18
0
static ngx_int_t
ngx_http_slice_handler(ngx_http_request_t *r)
{
    u_char                    *last;
    off_t                      begin, end, len;
    size_t                     root;
    ngx_int_t                  rc;
    ngx_uint_t                 level, i;
    ngx_str_t                  path, value;
    ngx_log_t                 *log;
    ngx_buf_t                 *b;
    ngx_chain_t                out[3];
    ngx_open_file_info_t       of;
    ngx_http_core_loc_conf_t  *clcf;
    ngx_http_slice_loc_conf_t *slcf;

    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }

    if (r->uri.data[r->uri.len - 1] == '/') {
        return NGX_DECLINED;
    }

    slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_module);

    rc = ngx_http_discard_request_body(r);

    if (rc != NGX_OK) {
        return rc;
    }

    last = ngx_http_map_uri_to_path(r, &path, &root, 0);
    if (last == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    log = r->connection->log;

    path.len = last - path.data;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                   "http slice filename: \"%V\"", &path);

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    ngx_memzero(&of, sizeof(ngx_open_file_info_t));

    of.read_ahead = clcf->read_ahead;
    of.directio = clcf->directio;
    of.valid = clcf->open_file_cache_valid;
    of.min_uses = clcf->open_file_cache_min_uses;
    of.errors = clcf->open_file_cache_errors;
    of.events = clcf->open_file_cache_events;

    if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
        != NGX_OK)
    {
        switch (of.err) {

        case 0:
            return NGX_HTTP_INTERNAL_SERVER_ERROR;

        case NGX_ENOENT:
        case NGX_ENOTDIR:
        case NGX_ENAMETOOLONG:

            level = NGX_LOG_ERR;
            rc = NGX_HTTP_NOT_FOUND;
            break;

        case NGX_EACCES:

            level = NGX_LOG_ERR;
            rc = NGX_HTTP_FORBIDDEN;
            break;

        default:

            level = NGX_LOG_CRIT;
            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
            break;
        }

        if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
            ngx_log_error(level, log, of.err,
                          "%s \"%s\" failed", of.failed, path.data);
        }

        return rc;
    }

    if (!of.is_file) {

        if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                          ngx_close_file_n " \"%s\" failed", path.data);
        }

        return NGX_DECLINED;
    }

    r->root_tested = !r->error_page;

    begin = 0;
    end = of.size;

    if (r->args.len) {

        if (ngx_http_arg(r, slcf->begin.data, slcf->begin.len, &value)
            == NGX_OK)
        {
            begin = ngx_atoof(value.data, value.len);

            if (begin == NGX_ERROR || begin >= of.size) {
                begin = 0;
            }
        }

        if (ngx_http_arg(r, slcf->end.data, slcf->end.len, &value) == NGX_OK) {

            end = ngx_atoof(value.data, value.len);

            if (end == NGX_ERROR || end >= of.size) {
                end = of.size;
            }
        }
    }

    end = end < begin ? of.size : end;

    len = (end == begin) ? 0 : ((end - begin)
            + ((begin == 0 && slcf->header_first) ? slcf->header.len : 0)
            + ((end == of.size && slcf->footer_last) ? slcf->footer.len : 0));

    log->action = "sending slice to client";

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = len;
    r->headers_out.last_modified_time = of.mtime;

    if (ngx_http_set_content_type(r) != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (len == 0) {
        r->header_only = 1;
        return ngx_http_send_header(r);
    }

    /*
     * add header when the first header is not denied
     */
    if (slcf->header.len
        && !(begin == 0 && !slcf->header_first))
    {
        b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
        if (b == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        b->pos = slcf->header.data;
        b->last = slcf->header.data + slcf->header.len;
        b->memory = 1;

        out[0].buf = b;
        out[0].next = &out[1];

        i = 0;
    } else {
        i = 1;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
    if (b->file == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    r->allow_ranges = 1;

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    b->file_pos = begin;
    b->file_last = end;

    b->in_file = b->file_last ? 1: 0;
    b->last_buf = 1;
    b->last_in_chain = 1;

    b->file->fd = of.fd;
    b->file->name = path;
    b->file->log = log;
    b->file->directio = of.is_directio;

    out[1].buf = b;
    out[1].next = NULL;

    /*
     * add footer when the last footer is not denied
     */
    if (slcf->footer.len
        && !(end == of.size && !slcf->footer_last))
    {
        b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
        if (b == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        b->pos = slcf->footer.data;
        b->last = slcf->footer.data + slcf->footer.len;
        b->memory = 1;
        b->last_buf = 1;
        b->last_in_chain = 1;

        out[2].buf = b;
        out[2].next = NULL;

        out[1].buf->last_buf = 0;
        out[1].buf->last_in_chain = 0;
        out[1].next = &out[2];
    }

    return ngx_http_output_filter(r, &out[i]);
}
static ngx_int_t 
ngx_http_weixin_auth(ngx_http_request_t *r)
{
    u_char     *p;
    ngx_int_t   rc;
    ngx_str_t   signature, str, array_str[3], tmp;
    ngx_sha1_t  sha;
    u_char      sha_buf[SHA_DIGEST_LENGTH];
    u_char      sha_buf_str[SHA_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
    ngx_http_weixin_auth_loc_conf_t *auth_conf;
    
    auth_conf = ngx_http_get_module_loc_conf(r, ngx_http_weixin_auth_module);
    
    if (ngx_http_arg(r, (u_char *) "signature", 9, &signature) != NGX_OK) {
        return NGX_DECLINED;
    }
    
    if (ngx_http_arg(r, (u_char *) "timestamp", 9, &array_str[0]) != NGX_OK) {
        return NGX_DECLINED;
    }
    
    if (ngx_http_arg(r, (u_char *) "nonce", 5, &array_str[1]) != NGX_OK) {
        return NGX_DECLINED;
    }
    
    if (signature.len != SHA_DIGEST_LENGTH * 2) {
        return NGX_DECLINED;
    }
    
    array_str[2] = auth_conf->token;
    
    //  token¡¢timestamp¡¢nonce
    if (ngx_memn2cmp(array_str[0].data, array_str[1].data, array_str[0].len, array_str[1].len) > 0) {
        tmp = array_str[0];
        array_str[0] = array_str[1];
        array_str[1] = tmp;
    }
    
    if (ngx_memn2cmp(array_str[1].data, array_str[2].data, array_str[1].len, array_str[2].len) > 0) {
        tmp = array_str[1];
        array_str[1] = array_str[2];
        array_str[2] = tmp;
    }

    if (ngx_memn2cmp(array_str[0].data, array_str[1].data, array_str[0].len, array_str[1].len) > 0) {
        tmp = array_str[0];
        array_str[0] = array_str[1];
        array_str[1] = tmp;
    }
    
    str.len = array_str[0].len + array_str[1].len + array_str[2].len;
    str.data = ngx_pcalloc(r->pool, str.len + 1);
    if (str.data == NULL) {
        return NGX_ERROR;
    }
    
    p = str.data;
    p = ngx_cpymem(p, array_str[0].data, array_str[0].len);
    p = ngx_cpymem(p, array_str[1].data, array_str[1].len);
    p = ngx_cpymem(p, array_str[2].data, array_str[2].len);
    p = '\0';
    
    ngx_sha1_init(&sha);
    ngx_sha1_update(&sha, str.data, str.len);
    ngx_sha1_final(sha_buf, &sha);
    
    p = ngx_hex_dump(sha_buf_str, sha_buf, SHA_DIGEST_LENGTH);
    p = '\0';
    
    rc = ngx_memcmp(sha_buf_str, signature.data, SHA_DIGEST_LENGTH * 2);
    if (rc != 0) {
        return NGX_DECLINED;
    }
    
    return NGX_OK;
}
示例#20
0
//-----------------------------------------------------------------------------
static int
ngx_c2h5oh_init_query_data(ngx_http_request_t *r, ngx_c2h5oh_ctx_t * ctx) {
  ngx_uint_t i;
  ngx_table_elt_t  **h;
  ngx_c2h5oh_loc_conf_t * alcf = ngx_http_get_module_loc_conf(r, ngx_c2h5oh_module);
  h = r->headers_in.cookies.elts;

  ngx_c2h5oh_query_data_set_len(r, ctx);
  ctx->query.data = ngx_palloc(r->pool, ctx->query.len);
  ctx->query.len = 0;
  ngx_memcpy(ctx->query.data, k_ngx_c2h5oh_select, sizeof(k_ngx_c2h5oh_select));//}', '{}')");
  ctx->query.len = sizeof(k_ngx_c2h5oh_select) - 1; 
  if (alcf->route.len == 0) {
    u_char * p = r->uri.data + 1 + alcf->root.len;
    if (r->uri.len == 1) {
      ngx_memcpy(ctx->query.data + ctx->query.len, "index", sizeof("index") - 1);
    } else {
      while(p < r->uri.data + r->uri.len) {
        if ((*p >= 0x30 && *p <= 0x39) || (*p >= 0x61 && *p <= 0x7a)) {
          *(ctx->query.data + ctx->query.len++) = *p;
        } else if (*p >= 0x41 && *p <= 0x5a) {
          *(ctx->query.data + ctx->query.len++) = *p + 0x20;
        } else if (*p == '/') {
          *(ctx->query.data + ctx->query.len++) = '_';
        }
        p++;
      }
      if (*(ctx->query.data + ctx->query.len - 1) == '_') {
        ctx->query.len--; 
      }
    }
    strcpy((char *)ctx->query.data + ctx->query.len, "('{");
    ctx->query.len += sizeof("('{") - 1; 

  } else {
    ngx_memcpy(ctx->query.data + ctx->query.len, alcf->route.data, alcf->route.len);
    ctx->query.len += alcf->route.len;

    strcpy((char *)ctx->query.data + ctx->query.len, "('");
    ctx->query.len += sizeof("('") - 1; 
    u_char * p = r->uri.data + alcf->root.len;
    while(p < r->uri.data + r->uri.len) {
      *(ctx->query.data + ctx->query.len++) = *p;
      if (*p == '\'') {
        *(ctx->query.data + ctx->query.len++) = *p;
      }
      p++;
    }
    *(ctx->query.data + ctx->query.len++) = '\'';
    *(ctx->query.data + ctx->query.len++) = ',';
    *(ctx->query.data + ctx->query.len++) = '\'';
    *(ctx->query.data + ctx->query.len++) = '{';
  }

  u_char * cookies_start = ctx->query.data + ctx->query.len;
  for(i = 0; i < r->headers_in.cookies.nelts; i++) {
    ngx_c2h5oh_parse_cookies(&ctx->query, &h[i]->value, cookies_start);
  }
  ngx_memcpy(ctx->query.data + ctx->query.len, "}','{", 5);
  ctx->query.len += sizeof("}','{") - 1; 
  u_char * args_start = ctx->query.data + ctx->query.len;
  if (ngx_http_arg(r, (u_char*)"callback", sizeof("callback") - 1, &ctx->callback) != NGX_OK) {
    ctx->callback.len = 0;
  }
  if (ngx_c2h5oh_parse_args(r, &ctx->query, r->args.data, r->args.data + r->args.len, args_start) != 0) {
    return -1;
  }
  if (r->request_body && r->request_body->buf && r->headers_in.content_type && r->request_body_in_single_buf) {
    if (r->request_body_in_single_buf) {
      if (ngx_memcmp(r->headers_in.content_type->value.data, "application/x-www-form-urlencoded", sizeof("application/x-www-form-urlencoded") - 1) == 0) {
        if (r->request_body->buf) {
          if (ngx_c2h5oh_parse_args(r, &ctx->query, r->request_body->buf->pos, r->request_body->buf->last, args_start) != 0) {
            return -1;
          }
        } else {
          ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "[c2h5oh] request_body is null");
        }
      } else {
        // TODO: pass whole body as parameter
      }
    } else {
      ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                    "[c2h5oh] request_body not in single buf");
    }
  }
  // TODO
  ngx_memcpy(ctx->query.data + ctx->query.len, "}');", sizeof("}');"));
  ctx->query.len += sizeof("}');"); 

  return 0;
}
static ngx_int_t ngx_hls_handler(ngx_http_request_t *r)
{
    //ngx_log_t *log = r->connection->log;
	
	if(!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))){
		return NGX_HTTP_NOT_ALLOWED;
	}
	ngx_http_hls_loc_conf_t *elcf = ngx_http_get_module_loc_conf(r,ngx_http_hls_module);

	char* media_type = ngx_http_hls_convert_string(elcf->media_type);
	char* media_path = ngx_http_hls_convert_string(elcf->media_path);
	//char *media_type = (char*)elcf->media_type.data;
	//char *media_path = (char*)elcf->media_path.data;
	ngx_int_t rc = ngx_http_discard_request_body(r);
	if(rc != NGX_OK){
		return rc;
	}

	if(strcmp(media_type,"live") == 0){
		//TODO:Live media.
	}
	else{
		ngx_str_t media_file;
		ngx_str_t media_start;
		ngx_str_t media_end;
		ngx_http_arg(r, (u_char *)"media", 5, &media_file);

		rc = ngx_http_arg(r,(u_char *)"start",5,&media_start);

		ngx_http_arg(r, (u_char *)"end", 3 , &media_end);

		if(rc == NGX_DECLINED || media_start.len == 0){
			char filename[512];
			bzero(filename,512);
			ngx_str_t type = ngx_string("application/x-mpegURL");//m3u8文件的content type
			ngx_snprintf((u_char*)filename,1024,"%s%V.m3u8",media_path,&media_file);
			
			//M3U8文件不存在,目前采用直接返回错误的方式,后期采用根据TS文件创建新的M3U8
			if(access((char*)filename,F_OK) == -1){
				ngx_log_error(NGX_LOG_CRIT,r->connection->log,0,"File[%s] is not exist!media_path = %s,media_file=%V",filename,media_path,&media_file);
				//r->headers_out.status = NGX_HTTP_NOT_FOUND;
				//rc = ngx_http_send_header(r);
				return NGX_HTTP_NOT_FOUND;	
			}
			else{
				ngx_chain_t *out = ngx_pcalloc(r->pool,sizeof(ngx_chain_t));
				ngx_buf_t *b;
				//b = ngx_create_temp_buf(r->pool,sizeof(ngx_buf_t));
				b = ngx_pcalloc(r->pool,sizeof(ngx_buf_t));
				if(b == NULL){
					return NGX_HTTP_INTERNAL_SERVER_ERROR;
				}
				b->in_file = 1;
				b->file = ngx_pcalloc(r->pool,sizeof(ngx_file_t));
				b->file->fd = ngx_open_file(filename,NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, NGX_FILE_OPEN, 0);
				if(b->file->fd == -1){
					return NGX_HTTP_INTERNAL_SERVER_ERROR;
				}
				b->file->name.data = (u_char*)filename;
				b->file->name.len = sizeof(filename) -1;
				if(ngx_file_info(filename,&b->file->info) == NGX_FILE_ERROR){
					return NGX_HTTP_INTERNAL_SERVER_ERROR;
				}
				
				r->headers_out.status = NGX_HTTP_OK;
				r->headers_out.content_length_n = b->file->info.st_size;
				r->headers_out.content_type = type;
				b->file_pos = 0;
				b->file_last = b->file->info.st_size;
				b->last_in_chain = 1;
				b->file->log = r->connection->log;
				b->last_buf = 1;
				

				//清理文件句柄
				/*
				ngx_pool_cleanup_t *cln = ngx_pool_cleanup_add(r->pool,sizeof(ngx_pool_cleanup_file_t));
				if(cln == NULL){
					return NGX_ERROR;
				}
				cln->handler = ngx_pool_cleanup_file;
				ngx_pool_cleanup_file_t *clnf = cln->data;
				clnf->fd = b->file->fd;
				clnf->name = b->file->name.data;
				clnf->log = r->pool->log;
				*/
				
				out->buf = b;
				out->next = NULL;
				rc = ngx_http_send_header(r);
				if(rc == NGX_ERROR || rc > NGX_OK || r->header_only)
				{
					return rc;
				}
				
				return ngx_http_output_filter(r,out);
			
			}
		}
		else{
			ngx_str_t type = ngx_string("video/mp2t");	//ts文件的content type
			//ngx_str_t type = ngx_string("application/octet-stream");
			char filename[512];
			bzero(filename,512);
			ngx_snprintf((u_char*)filename,512,"%s%V.ts",media_path,&media_file);
			ngx_log_error(NGX_LOG_CRIT,r->connection->log,0,"File[%s] is not exist!media_path = %s,media_file=%V",filename,media_path,&media_file);
			r->allow_ranges = 1; //开启range选项
			char *start = ngx_http_hls_convert_string(media_start);
			char *end = ngx_http_hls_convert_string(media_end);
			ngx_log_error(NGX_LOG_CRIT,r->connection->log,0,"start=%s;end=%s",start,end);
			ngx_chain_t *out = ngx_pcalloc(r->pool,sizeof(ngx_chain_t));
			ngx_buf_t *b = ngx_pcalloc(r->pool,sizeof(ngx_buf_t));
			if(b == NULL){
				return NGX_HTTP_INTERNAL_SERVER_ERROR;
			}
			b->in_file = 1;
			b->file = ngx_pcalloc(r->pool,sizeof(ngx_file_t));
			b->file->fd = ngx_open_file(filename,NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, NGX_FILE_OPEN,0);
			if(b->file->fd == -1){
				return NGX_HTTP_INTERNAL_SERVER_ERROR;
			}
			b->file->name.data = (u_char*)filename;
			b->file->name.len = sizeof(filename)-1;
		
			r->headers_out.status = NGX_HTTP_OK;
			r->headers_out.content_length_n = atol(end)-atol(start);
			 ngx_log_error(NGX_LOG_CRIT,r->connection->log,0,"%d",r->headers_out.content_length_n);
			r->headers_out.content_type = type;
			b->file_pos = atol(start);
			b->file_last= atol(end);
			b->last_in_chain = 1;
			b->file->log = r->connection->log;
			b->last_buf = 1;
			out->buf = b;
			out->next = NULL;

			rc = ngx_http_send_header(r);
			if(rc == NGX_ERROR || rc > NGX_OK || r->header_only)
			{
				return rc;
			}
			
			return ngx_http_output_filter(r,out);
			
		}	
	
	}
	return NGX_OK;
}
static ngx_int_t
ngx_http_flv_handler(ngx_http_request_t *r)
{
    u_char                    *last;
    off_t                      start, len;
    size_t                     root;
    ngx_int_t                  rc;
    ngx_uint_t                 level, i;
    ngx_str_t                  path, value;
    ngx_log_t                 *log;
    ngx_buf_t                 *b;
    ngx_chain_t                out[2];
    ngx_open_file_info_t       of;
    ngx_http_core_loc_conf_t  *clcf;

    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }

    if (r->uri.data[r->uri.len - 1] == '/') {
        return NGX_DECLINED;
    }

    rc = ngx_http_discard_request_body(r);

    if (rc != NGX_OK) {
        return rc;
    }

    last = ngx_http_map_uri_to_path(r, &path, &root, 0);
    if (last == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    log = r->connection->log;

    path.len = last - path.data;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
                   "http flv filename: \"%V\"", &path);

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    ngx_memzero(&of, sizeof(ngx_open_file_info_t));

    of.read_ahead = clcf->read_ahead;
    of.directio = clcf->directio;
    of.valid = clcf->open_file_cache_valid;
    of.min_uses = clcf->open_file_cache_min_uses;
    of.errors = clcf->open_file_cache_errors;
    of.events = clcf->open_file_cache_events;

    if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
        != NGX_OK)
    {
        switch (of.err) {

        case 0:
            return NGX_HTTP_INTERNAL_SERVER_ERROR;

        case NGX_ENOENT:
        case NGX_ENOTDIR:
        case NGX_ENAMETOOLONG:

            level = NGX_LOG_ERR;
            rc = NGX_HTTP_NOT_FOUND;
            break;

        case NGX_EACCES:

            level = NGX_LOG_ERR;
            rc = NGX_HTTP_FORBIDDEN;
            break;

        default:

            level = NGX_LOG_CRIT;
            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
            break;
        }

        if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
            ngx_log_error(level, log, of.err,
                          "%s \"%s\" failed", of.failed, path.data);
        }

        return rc;
    }

    if (!of.is_file) {

        if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                          ngx_close_file_n " \"%s\" failed", path.data);
        }

        return NGX_DECLINED;
    }

    r->root_tested = !r->error_page;

    start = 0;
    len = of.size;
    i = 1;

    if (r->args.len) {

        if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) {

            start = ngx_atoof(value.data, value.len);

            if (start == NGX_ERROR || start >= len) {
                start = 0;
            }

            if (start) {
                len = sizeof(ngx_flv_header) - 1 + len - start;
                i = 0;
            }
        }
    }

    log->action = "sending flv to client";

    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = len;
    r->headers_out.last_modified_time = of.mtime;

    if (ngx_http_set_content_type(r) != NGX_OK) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (i == 0) {
        b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
        if (b == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        b->pos = ngx_flv_header;
        b->last = ngx_flv_header + sizeof(ngx_flv_header) - 1;
        b->memory = 1;

        out[0].buf = b;
        out[0].next = &out[1];
    }


    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
    if (b->file == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    r->allow_ranges = 1;

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }

    b->file_pos = start;
    b->file_last = of.size;

    b->in_file = b->file_last ? 1: 0;
    b->last_buf = 1;
    b->last_in_chain = 1;

    b->file->fd = of.fd;
    b->file->name = path;
    b->file->log = log;
    b->file->directio = of.is_directio;

    out[1].buf = b;
    out[1].next = NULL;

    return ngx_http_output_filter(r, &out[i]);
}
示例#23
0
static ngx_int_t ngx_http_shmtest_get(ngx_http_request_t *r){
	ngx_int_t rc = NGX_HTTP_OK;
	ngx_str_t key = ngx_null_string;
	ngx_str_t value = ngx_null_string;
	int32_t ikey = 0;
	uint8_t value_type = VT_BINARY;
	uint32_t exptime = 0;
	uint32_t user_flags = 0;
	
	if(ngx_http_arg(r, (u_char*)"key", 3, &key)!=NGX_OK){
		NLOG_ERROR("get arg 'key' failed!");
		return NGX_HTTP_BAD_REQUEST;
	}
	if(key.len > 2 && key.data[0] == '0' &&	key.data[1] == 'x'){
		key.data += 2;
		key.len -= 2;
		ikey = ngx_hextoi(key.data, key.len);
		ngx_str_set_int32(&key, &ikey);
		NLOG_DEBUG("use int key ikey=%d", ikey);
	} 

	shmtest_main_conf_t* smcf;
	smcf = ngx_http_get_module_main_conf(r, ngx_http_shmtest_module);
	if(smcf == NULL){
		NLOG_ERROR("get module ngx_http_shmtest_module's main conf failed!");
		return NGX_HTTP_INTERNAL_SERVER_ERROR;
	}

	ngx_shm_zone_t* zone = smcf->shmap;
	u_char* rsp = ngx_pcalloc(r->connection->pool, 256);
	int rsp_len = 0;

	rc = ngx_shmap_get(zone, &key, &value, &value_type,
				&exptime, &user_flags);

	if(ikey != 0){
		if(rc == 0){
			rsp_len = ngx_sprintf(rsp, "get(%d)={value=%V,exptime=%d,user_flags=%d}!\n",
							ikey,&value,exptime,user_flags)-rsp;
		}else{
			rsp_len = ngx_sprintf(rsp, "get(%d) failed!\n", ikey)-rsp;
		}
	}else{
		if(rc == 0){
			rsp_len = ngx_sprintf(rsp, "get(%V)={value=%V,exptime=%d,user_flags=%d}!\n",
							&key,&value,exptime,user_flags)-rsp;
		}else{
			rsp_len = ngx_sprintf(rsp, "get(%V) failed!\n", &key)-rsp;
		}
	}

	ngx_chain_t* chain = ngx_http_shmtest_resp(r, (char*)rsp, rsp_len);
	if(chain != NULL){
	    r->headers_out.content_length_n = rsp_len;
	}else{
		r->headers_out.content_length_n = 0;
	}

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        
    }else{
    	rc = ngx_http_output_filter(r, chain);
    }

	return rc;
}
static ngx_int_t
ngx_screenshot_handler(ngx_http_request_t *r)
{
    size_t                              len;
    u_char                             *p;
    ngx_buf_t                          *b;
    ngx_chain_t                         cl;
    u_char                              path[1024];
    ExceptionInfo                      *exception;
    Image                              *image = 0, *resized = 0;
    ImageInfo                          *image_info = 0;
    unsigned char                      *image_data;
    ngx_str_t                           size;
    ngx_int_t                           width = -1, height = -1;
    ngx_screenshot_sizes_conf_t        *screenshot_sizes_conf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_screenshot_module);

    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "TEST %d", screenshot_sizes_conf->sizes.nelts);
    
    //TODO: generate unique name
    system("avconv -analyzeduration 1000 -i \"rtmp://127.0.0.1:1935\" -vframes 1 -q:v 2 -f image2 /tmp/output.png -loglevel quiet");

    MagickCoreGenesis("", MagickTrue);
    exception = AcquireExceptionInfo();
    
    ngx_memzero(path, sizeof(path));
    
    strcpy((char *)path, "/tmp/output.png");
    
    image_info = CloneImageInfo((ImageInfo *)NULL);
    strcpy(image_info->filename, (const char*)path);
    
    image = ReadImage(image_info, exception);
    
    if (image == 0) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to open screenshot file");
        goto error;
    }
    
    if (ngx_http_arg(r, (u_char *) "size", sizeof("size") - 1, &size) == NGX_OK) {
        
        if (size.len > 0) {
            if (size.data[0] == 'l' && size.data[1] == 'o' && size.data[2] == 'w') {
                width = 320;
                height = 180;
            }
            else if (size.data[0] == 'm' && size.data[1] == 'e' && size.data[2] == 'd') {
                width = 640;
                height = 360;
            }
            else if (size.data[0] == 'h' && size.data[1] == 'i') {
                width = 960;
                height = 540;
            }
            else if (size.data[0] == 'h' && size.data[1] == 'd') {
                width = 1280;
                height = 720;
            }
        }
    }
    
    if (width < 1 || width > (ngx_int_t)image->columns) {
        width = image->columns;
    }
    
    if (height < 1 || height > (ngx_int_t)image->rows) {
        height = image->rows;
    }
    
    if (width == (ngx_int_t)image->columns && height == (ngx_int_t)image->rows) {
        resized = image;
    }
    else {
        resized = ResizeImage(image, width, height, SincFilter, 1.0, exception);
    }
    
    if (resized == 0) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to resize screenshot file");
        goto error;
    }
    
    image_data = ImageToBlob(image_info, resized, &len, exception);
    
    p = ngx_palloc(r->connection->pool, len);
    if (p == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate memory for response");
        goto error;
    }
    
    ngx_memcpy(p, image_data, len);
    
    if (resized != image) {
        DestroyImage(resized);
    }
    
    DestroyImage(image);
    MagicComponentTerminus();
    
    ngx_str_set(&r->headers_out.content_type, "image/png");
    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = len;
    
    b = ngx_calloc_buf(r->pool);
    if (b == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to allocate memory for response");
        goto error;
    }
    
    b->start = b->pos = p;
    b->end = b->last = p + len;
    b->temporary = 1;
    b->last_buf = 1;
    
    ngx_memzero(&cl, sizeof(cl));
    cl.buf = b;
    
    ngx_http_send_header(r);
    
    return ngx_http_output_filter(r, &cl);
    
error:
    if (resized && resized != image) DestroyImage(resized);
    if (image) DestroyImage(image);
    
    MagicComponentTerminus();
    
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
static ngx_int_t
ngx_http_xss_header_filter(ngx_http_request_t *r)
{
    ngx_http_xss_ctx_t          *ctx;
    ngx_http_xss_loc_conf_t     *xlcf;
    ngx_str_t                    callback;
    u_char                      *p, *src, *dst;

    if (r != r->main) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped in subrequests");

        return ngx_http_next_header_filter(r);
    }

    xlcf = ngx_http_get_module_loc_conf(r, ngx_http_xss_filter_module);

    if (!xlcf->get_enabled) {
        return ngx_http_next_header_filter(r);
    }

    if (r->method != NGX_HTTP_GET) {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped due to the unmatched request method: %V",
                       &r->method_name);

        return ngx_http_next_header_filter(r);
    }

    if (xlcf->check_status) {

        if (r->headers_out.status != NGX_HTTP_OK
            && r->headers_out.status != NGX_HTTP_CREATED)
        {
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "xss skipped due to unmatched response status "
                           "\"%ui\"", r->headers_out.status);

            return ngx_http_next_header_filter(r);
        }
    }

    if (xlcf->callback_arg.len == 0) {

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xss: xss_get is enabled but no xss_callback_arg "
                      "specified");

        return ngx_http_next_header_filter(r);
    }

    if (ngx_http_test_content_type(r, &xlcf->input_types) == NULL) {

        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped due to unmatched Content-Type response "
                       "header");

        return ngx_http_next_header_filter(r);
    }

    if (ngx_http_arg(r, xlcf->callback_arg.data, xlcf->callback_arg.len,
                     &callback)
        != NGX_OK)
    {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped: no GET argument \"%V\" specified in "
                       "the request", &xlcf->callback_arg);

        return ngx_http_next_header_filter(r);
    }

    p = ngx_palloc(r->pool, callback.len);
    if (p == NULL) {
        return NGX_ERROR;
    }

    src = callback.data; dst = p;

    ngx_unescape_uri(&dst, &src, callback.len, NGX_UNESCAPE_URI_COMPONENT);

    if (src != callback.data + callback.len) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xss: unescape uri: input data not consumed completely");

        return NGX_ERROR;
    }

    callback.data = p;
    callback.len = dst - p;

    if (ngx_http_xss_test_callback(callback.data, callback.len) != NGX_OK) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xss: bad callback argument: \"%V\"", &callback);

        return ngx_http_next_header_filter(r);
    }

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

    /*
     * set by ngx_pcalloc():
     *
     *     ctx->callback = { 0, NULL };
     *     ctx->before_body_sent = 0;
     */

    ctx->callback = callback;

    ngx_http_set_ctx(r, ctx, ngx_http_xss_filter_module);

    r->headers_out.content_type = xlcf->output_type;
    r->headers_out.content_type_len = xlcf->output_type.len;
    r->headers_out.content_type_lowcase = NULL;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "xss output Content-Type header \"%V\"",
                   &xlcf->output_type);

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    if (xlcf->override_status
        && r->headers_out.status >= NGX_HTTP_SPECIAL_RESPONSE)
    {
        r->headers_out.status = NGX_HTTP_OK;
    }

    return ngx_http_next_header_filter(r);
}
示例#26
0
static ngx_int_t
ngx_http_restful_parse_action_raw(ngx_http_request_t *r,
    ngx_http_tfs_restful_ctx_t *ctx)
{
    ngx_int_t  rc;
    ngx_str_t  arg_value;

    switch(r->method) {
    case NGX_HTTP_GET:
        if (ngx_http_arg(r, (u_char *) "suffix", 6, &arg_value) == NGX_OK) {
            ctx->file_suffix = arg_value;
        }

        rc = ngx_http_tfs_raw_fsname_parse(&ctx->file_path_s, &ctx->file_suffix,
                                           &ctx->fsname);
        if (rc != NGX_OK) {
            return NGX_HTTP_BAD_REQUEST;
        }

        if (ngx_http_arg(r, (u_char *) "type", 4, &arg_value) == NGX_OK) {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->read_stat_type = ngx_atoi(arg_value.data, arg_value.len);
            /* normal_read/stat(0) or force_read/stat(1) */
            if (ctx->read_stat_type == NGX_ERROR
                || (ctx->read_stat_type != NGX_HTTP_TFS_READ_STAT_NORMAL
                    && ctx->read_stat_type != NGX_HTTP_TFS_READ_STAT_FORCE))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }
        if (ctx->meta) {
            ctx->action.code = NGX_HTTP_TFS_ACTION_STAT_FILE;
            ngx_str_set(&ctx->action.msg, "stat_file");

        } else {
            ctx->action.code = NGX_HTTP_TFS_ACTION_READ_FILE;
            ngx_str_set(&ctx->action.msg, "read_file");
            if (ngx_http_arg(r, (u_char *) "offset", 6, &arg_value) == NGX_OK) {
                ctx->offset = ngx_http_tfs_atoll(arg_value.data, arg_value.len);
                if (ctx->offset == NGX_ERROR) {
                    return NGX_HTTP_BAD_REQUEST;
                }
            }

            if (ngx_http_arg(r, (u_char *) "size", 4, &arg_value) == NGX_OK) {
                rc = ngx_http_tfs_atoull(arg_value.data,
                                         arg_value.len,
                                         (unsigned long long *)&ctx->size);
                if (rc == NGX_ERROR) {
                    return NGX_HTTP_BAD_REQUEST;
                }

                if (ctx->size == 0) {
                    return NGX_HTTP_BAD_REQUEST;
                }

                return NGX_OK;
            }

            ctx->size = NGX_HTTP_TFS_MAX_SIZE;
        }
        break;

    case NGX_HTTP_POST:
        ctx->action.code = NGX_HTTP_TFS_ACTION_WRITE_FILE;
        if (ngx_http_arg(r, (u_char *) "suffix", 6, &arg_value) == NGX_OK) {
            ctx->file_suffix = arg_value;
        }

        if (ngx_http_arg(r, (u_char *) "simple_name", 11, &arg_value)
            == NGX_OK)
        {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->simple_name = ngx_atoi(arg_value.data, arg_value.len);
            if (ctx->simple_name == NGX_ERROR
                || (ctx->simple_name != NGX_HTTP_TFS_NO
                    && ctx->simple_name != NGX_HTTP_TFS_YES))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }

        if (ngx_http_arg(r, (u_char *) "large_file", 10, &arg_value)
            == NGX_OK)
        {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->large_file = ngx_atoi(arg_value.data, arg_value.len);
            if (ctx->large_file == NGX_ERROR
                || (ctx->large_file != NGX_HTTP_TFS_NO
                    && ctx->large_file != NGX_HTTP_TFS_YES))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }

        if (ngx_http_arg(r, (u_char *) "meta_segment", 12, &arg_value)
            == NGX_OK)
        {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->write_meta_segment = ngx_atoi(arg_value.data, arg_value.len);
            if (ctx->write_meta_segment == NGX_ERROR
                || (ctx->write_meta_segment != NGX_HTTP_TFS_NO
                    && ctx->write_meta_segment != NGX_HTTP_TFS_YES))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }

        if (ngx_http_arg(r, (u_char *) "no_dedup", 8, &arg_value) == NGX_OK) {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->no_dedup = ngx_atoi(arg_value.data, arg_value.len);
            if (ctx->no_dedup == NGX_ERROR
                || (ctx->no_dedup != NGX_HTTP_TFS_NO
                    && ctx->no_dedup != NGX_HTTP_TFS_YES))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }

        ngx_str_set(&ctx->action.msg, "write_file");
        break;

    case NGX_HTTP_DELETE:
        ctx->action.code = NGX_HTTP_TFS_ACTION_REMOVE_FILE;
        ngx_str_set(&ctx->action.msg, "remove_file");

        /* for outer user use */
        if (ngx_http_arg(r, (u_char *) "hide", 4, &arg_value) == NGX_OK) {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->unlink_type = ngx_atoi(arg_value.data, arg_value.len);
            /* hide(1) or reveal(0)*/
            if (ctx->unlink_type == NGX_ERROR
                || (ctx->unlink_type != 0 && ctx->unlink_type != 1))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
            /* convert to actual type */
            if (ctx->unlink_type == 1) {
                ctx->unlink_type = NGX_HTTP_TFS_UNLINK_CONCEAL;

            } else {
                ctx->unlink_type = NGX_HTTP_TFS_UNLINK_REVEAL;
            }
        }

        if (ngx_http_arg(r, (u_char *) "type", 4, &arg_value) == NGX_OK) {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->unlink_type = ngx_atoi(arg_value.data, arg_value.len);
            /* del(0) or undel(2) or hide(4) or reveal(6)*/
            if (ctx->unlink_type == NGX_ERROR
                || (ctx->unlink_type != NGX_HTTP_TFS_UNLINK_DELETE
                    && ctx->unlink_type != NGX_HTTP_TFS_UNLINK_UNDELETE
                    && ctx->unlink_type != NGX_HTTP_TFS_UNLINK_CONCEAL
                    && ctx->unlink_type != NGX_HTTP_TFS_UNLINK_REVEAL))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }

        if (ngx_http_arg(r, (u_char *) "suffix", 6, &arg_value) == NGX_OK) {
            ctx->file_suffix = arg_value;
        }

        rc = ngx_http_tfs_raw_fsname_parse(&ctx->file_path_s, &ctx->file_suffix,
                                           &ctx->fsname);
        if (rc != NGX_OK) {
            return NGX_HTTP_BAD_REQUEST;
        }

        /* large file not support UNDELETE */
        if ((ctx->fsname.file_type == NGX_HTTP_TFS_LARGE_FILE_TYPE)
            && ctx->unlink_type == NGX_HTTP_TFS_UNLINK_UNDELETE)
        {
            return NGX_HTTP_BAD_REQUEST;
        }
        break;

    case NGX_HTTP_HEAD:
        if (ngx_http_arg(r, (u_char *) "suffix", 6, &arg_value) == NGX_OK) {
            ctx->file_suffix = arg_value;
        }

        rc = ngx_http_tfs_raw_fsname_parse(&ctx->file_path_s, &ctx->file_suffix,
                                           &ctx->fsname);
        if (rc != NGX_OK) {
            return NGX_HTTP_BAD_REQUEST;
        }

        if (ngx_http_arg(r, (u_char *) "type", 4, &arg_value) == NGX_OK) {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->read_stat_type = ngx_atoi(arg_value.data, arg_value.len);
            /* normal_read/stat(0) or force_read/stat(1) */
            if (ctx->read_stat_type == NGX_ERROR
                || (ctx->read_stat_type != NGX_HTTP_TFS_READ_STAT_NORMAL
                    && ctx->read_stat_type != NGX_HTTP_TFS_READ_STAT_FORCE))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }
        ctx->action.code = NGX_HTTP_TFS_ACTION_STAT_FILE;
        ngx_str_set(&ctx->action.msg, "stat_file");
        ctx->chk_exist = NGX_HTTP_TFS_YES;
        break;

    case NGX_HTTP_PUT:
        ctx->action.code = NGX_HTTP_TFS_ACTION_WRITE_FILE;
        if (ngx_http_arg(r, (u_char *) "suffix", 6, &arg_value) == NGX_OK) {
            ctx->file_suffix = arg_value;
        }

        if (ngx_http_arg(r, (u_char *) "simple_name", 11, &arg_value)
            == NGX_OK)
        {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->simple_name = ngx_atoi(arg_value.data, arg_value.len);
            if (ctx->simple_name == NGX_ERROR
                || (ctx->simple_name != NGX_HTTP_TFS_NO
                    && ctx->simple_name != NGX_HTTP_TFS_YES))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }

        if (ctx->file_path_s.data == NULL) {
            return NGX_HTTP_BAD_REQUEST;
        }

        /* large file not support update */
        if (ngx_http_arg(r, (u_char *) "large_file", 10, &arg_value) == NGX_OK) {
            return NGX_HTTP_BAD_REQUEST;
        }

        rc = ngx_http_tfs_raw_fsname_parse(&ctx->file_path_s, &ctx->file_suffix,
                                           &ctx->fsname);
        /* large file not support update */
        if (rc != NGX_OK
            || (ctx->fsname.file_type == NGX_HTTP_TFS_LARGE_FILE_TYPE))
        {
            return NGX_HTTP_BAD_REQUEST;
        }

        ctx->is_raw_update = NGX_HTTP_TFS_YES;
        ngx_str_set(&ctx->action.msg, "write_file");
        break;

    default:
        return NGX_HTTP_BAD_REQUEST;
    }

    return NGX_OK;
}
示例#27
0
static ngx_int_t
ngx_http_restful_parse_action(ngx_http_request_t *r,
    ngx_http_tfs_restful_ctx_t *ctx)
{
    ngx_int_t  rc;
    ngx_str_t  arg_value, file_path_d, file_temp_path;

    switch(r->method) {
    case NGX_HTTP_GET:
        if (ctx->get_appid) {
            ctx->action.code = NGX_HTTP_TFS_ACTION_GET_APPID;
            ngx_str_set(&ctx->action.msg, "get_appid");
            return NGX_OK;
        }
        if (ctx->file_type == NGX_HTTP_TFS_CUSTOM_FT_FILE) {
            if (ctx->meta) {
                ctx->action.code = NGX_HTTP_TFS_ACTION_LS_FILE;
                ngx_str_set(&ctx->action.msg, "ls_file");
                return NGX_OK;
            }

            ctx->action.code = NGX_HTTP_TFS_ACTION_READ_FILE;
            ngx_str_set(&ctx->action.msg, "read_file");

            if (r->headers_in.range != NULL) {
                return NGX_HTTP_BAD_REQUEST;
            }

            if (ngx_http_arg(r, (u_char *) "check_hole", 10, &arg_value)
                == NGX_OK)
            {
                ctx->chk_file_hole = ngx_atoi(arg_value.data, arg_value.len);
                if (ctx->chk_file_hole == NGX_ERROR
                    || (ctx->chk_file_hole != NGX_HTTP_TFS_NO
                        && ctx->chk_file_hole != NGX_HTTP_TFS_YES))
                {
                    return NGX_HTTP_BAD_REQUEST;
                }
            }

            if (ngx_http_arg(r, (u_char *) "offset", 6, &arg_value) == NGX_OK) {
                ctx->offset = ngx_http_tfs_atoll(arg_value.data, arg_value.len);
                if (ctx->offset == NGX_ERROR) {
                    return NGX_HTTP_BAD_REQUEST;
                }
            }

            if (ngx_http_arg(r, (u_char *) "size", 4, &arg_value) == NGX_OK) {
                rc = ngx_http_tfs_atoull(arg_value.data, arg_value.len,
                                         (unsigned long long *)&ctx->size);
                if (rc == NGX_ERROR) {
                    return NGX_HTTP_BAD_REQUEST;
                }
                if (ctx->size == 0) {
                    return NGX_HTTP_BAD_REQUEST;
                }
                return NGX_OK;
            }

            ctx->size = NGX_HTTP_TFS_MAX_SIZE;

            return NGX_OK;
        }

        ctx->action.code = NGX_HTTP_TFS_ACTION_LS_DIR;
        ngx_str_set(&ctx->action.msg, "ls_dir");
        return NGX_OK;
    case NGX_HTTP_POST:
        if (ngx_http_tfs_parse_headerin(r, &ali_move_source, &file_path_d)
            == NGX_OK)
        {
            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                          "move from %V to %V",
                          &file_path_d, &ctx->file_path_s);

            if (file_path_d.len < 1
                || file_path_d.len > NGX_HTTP_TFS_MAX_FILE_NAME_LEN
                || ctx->file_path_s.len == 1)
            {
                return NGX_HTTP_BAD_REQUEST;
            }

            if (ctx->file_path_s.len == file_path_d.len
                && ngx_strncmp(ctx->file_path_s.data, file_path_d.data,
                               file_path_d.len) == 0)
            {
                return NGX_HTTP_BAD_REQUEST;
            }

            file_temp_path = ctx->file_path_s;
            ctx->file_path_s = file_path_d;
            ctx->file_path_d = file_temp_path;
            if (ctx->file_type == NGX_HTTP_TFS_CUSTOM_FT_FILE) {
                ctx->action.code = NGX_HTTP_TFS_ACTION_MOVE_FILE;
                ngx_str_set(&ctx->action.msg, "move_file");

            } else {
                ctx->action.code = NGX_HTTP_TFS_ACTION_MOVE_DIR;
                ngx_str_set(&ctx->action.msg, "move_dir");
            }

        } else {
            if (ctx->file_type == NGX_HTTP_TFS_CUSTOM_FT_FILE) {
                ctx->action.code = NGX_HTTP_TFS_ACTION_CREATE_FILE;
                ngx_str_set(&ctx->action.msg, "create_file");

            } else {
                /* forbid create "/" */
                if (ctx->file_path_s.len == 1) {
                    return NGX_HTTP_BAD_REQUEST;
                }

                ctx->action.code = NGX_HTTP_TFS_ACTION_CREATE_DIR;
                ngx_str_set(&ctx->action.msg, "create_dir");
            }
        }
        if (ngx_http_arg(r, (u_char *) "recursive", 9, &arg_value) == NGX_OK) {
            if (arg_value.len != 1) {
                return NGX_HTTP_BAD_REQUEST;
            }
            ctx->recursive = ngx_atoi(arg_value.data, arg_value.len);
            if (ctx->recursive == NGX_ERROR
                || (ctx->recursive != NGX_HTTP_TFS_NO
                    && ctx->recursive != NGX_HTTP_TFS_YES))
            {
                return NGX_HTTP_BAD_REQUEST;
            }
        }
        break;
    case NGX_HTTP_PUT:
        if (ctx->file_type == NGX_HTTP_TFS_CUSTOM_FT_FILE) {
            ctx->action.code = NGX_HTTP_TFS_ACTION_WRITE_FILE;
            ngx_str_set(&ctx->action.msg, "write_file");
            if (ngx_http_arg(r, (u_char *) "offset", 6, &arg_value) == NGX_OK) {
                ctx->offset = ngx_http_tfs_atoll(arg_value.data, arg_value.len);
                if (ctx->offset == NGX_ERROR) {
                    return NGX_HTTP_BAD_REQUEST;
                }

            } else {
                /* no specify offset, append by default */
                ctx->offset = NGX_HTTP_TFS_APPEND_OFFSET;
            }
            return NGX_OK;
        }
        /* forbid put aciont on dir */
        return NGX_ERROR;
    case NGX_HTTP_DELETE:
        if (ctx->file_type == NGX_HTTP_TFS_CUSTOM_FT_FILE) {
            ctx->action.code = NGX_HTTP_TFS_ACTION_REMOVE_FILE;
            ngx_str_set(&ctx->action.msg, "remove_file");
            /* for t->file.left_length */
            ctx->size = NGX_HTTP_TFS_MAX_SIZE;

            return NGX_OK;
        }

        /* forbid delete "/" */
        if (ctx->file_path_s.len == 1) {
            return NGX_HTTP_BAD_REQUEST;
        }

        ctx->action.code = NGX_HTTP_TFS_ACTION_REMOVE_DIR;
        ngx_str_set(&ctx->action.msg, "remove_dir");
        break;
    case NGX_HTTP_HEAD:
        if (ctx->file_type == NGX_HTTP_TFS_CUSTOM_FT_FILE) {
            ctx->action.code = NGX_HTTP_TFS_ACTION_LS_FILE;
            ngx_str_set(&ctx->action.msg, "ls_file");

        } else {
            ctx->action.code = NGX_HTTP_TFS_ACTION_LS_DIR;
            ngx_str_set(&ctx->action.msg, "ls_dir");
        }
        ctx->chk_exist = NGX_HTTP_TFS_YES;
        return NGX_OK;
    }

    return NGX_OK;
}
static ngx_int_t
ngx_http_conhash_test_handler(ngx_http_request_t *r)
{
    ngx_int_t                            rc, cmd;
    ngx_chain_t                          out;
    ngx_str_t                            value;
    ngx_conhash_t                       *conhash;
    ngx_http_conhash_test_main_conf_t   *ctmcf;
    
    ctmcf = ngx_http_get_module_main_conf(r, ngx_http_conhash_test_module);
    
    conhash = ctmcf->conhash;

    out.buf = NULL;
    out.next = NULL;
    
    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
        return NGX_HTTP_NOT_ALLOWED;
    }
    
    if (conhash == NULL) {
        return NGX_DECLINED;
    }
    
    rc = ngx_http_arg(r, (u_char *) KEY_STR, sizeof(KEY_STR) - 1, &value);
    if (rc != NGX_OK) {
        return rc;
    }
    
    cmd = ngx_atoi(value.data, value.len);
    if (cmd < 1 && cmd > 4) {
        return NGX_DECLINED;
    }
    
    switch (cmd) {
        case 1:         //  add
            rc = ngx_http_conhash_test_add(r, conhash, &out);
            break;
        case 2:         //  del
            rc = ngx_http_conhash_test_del(r, conhash, &out);
            break;
        case 3:         //  search
            rc = ngx_http_conhash_test_search(r, conhash, &out);
            break;
        case 4:         //  traverse
            rc = ngx_http_conhash_test_traverse(r, conhash, &out);
            break;
        case 5:         //  clear
            rc = ngx_http_conhash_test_clear(r, conhash, &out);
            break;
    }
    
    if (rc != NGX_OK) {
        return rc;
    }
    
    r->headers_out.status = NGX_HTTP_OK;
    ngx_str_set(&r->headers_out.content_type, "text/plain");
    
    if (out.buf != NULL) {
        r->headers_out.content_length_n = ngx_buf_size(out.buf);
    } else {
        r->header_only = 1;
        r->headers_out.content_length_n = 0;
    }
    
    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        return rc;
    }
    
    return ngx_http_output_filter(r, &out);
}
static ngx_int_t
ngx_http_push_stream_subscriber_polling_handler(ngx_http_request_t *r, ngx_http_push_stream_requested_channel_t *channels_ids, time_t if_modified_since, ngx_str_t *last_event_id, ngx_flag_t longpolling, ngx_pool_t *temp_pool)
{
    ngx_http_push_stream_loc_conf_t                *cf = ngx_http_get_module_loc_conf(r, ngx_http_push_stream_module);
    ngx_slab_pool_t                                *shpool = (ngx_slab_pool_t *)ngx_http_push_stream_shm_zone->shm.addr;
    ngx_http_push_stream_subscriber_ctx_t          *ctx = ngx_http_get_module_ctx(r, ngx_http_push_stream_module);
    ngx_http_push_stream_requested_channel_t       *cur;
    ngx_http_push_stream_subscriber_t              *worker_subscriber;
    ngx_http_push_stream_channel_t                 *channel;
    ngx_http_push_stream_subscription_t            *subscription;
    ngx_str_t                                      *etag = NULL, vv_etag = ngx_null_string;
    ngx_int_t                                       tag;
    time_t                                          greater_message_time;
    ngx_int_t                                       greater_message_tag;
    ngx_flag_t                                      has_message_to_send = 0;
    ngx_str_t                                       callback_function_name;

    if (cf->last_received_message_tag != NULL) {
        ngx_http_push_stream_complex_value(r, cf->last_received_message_tag, &vv_etag);
        etag = vv_etag.len ? &vv_etag : NULL;
    } else {
        etag = ngx_http_push_stream_get_header(r, &NGX_HTTP_PUSH_STREAM_HEADER_IF_NONE_MATCH);
    }

    if (ngx_http_arg(r, NGX_HTTP_PUSH_STREAM_CALLBACK.data, NGX_HTTP_PUSH_STREAM_CALLBACK.len, &callback_function_name) == NGX_OK) {
        ngx_http_push_stream_unescape_uri(&callback_function_name);
        if ((ctx->callback = ngx_http_push_stream_get_formatted_chunk(callback_function_name.data, callback_function_name.len, r->pool)) == NULL) {
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: unable to allocate memory for callback function name");
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
    }

    tag = ((etag != NULL) && ((tag = ngx_atoi(etag->data, etag->len)) != NGX_ERROR)) ? ngx_abs(tag) : -1;

    greater_message_tag = tag;
    greater_message_time = if_modified_since = (if_modified_since < 0) ? 0 : if_modified_since;

    ngx_shmtx_lock(&shpool->mutex);

    // check if has any message to send
    cur = channels_ids;
    while ((cur = (ngx_http_push_stream_requested_channel_t *) ngx_queue_next(&cur->queue)) != channels_ids) {
        channel = ngx_http_push_stream_find_channel(cur->id, r->connection->log);
        if (channel == NULL) {
            // channel not found
            ngx_shmtx_unlock(&shpool->mutex);
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: unable to allocate shared memory for channel %s", cur->id->data);
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        if (ngx_http_push_stream_has_old_messages_to_send(channel, cur->backtrack_messages, if_modified_since, tag, greater_message_time, greater_message_tag, last_event_id)) {
            has_message_to_send = 1;
            if (channel->last_message_time > greater_message_time) {
                greater_message_time = channel->last_message_time;
                greater_message_tag = channel->last_message_tag;
            } else {
                if ((channel->last_message_time == greater_message_time) && (channel->last_message_tag > greater_message_tag) ) {
                    greater_message_tag = channel->last_message_tag;
                }
            }
        }
    }


    if (longpolling && !has_message_to_send) {
        // long polling mode without messages
        if ((worker_subscriber = ngx_http_push_stream_subscriber_prepare_request_to_keep_connected(r)) == NULL) {
            ngx_shmtx_unlock(&shpool->mutex);
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        worker_subscriber->longpolling = 1;

        if (ngx_http_push_stream_registry_subscriber_locked(r, worker_subscriber) == NGX_ERROR) {
            ngx_shmtx_unlock(&shpool->mutex);
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        // adding subscriber to channel(s)
        cur = channels_ids;
        while ((cur = (ngx_http_push_stream_requested_channel_t *) ngx_queue_next(&cur->queue)) != channels_ids) {
            if ((channel = ngx_http_push_stream_find_channel(cur->id, r->connection->log)) == NULL) {
                // channel not found
                ngx_shmtx_unlock(&shpool->mutex);
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: unable to allocate shared memory for channel %s", cur->id->data);
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            if ((subscription = ngx_http_push_stream_create_channel_subscription(r, channel, worker_subscriber)) == NULL) {
                ngx_shmtx_unlock(&shpool->mutex);
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            ngx_http_push_stream_assing_subscription_to_channel_locked(shpool, cur->id, subscription, &worker_subscriber->subscriptions_sentinel, r->connection->log);
        }

        ngx_shmtx_unlock(&shpool->mutex);
        return NGX_DONE;
    }

    ngx_shmtx_unlock(&shpool->mutex);

    // polling or long polling without messages to send

    ngx_http_push_stream_add_polling_headers(r, greater_message_time, greater_message_tag, temp_pool);

    if (!has_message_to_send) {
        // polling subscriber requests get a 304 with their entity tags preserved if don't have new messages.
        return ngx_http_push_stream_send_only_header_response(r, NGX_HTTP_NOT_MODIFIED, NULL);
    }

    // polling with messages or long polling without messages to send
    r->headers_out.status = NGX_HTTP_OK;
    r->headers_out.content_length_n = -1;

    ngx_http_push_stream_add_response_header(r, &NGX_HTTP_PUSH_STREAM_HEADER_TRANSFER_ENCODING, &NGX_HTTP_PUSH_STREAM_HEADER_CHUNCKED);
    ngx_http_send_header(r);

    // sending response content header
    if (ngx_http_push_stream_send_response_content_header(r, cf) == NGX_ERROR) {
        ngx_log_error(NGX_LOG_ERR, (r)->connection->log, 0, "push stream module: could not send content header to subscriber");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (ctx->callback != NULL) {
        ngx_http_push_stream_send_response_text(r, ctx->callback->data, ctx->callback->len, 0);
        ngx_http_push_stream_send_response_text(r, NGX_HTTP_PUSH_STREAM_CALLBACK_INIT_CHUNK.data, NGX_HTTP_PUSH_STREAM_CALLBACK_INIT_CHUNK.len, 0);
    }

    cur = channels_ids;
    while ((cur = (ngx_http_push_stream_requested_channel_t *) ngx_queue_next(&cur->queue)) != channels_ids) {
        channel = ngx_http_push_stream_find_channel(cur->id, r->connection->log);
        if (channel == NULL) {
            // channel not found
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "push stream module: unable to allocate shared memory for channel %s", cur->id->data);
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }
        ngx_http_push_stream_send_old_messages(r, channel, cur->backtrack_messages, if_modified_since, tag, greater_message_time, greater_message_tag, last_event_id);
    }

    if (ctx->callback != NULL) {
        ngx_http_push_stream_send_response_text(r, NGX_HTTP_PUSH_STREAM_CALLBACK_END_CHUNK.data, NGX_HTTP_PUSH_STREAM_CALLBACK_END_CHUNK.len, 0);
    }

    if (cf->footer_template.len > 0) {
        ngx_http_push_stream_send_response_text(r, cf->footer_template.data, cf->footer_template.len, 0);
    }

    ngx_http_push_stream_send_response_text(r, NGX_HTTP_PUSH_STREAM_LAST_CHUNK.data, NGX_HTTP_PUSH_STREAM_LAST_CHUNK.len, 1);

    return NGX_OK;
}
示例#30
0
static ngx_int_t ngx_http_shmtest_add_or_update(ngx_http_request_t *r,int func){
	ngx_int_t rc = NGX_HTTP_OK;
	ngx_str_t key = ngx_null_string;
	int32_t ikey = 0;
	ngx_str_t value = ngx_null_string;
 	char* szFunc = funcs[func];
	
	if(ngx_http_arg(r, (u_char*)"key", 3, &key)!=NGX_OK){
		NLOG_ERROR("get arg 'key' failed!");
		return NGX_HTTP_BAD_REQUEST;
	}

	if(ngx_http_arg(r, (u_char*)"value", 5, &value)!=NGX_OK){
		NLOG_ERROR("get arg 'value' failed!");
		return NGX_HTTP_BAD_REQUEST;
	}

	//如果key开始为0x 表示使用数字的KEY.
	if(key.len > 2 && key.data[0] == '0' &&	key.data[1] == 'x'){
		key.data += 2;
		key.len -= 2;
		ikey = ngx_hextoi(key.data, key.len);
		ngx_str_set_int32(&key, &ikey);
		NLOG_DEBUG("use int key ikey=%d", ikey);
	}
	
	uint64_t exptime = 0;
	ngx_str_t sexptime = ngx_null_string;
	if(ngx_http_arg(r, (u_char*)"exptime", 7, &sexptime)==NGX_OK){
		exptime = ngx_parse_time(&sexptime, 1);
	}

	if(ikey != 0){
		NLOG_DEBUG("%s(key=%d,value=%V,exptime=%d)", szFunc,ikey,&value,exptime);
	}else{
		NLOG_DEBUG("%s(key=%V,value=%V,exptime=%d)", szFunc,&key,&value,exptime);
	}
	shmtest_main_conf_t* smcf;
	smcf = ngx_http_get_module_main_conf(r, ngx_http_shmtest_module);
	if(smcf == NULL){
		NLOG_ERROR("get module ngx_http_shmtest_module's main conf failed!");
		return NGX_HTTP_INTERNAL_SERVER_ERROR;
	}

	ngx_shm_zone_t* zone = smcf->shmap;
	
	int ret = 0;
	switch(func){
	case FUNC_ADD:
		ret = ngx_shmap_add(zone, &key,&value,VT_STRING,exptime,0);
	break;
	case FUNC_SET:
		ret = ngx_shmap_set(zone, &key,&value,VT_STRING,exptime,0);
	break;
	case FUNC_REPLACE:
		ret = ngx_shmap_replace(zone, &key,&value,VT_STRING,exptime,0);
	break;
	default:
		NLOG_ERROR("un process type [%d]", func);
		return NGX_HTTP_BAD_REQUEST;
	}

	char* rsp = ngx_pcalloc(r->connection->pool, 256);
	int rsp_len = 0;
	if(ret == 0){
		rsp_len = sprintf(rsp, "%s success!\n", szFunc);
	}else{
		rsp_len = sprintf(rsp, "%s failed!\n", szFunc);
	}

	ngx_chain_t* chain = ngx_http_shmtest_resp(r, rsp, rsp_len);
	if(chain != NULL){
	    r->headers_out.content_length_n = rsp_len;
	}else{
		r->headers_out.content_length_n = 0;
	}

    rc = ngx_http_send_header(r);

    if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
        
    }else{
    	rc = ngx_http_output_filter(r, chain);
    }

	return rc;
}