Ejemplo n.º 1
0
ngx_int_t ngx_mrb_run_body_filter(ngx_http_request_t *r, ngx_mrb_state_t *state, ngx_mrb_code_t *code, ngx_flag_t cached, ngx_http_mruby_ctx_t *ctx)
{
    mrb_value ARGV, mrb_result;

    ARGV = mrb_ary_new_capa(state->mrb, 1);

    mrb_ary_push(state->mrb, ARGV, mrb_str_new(state->mrb, (char *)ctx->body, ctx->body_length));
    mrb_define_global_const(state->mrb, "ARGV", ARGV);

    mrb_result = mrb_run(state->mrb, mrb_proc_new(state->mrb, state->mrb->irep[code->n]), mrb_top_self(state->mrb));
    if (state->mrb->exc) {
        if (code->code_type == NGX_MRB_CODE_TYPE_FILE) {
            ngx_mrb_raise_file_error(state->mrb, mrb_obj_value(state->mrb->exc), r, code->code.file);
        } else {
            ngx_mrb_raise_error(state->mrb, mrb_obj_value(state->mrb->exc), r);
        }
        mrb_gc_arena_restore(state->mrb, state->ai);
        if (!cached) {
            ngx_mrb_irep_clean(r, state, code);
            ngx_mrb_state_clean(r, state);
        }
        return NGX_ERROR;
    }
    
    if (mrb_type(mrb_result) != MRB_TT_STRING) {
        mrb_result = mrb_funcall(state->mrb, mrb_result, "to_s", 0, NULL);
    }

    ctx->body        = (u_char *)RSTRING_PTR(mrb_result);
    ctx->body_length = ngx_strlen(ctx->body);

    mrb_gc_arena_restore(state->mrb, state->ai);
    if (!cached) {
        ngx_mrb_irep_clean(r, state, code);
        ngx_mrb_state_clean(r, state);
    }
    return NGX_OK;
}
Ejemplo n.º 2
0
ngx_int_t ngx_mrb_run(ngx_http_request_t *r, ngx_mrb_state_t *state, ngx_flag_t cached)
{
    ngx_mruby_ctx_t *ctx;
    rputs_chain_list_t *chain;
    if (state == NGX_CONF_UNSET_PTR) {
        return NGX_DECLINED;
    }
    if ((ctx = ngx_pcalloc(r->pool, sizeof(*ctx))) == NULL) {
        ngx_log_error(NGX_LOG_ERR
            , r->connection->log
            , 0
            , "failed to allocate memory from r->pool %s:%d"
            , __FUNCTION__
            , __LINE__
        );
        return NGX_ERROR;
    }
    ngx_http_set_ctx(r, ctx, ngx_http_mruby_module);
    ngx_mrb_push_request(r);
    mrb_run(state->mrb, mrb_proc_new(state->mrb, state->mrb->irep[state->n]), mrb_nil_value());
    if (state->mrb->exc) {
        if (state->code_type == NGX_MRB_CODE_TYPE_FILE) {
            ngx_mrb_raise_file_error(state->mrb, mrb_obj_value(state->mrb->exc), r, state->code.file);
        } else {
            ngx_mrb_raise_error(state->mrb, mrb_obj_value(state->mrb->exc), r);
        }
    }
    mrb_gc_arena_restore(state->mrb, state->ai);
    if (!cached) {
        ngx_mrb_irep_clean(state);
    }
    if (ngx_http_get_module_ctx(r, ngx_http_mruby_module) != NULL) {
        chain = ctx->rputs_chain;
        if (r->headers_out.status == NGX_HTTP_OK || !(*chain->last)->buf->last_buf) {
            r->headers_out.status = NGX_HTTP_OK;
            (*chain->last)->buf->last_buf = 1;
            ngx_http_send_header(r);
            ngx_http_output_filter(r, chain->out);
            ngx_http_set_ctx(r, NULL, ngx_http_mruby_module);
            return NGX_OK;
        } else {
            return r->headers_out.status;
        }
    }
    return NGX_OK;
}
Ejemplo n.º 3
0
ngx_int_t ngx_mrb_run(ngx_http_request_t *r, ngx_mrb_state_t *state, ngx_mrb_code_t *code, ngx_flag_t cached, ngx_str_t *result)
{
    int result_len;
    mrb_value mrb_result;
    ngx_http_mruby_ctx_t *ctx;
    ngx_mrb_rputs_chain_list_t *chain;

    if (state == NGX_CONF_UNSET_PTR || code == NGX_CONF_UNSET_PTR) {
        return NGX_DECLINED;
    }
    ctx = ngx_http_get_module_ctx(r, ngx_http_mruby_module);
    if (ctx == NULL && (ctx = ngx_pcalloc(r->pool, sizeof(*ctx))) == NULL) {
        ngx_log_error(NGX_LOG_ERR
            , r->connection->log
            , 0
            , "failed to allocate memory from r->pool %s:%d"
            , __FUNCTION__
            , __LINE__
        );
        return NGX_ERROR;
    }
    ngx_http_set_ctx(r, ctx, ngx_http_mruby_module);
    ngx_mrb_push_request(r);

    if (!cached) {
        state->ai = mrb_gc_arena_save(state->mrb);
    }

    ngx_log_error(NGX_LOG_INFO
        , r->connection->log
        , 0
        , "%s INFO %s:%d: mrb_run info: irep_n=%d arena_idx=%d"
        , MODULE_NAME
        , __func__
        , __LINE__
        , code->n
        , state->ai
    );
    mrb_result = mrb_run(state->mrb, mrb_proc_new(state->mrb, state->mrb->irep[code->n]), mrb_top_self(state->mrb));
    if (state->mrb->exc) {
        if (code->code_type == NGX_MRB_CODE_TYPE_FILE) {
            ngx_mrb_raise_file_error(state->mrb, mrb_obj_value(state->mrb->exc), r, code->code.file);
        } else {
            ngx_mrb_raise_error(state->mrb, mrb_obj_value(state->mrb->exc), r);
        }
    }
    if (result != NULL) {
        if (mrb_nil_p(mrb_result)) { 
            result->data = NULL;
            result->len = 0;
        } else {
            if (mrb_type(mrb_result) != MRB_TT_STRING) {
                mrb_result = mrb_funcall(state->mrb, mrb_result, "to_s", 0, NULL);
            }
            result_len = ngx_strlen((u_char *)RSTRING_PTR(mrb_result));
            result->data = ngx_palloc(r->pool, result_len);
            if (result->data == NULL) {
                return NGX_ERROR;
            }
            ngx_memcpy(result->data, (u_char *)RSTRING_PTR(mrb_result), result_len);
            result->len  = result_len;
            ngx_log_error(NGX_LOG_INFO
                , r->connection->log
                , 0
                , "%s INFO %s:%d: mrb_run info: irep_n=(%d) return value=(%s)"
                , MODULE_NAME
                , __func__
                , __LINE__
                , code->n
                , RSTRING_PTR(mrb_result)
            );
        }
    }

    mrb_gc_arena_restore(state->mrb, state->ai);

    if (!cached) {
        ngx_mrb_irep_clean(r, state, code);
        ngx_mrb_state_clean(r, state);
    }

    // TODO: Support rputs by multi directive
    if (ngx_http_get_module_ctx(r, ngx_http_mruby_module) != NULL) {
        chain = ctx->rputs_chain;
        if (chain == NULL) {
            ngx_log_error(NGX_LOG_INFO
                , r->connection->log
                , 0
                , "%s INFO %s:%d: mrb_run info: irep_n=(%d) rputs_chain is null and return NGX_OK"
                , MODULE_NAME
                , __func__
                , __LINE__
                , code->n
            );
            return NGX_OK;
        }
        if (r->headers_out.status == NGX_HTTP_OK || !(*chain->last)->buf->last_buf) {
            r->headers_out.status = NGX_HTTP_OK;
            (*chain->last)->buf->last_buf = 1;
            ngx_http_send_header(r);
            ngx_http_output_filter(r, chain->out);
            ngx_http_set_ctx(r, NULL, ngx_http_mruby_module);
            return NGX_OK;
        } else {
            return r->headers_out.status;
        }
    }
    return NGX_OK;
}