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

📄 ngx_http_perl_module.c

📁 nginx安装说明文档
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) Igor Sysoev */#include <ngx_config.h>#include <ngx_core.h>#include <ngx_http.h>#include <ngx_http_perl_module.h>typedef struct {    PerlInterpreter   *perl;    HV                *nginx;    ngx_str_t          modules;    ngx_array_t        requires;} ngx_http_perl_main_conf_t;typedef struct {    SV                *sub;    ngx_str_t          handler;} ngx_http_perl_loc_conf_t;typedef struct {    SV                *sub;    ngx_str_t          handler;} ngx_http_perl_variable_t;typedef struct {    SV                *sv;    PerlInterpreter   *perl;} ngx_http_perl_cleanup_t;#if (NGX_HTTP_SSI)static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,    ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params);#endifstatic void ngx_http_perl_sleep_handler(ngx_http_request_t *r);static char *ngx_http_perl_init_interpreter(ngx_conf_t *cf,    ngx_http_perl_main_conf_t *pmcf);static PerlInterpreter *ngx_http_perl_create_interpreter(ngx_conf_t *cf,    ngx_http_perl_main_conf_t *pmcf);static ngx_int_t ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires,    ngx_log_t *log);static ngx_int_t ngx_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);static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv);static ngx_int_t ngx_http_perl_preconfiguration(ngx_conf_t *cf);static void *ngx_http_perl_create_main_conf(ngx_conf_t *cf);static char *ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf);static void *ngx_http_perl_create_loc_conf(ngx_conf_t *cf);static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent,    void *child);static char *ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd,    void *conf);static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);#if (NGX_HAVE_PERL_MULTIPLICITY)static void ngx_http_perl_cleanup_perl(void *data);#endifstatic ngx_int_t ngx_http_perl_init_worker(ngx_cycle_t *cycle);static void ngx_http_perl_exit(ngx_cycle_t *cycle);static ngx_command_t  ngx_http_perl_commands[] = {    { ngx_string("perl_modules"),      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,      ngx_conf_set_str_slot,      NGX_HTTP_MAIN_CONF_OFFSET,      offsetof(ngx_http_perl_main_conf_t, modules),      NULL },    { ngx_string("perl_require"),      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,      ngx_http_perl_require,      NGX_HTTP_MAIN_CONF_OFFSET,      0,      NULL },    { ngx_string("perl"),      NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,      ngx_http_perl,      NGX_HTTP_LOC_CONF_OFFSET,      0,      NULL },    { ngx_string("perl_set"),      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,      ngx_http_perl_set,      NGX_HTTP_LOC_CONF_OFFSET,      0,      NULL },      ngx_null_command};static ngx_http_module_t  ngx_http_perl_module_ctx = {    ngx_http_perl_preconfiguration,        /* preconfiguration */    NULL,                                  /* postconfiguration */    ngx_http_perl_create_main_conf,        /* create main configuration */    ngx_http_perl_init_main_conf,          /* init main configuration */    NULL,                                  /* create server configuration */    NULL,                                  /* merge server configuration */    ngx_http_perl_create_loc_conf,         /* create location configuration */    ngx_http_perl_merge_loc_conf           /* merge location configuration */};ngx_module_t  ngx_http_perl_module = {    NGX_MODULE_V1,    &ngx_http_perl_module_ctx,             /* module context */    ngx_http_perl_commands,                /* module directives */    NGX_HTTP_MODULE,                       /* module type */    NULL,                                  /* init master */    NULL,                                  /* init module */    ngx_http_perl_init_worker,             /* init process */    NULL,                                  /* init thread */    NULL,                                  /* exit thread */    NULL,                                  /* exit process */    ngx_http_perl_exit,                    /* exit master */    NGX_MODULE_V1_PADDING};#if (NGX_HTTP_SSI)#define NGX_HTTP_PERL_SSI_SUB  0#define NGX_HTTP_PERL_SSI_ARG  1static ngx_http_ssi_param_t  ngx_http_perl_ssi_params[] = {    { ngx_string("sub"), NGX_HTTP_PERL_SSI_SUB, 1, 0 },    { ngx_string("arg"), NGX_HTTP_PERL_SSI_ARG, 0, 1 },    { ngx_null_string, 0, 0, 0 }};static ngx_http_ssi_command_t  ngx_http_perl_ssi_command = {    ngx_string("perl"), ngx_http_perl_ssi, ngx_http_perl_ssi_params, 0, 0, 1};#endifstatic ngx_str_t  ngx_null_name = ngx_null_string;static HV  *nginx_stash;static voidngx_http_perl_xs_init(pTHX){    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__);    nginx_stash = gv_stashpv("nginx", TRUE);}static ngx_int_tngx_http_perl_handler(ngx_http_request_t *r){    /* TODO: Win32 */    if (r->zero_in_uri) {        return NGX_HTTP_NOT_FOUND;    }    ngx_http_perl_handle_request(r);    return NGX_DONE;}voidngx_http_perl_handle_request(ngx_http_request_t *r){    SV                         *sub;    ngx_int_t                   rc;    ngx_str_t                   uri, args, *handler;    ngx_http_perl_ctx_t        *ctx;    ngx_http_perl_loc_conf_t   *plcf;    ngx_http_perl_main_conf_t  *pmcf;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl handler");    ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);    if (ctx == NULL) {        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t));        if (ctx == NULL) {            ngx_http_finalize_request(r, NGX_ERROR);            return;        }        ngx_http_set_ctx(r, ctx, ngx_http_perl_module);    }    pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);    {    dTHXa(pmcf->perl);    PERL_SET_CONTEXT(pmcf->perl);    if (ctx->next == NULL) {        plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module);        sub = plcf->sub;        handler = &plcf->handler;    } else {        sub = ctx->next;        handler = &ngx_null_name;        ctx->next = NULL;    }    rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, NULL, handler,                                    NULL);    }    if (rc > 600) {        rc = NGX_OK;    }    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "perl handler done: %i", rc);    if (ctx->redirect_uri.len) {        uri = ctx->redirect_uri;        args = ctx->redirect_args;    } else {        uri.len = 0;    }    ctx->filename.data = NULL;    ctx->redirect_uri.len = 0;    if (ctx->sleep) {        ngx_add_timer(r->connection->write, (ngx_msec_t) ctx->sleep);        r->write_event_handler = ngx_http_perl_sleep_handler;        ctx->sleep = 0;    }    if (ctx->done || ctx->next) {        return;    }    if (uri.len) {        ngx_http_internal_redirect(r, &uri, &args);        return;    }    if (rc == NGX_OK || rc == NGX_HTTP_OK) {        ngx_http_send_special(r, NGX_HTTP_LAST);        ctx->done = 1;    }    ngx_http_finalize_request(r, rc);}static voidngx_http_perl_sleep_handler(ngx_http_request_t *r){    ngx_event_t  *wev;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "perl sleep handler");    wev = r->connection->write;    if (wev->timedout) {        wev->timedout = 0;        ngx_http_perl_handle_request(r);        return;    }    if (ngx_handle_write_event(wev, 0) == NGX_ERROR) {        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);    }}static ngx_int_tngx_http_perl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,    uintptr_t data){    ngx_http_perl_variable_t *pv = (ngx_http_perl_variable_t *) data;    ngx_int_t                   rc;    ngx_str_t                   value;    ngx_http_perl_ctx_t        *ctx;    ngx_http_perl_main_conf_t  *pmcf;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "perl variable handler");    ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);    if (ctx == NULL) {        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t));        if (ctx == NULL) {            return NGX_ERROR;        }        ngx_http_set_ctx(r, ctx, ngx_http_perl_module);    }    pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);    value.data = NULL;    {    dTHXa(pmcf->perl);    PERL_SET_CONTEXT(pmcf->perl);    rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, pv->sub, NULL,                                    &pv->handler, &value);    }    if (value.data) {        v->len = value.len;        v->valid = 1;        v->no_cachable = 0;        v->not_found = 0;        v->data = value.data;    } else {        v->not_found = 1;    }    ctx->filename.data = NULL;    ctx->redirect_uri.len = 0;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "perl variable done");    return rc;}#if (NGX_HTTP_SSI)static ngx_int_tngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,    ngx_str_t **params){    SV                         *sv;    ngx_int_t                   rc;    ngx_str_t                  *handler;    ngx_http_perl_ctx_t        *ctx;    ngx_http_perl_main_conf_t  *pmcf;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                   "perl ssi handler");    ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module);    if (ctx == NULL) {        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t));        if (ctx == NULL) {            return NGX_ERROR;        }        ngx_http_set_ctx(r, ctx, ngx_http_perl_module);    }    pmcf = ngx_http_get_module_main_conf(r, ngx_http_perl_module);    ctx->ssi = ssi_ctx;    handler = params[NGX_HTTP_PERL_SSI_SUB];    handler->data[handler->len] = '\0';    {    dTHXa(pmcf->perl);    PERL_SET_CONTEXT(pmcf->perl);#if 0    /* the code is disabled to force the precompiled perl code using only */    ngx_http_perl_eval_anon_sub(aTHX_ handler, &sv);    if (sv == &PL_sv_undef) {        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,                      "eval_pv(\"%V\") failed", handler);        return NGX_ERROR;    }    if (sv == NULL) {        sv = newSVpvn((char *) handler->data, handler->len);    }#endif    sv = newSVpvn((char *) handler->data, handler->len);    rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sv,                                    &params[NGX_HTTP_PERL_SSI_ARG],                                    handler, NULL);    SvREFCNT_dec(sv);    }    ctx->filename.data = NULL;    ctx->redirect_uri.len = 0;    ctx->ssi = NULL;    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "perl ssi done");    return rc;}#endifstatic char *ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf){#if (NGX_HAVE_PERL_MULTIPLICITY)    ngx_pool_cleanup_t       *cln;    cln = ngx_pool_cleanup_add(cf->pool, 0);    if (cln == NULL) {        return NGX_CONF_ERROR;    }#else    static PerlInterpreter  *perl;#endif#ifdef NGX_PERL_MODULES    if (pmcf->modules.data == NULL) {        pmcf->modules.data = NGX_PERL_MODULES;    }#endif    if (pmcf->modules.data) {        if (ngx_conf_full_name(cf->cycle, &pmcf->modules) != NGX_OK) {            return NGX_CONF_ERROR;        }    }#if !(NGX_HAVE_PERL_MULTIPLICITY)    if (perl) {        if (ngx_set_environment(cf->cycle, NULL) == NULL) {            return NGX_CONF_ERROR;        }        if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log)            != NGX_OK)        {            return NGX_CONF_ERROR;        }        pmcf->perl = perl;        pmcf->nginx = nginx_stash;        return NGX_CONF_OK;    }#endif    if (nginx_stash == NULL) {        PERL_SYS_INIT(&ngx_argc, &ngx_argv);    }    pmcf->perl = ngx_http_perl_create_interpreter(cf, pmcf);    if (pmcf->perl == NULL) {        return NGX_CONF_ERROR;    }    pmcf->nginx = nginx_stash;#if (NGX_HAVE_PERL_MULTIPLICITY)    cln->handler = ngx_http_perl_cleanup_perl;    cln->data = pmcf->perl;#else    perl = pmcf->perl;#endif    return NGX_CONF_OK;}static PerlInterpreter *ngx_http_perl_create_interpreter(ngx_conf_t *cf,    ngx_http_perl_main_conf_t *pmcf){    int                n;    STRLEN             len;    SV                *sv;

⌨️ 快捷键说明

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