⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_http_perl_module.c

📁 nginx安装说明文档
💻 C
📖 第 1 页 / 共 2 页
字号:
    char              *ver, *embedding[6];    PerlInterpreter   *perl;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter");    if (ngx_set_environment(cf->cycle, NULL) == NULL) {        return NULL;    }    perl = perl_alloc();    if (perl == NULL) {        ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_alloc() failed");        return NULL;    }    {    dTHXa(perl);    PERL_SET_CONTEXT(perl);    perl_construct(perl);#ifdef PERL_EXIT_DESTRUCT_END    PL_exit_flags |= PERL_EXIT_DESTRUCT_END;#endif    embedding[0] = "";    if (pmcf->modules.data) {        embedding[1] = "-I";        embedding[2] = (char *) pmcf->modules.data;        n = 3;    } else {        n = 1;    }    embedding[n++] = "-Mnginx";    embedding[n++] = "-e";    embedding[n++] = "0";    n = perl_parse(perl, ngx_http_perl_xs_init, n, embedding, NULL);    if (n != 0) {        ngx_log_error(NGX_LOG_ALERT, cf->log, 0, "perl_parse() failed: %d", n);        goto fail;    }    sv = get_sv("nginx::VERSION", FALSE);    ver = SvPV(sv, len);    if (ngx_strcmp(ver, NGINX_VERSION) != 0) {        ngx_log_error(NGX_LOG_ALERT, cf->log, 0,                      "version " NGINX_VERSION " of nginx.pm is required, "                      "but %s was found", ver);        goto fail;    }    if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) != NGX_OK) {        goto fail;    }    }    return perl;fail:    (void) perl_destruct(perl);    perl_free(perl);    return NULL;}static ngx_int_tngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log){    char       **script;    STRLEN       len;    ngx_str_t    err;    ngx_uint_t   i;    script = requires->elts;    for (i = 0; i < requires->nelts; i++) {        require_pv(script[i]);        if (SvTRUE(ERRSV)) {            err.data = (u_char *) SvPV(ERRSV, len);            for (len--; err.data[len] == LF || err.data[len] == CR; len--) {                /* void */            }            err.len = len + 1;            ngx_log_error(NGX_LOG_EMERG, log, 0,                          "require_pv(\"%s\") failed: \"%V\"", script[i], &err);            return NGX_ERROR;        }    }    return NGX_OK;}static ngx_int_tngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,    ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv){    SV          *sv;    int          n, status;    char        *line;    STRLEN       len, n_a;    ngx_str_t    err;    ngx_uint_t   i;    dSP;    status = 0;    ENTER;    SAVETMPS;    PUSHMARK(sp);    sv = sv_2mortal(sv_bless(newRV_noinc(newSViv(PTR2IV(r))), nginx));    XPUSHs(sv);    if (args) {        for (i = 0; args[i]; i++) { /* void */ }        EXTEND(sp, (int) i);        for (i = 0; args[i]; i++) {            PUSHs(sv_2mortal(newSVpvn((char *) args[i]->data, args[i]->len)));        }    }    PUTBACK;    n = call_sv(sub, G_EVAL);    SPAGAIN;    if (n) {        if (rv == NULL) {            status = POPi;            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                           "call_sv: %d", status);        } else {            line = SvPVx(POPs, n_a);            rv->len = n_a;            rv->data = ngx_palloc(r->pool, n_a);            if (rv->data == NULL) {                return NGX_ERROR;            }            ngx_memcpy(rv->data, line, n_a);        }    }    PUTBACK;    FREETMPS;    LEAVE;    /* check $@ */    if (SvTRUE(ERRSV)) {        err.data = (u_char *) SvPV(ERRSV, len);        for (len--; err.data[len] == LF || err.data[len] == CR; len--) {            /* void */        }        err.len = len + 1;        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,                      "call_sv(\"%V\") failed: \"%V\"",                      handler, &err);        if (rv) {            return NGX_ERROR;        }        return NGX_HTTP_INTERNAL_SERVER_ERROR;    }    if (n != 1) {        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,                      "call_sv(\"%V\") returned %d results", handler, n);        status = NGX_OK;    }    if (rv) {        return NGX_OK;    }    return (ngx_int_t) status;}static voidngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv){    u_char  *p;    for (p = handler->data; *p; p++) {        if (*p != ' ' && *p != '\t' && *p != CR && *p != LF) {            break;        }    }    if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) {        *sv = eval_pv((char *) p, FALSE);        /* eval_pv() does not set ERRSV on failure */        return;    }    *sv = NULL;}static void *ngx_http_perl_create_main_conf(ngx_conf_t *cf){    ngx_http_perl_main_conf_t  *pmcf;    pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t));    if (pmcf == NULL) {        return NGX_CONF_ERROR;    }    if (ngx_array_init(&pmcf->requires, cf->pool, 1, sizeof(u_char *))        != NGX_OK)    {        return NULL;    }    return pmcf;}static char *ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf){    ngx_http_perl_main_conf_t *pmcf = conf;    if (pmcf->perl == NULL) {        if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) {            return NGX_CONF_ERROR;        }    }    return NGX_CONF_OK;}#if (NGX_HAVE_PERL_MULTIPLICITY)static voidngx_http_perl_cleanup_perl(void *data){    PerlInterpreter  *perl = data;    PERL_SET_CONTEXT(perl);    (void) perl_destruct(perl);    perl_free(perl);}#endifstatic ngx_int_tngx_http_perl_preconfiguration(ngx_conf_t *cf){#if (NGX_HTTP_SSI)    ngx_int_t                  rc;    ngx_http_ssi_main_conf_t  *smcf;    smcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_ssi_filter_module);    rc = ngx_hash_add_key(&smcf->commands, &ngx_http_perl_ssi_command.name,                          &ngx_http_perl_ssi_command, NGX_HASH_READONLY_KEY);    if (rc != NGX_OK) {        if (rc == NGX_BUSY) {            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                               "conflicting SSI command \"%V\"",                               &ngx_http_perl_ssi_command.name);        }        return NGX_ERROR;    }#endif    return NGX_OK;}static void *ngx_http_perl_create_loc_conf(ngx_conf_t *cf){    ngx_http_perl_loc_conf_t *plcf;    plcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_loc_conf_t));    if (plcf == NULL) {        return NGX_CONF_ERROR;    }    /*     * set by ngx_pcalloc():     *     *     plcf->handler = { 0, NULL };     */    return plcf;}static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child){    ngx_http_perl_loc_conf_t *prev = parent;    ngx_http_perl_loc_conf_t *conf = child;    if (conf->sub == NULL) {        conf->sub = prev->sub;        conf->handler = prev->handler;    }    return NGX_CONF_OK;}static char *ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){    ngx_http_perl_main_conf_t *pmcf = conf;    u_char     **p;    ngx_str_t   *value;    value = cf->args->elts;    p = ngx_array_push(&pmcf->requires);    if (p == NULL) {        return NGX_CONF_ERROR;    }    *p = value[1].data;    return NGX_CONF_OK;}static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){    ngx_http_perl_loc_conf_t *plcf = conf;    ngx_str_t                  *value;    ngx_http_core_loc_conf_t   *clcf;    ngx_http_perl_main_conf_t  *pmcf;    value = cf->args->elts;    if (plcf->handler.data) {        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                           "duplicate perl handler \"%V\"", &value[1]);        return NGX_CONF_ERROR;    }    pmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_perl_module);    if (pmcf->perl == NULL) {        if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) {            return NGX_CONF_ERROR;        }    }    plcf->handler = value[1];    {    dTHXa(pmcf->perl);    PERL_SET_CONTEXT(pmcf->perl);    ngx_http_perl_eval_anon_sub(aTHX_ &value[1], &plcf->sub);    if (plcf->sub == &PL_sv_undef) {        ngx_conf_log_error(NGX_LOG_ERR, cf, 0,                           "eval_pv(\"%V\") failed", &value[1]);        return NGX_CONF_ERROR;    }    if (plcf->sub == NULL) {        plcf->sub = newSVpvn((char *) value[1].data, value[1].len);    }    }    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);    clcf->handler = ngx_http_perl_handler;    return NGX_CONF_OK;}static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){    ngx_int_t                   index;    ngx_str_t                  *value;    ngx_http_variable_t        *v;    ngx_http_perl_variable_t   *pv;    ngx_http_perl_main_conf_t  *pmcf;    value = cf->args->elts;    if (value[1].data[0] != '$') {        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,                           "invalid variable name \"%V\"", &value[1]);        return NGX_CONF_ERROR;    }    value[1].len--;    value[1].data++;    v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);    if (v == NULL) {        return NGX_CONF_ERROR;    }    pv = ngx_palloc(cf->pool, sizeof(ngx_http_perl_variable_t));    if (pv == NULL) {        return NGX_CONF_ERROR;    }    index = ngx_http_get_variable_index(cf, &value[1]);    if (index == NGX_ERROR) {        return NGX_CONF_ERROR;    }    pmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_perl_module);    if (pmcf->perl == NULL) {        if (ngx_http_perl_init_interpreter(cf, pmcf) != NGX_CONF_OK) {            return NGX_CONF_ERROR;        }    }    pv->handler = value[2];    {    dTHXa(pmcf->perl);    PERL_SET_CONTEXT(pmcf->perl);    ngx_http_perl_eval_anon_sub(aTHX_ &value[2], &pv->sub);    if (pv->sub == &PL_sv_undef) {        ngx_conf_log_error(NGX_LOG_ERR, cf, 0,                           "eval_pv(\"%V\") failed", &value[2]);        return NGX_CONF_ERROR;    }    if (pv->sub == NULL) {        pv->sub = newSVpvn((char *) value[2].data, value[2].len);    }    }    v->get_handler = ngx_http_perl_variable;    v->data = (uintptr_t) pv;    return NGX_CONF_OK;}static ngx_int_tngx_http_perl_init_worker(ngx_cycle_t *cycle){    ngx_http_perl_main_conf_t  *pmcf;    pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module);    {    dTHXa(pmcf->perl);    PERL_SET_CONTEXT(pmcf->perl);    /* set worker's $$ */    sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), (I32) ngx_pid);    }    return NGX_OK;}static voidngx_http_perl_exit(ngx_cycle_t *cycle){    PERL_SYS_TERM();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -