Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 02a85c4f7b
Fetching contributors…

Cannot retrieve contributors at this time

251 lines (232 sloc) 6.986 kb
diff -ur nginx-0.7.61-original/src/http/modules/perl/nginx.pm nginx-0.7.61/src/http/modules/perl/nginx.pm
--- nginx-0.7.61-original/src/http/modules/perl/nginx.pm 2009-09-13 12:55:21.000000000 +0900
+++ nginx-0.7.61/src/http/modules/perl/nginx.pm 2009-09-13 15:04:28.000000000 +0900
@@ -99,6 +99,65 @@
}
+sub psgi_handler {
+ my($r, $handler, ) = @_;
+
+ my %env;
+ $env{'psig.version'} = [1,0];
+ $env{'psig.inputs'} = undef; # XXX tied?
+ $env{'psig.errors'} = undef; # XXX
+ $env{REQUEST_METHOD} = $r->request_method;
+ $env{SCRIPT_NAME} = $r->uri || '/';
+ $env{QUERY_STRING} = $r->args || '';
+ $env{SERVER_NAME} = 'nginx';
+
+ $env{REMOTE_ADDR} = $r->remote_addr;
+
+ # fetch headers;
+ my @headers = $r->headers;
+ while (my($name, $value) = splice @headers, 0, 2) {
+ next unless $name && $value;
+ $name =~ s/-/_/g;
+ $name = uc $name;
+ $name = "HTTP_$name" unless $name eq 'CONTENT_LENGTH' || $name eq 'CONTENT_TYPE';
+
+ $env{$name} = $value;
+ }
+
+ my $res;
+ {
+ no strict 'refs';
+ my $code = \&{$handler};
+ $res = $code->(\%env);
+ };
+ my $content_type = 'text/html';
+ while (my($k, $v) = splice @{ $res->[1] }, 0, 2) {
+ if (uc $k eq 'CONTENT-TYPE') {
+ $content_type = $v;
+ } else {
+ $r->header_out($k, $v);
+ }
+ }
+ $r->send_http_header($content_type);
+
+ return $res->[0] if $r->header_only;
+
+ my $body = $res->[2];
+ if (ref $body eq 'ARRAY') {
+ for my $line (@$body) {
+ $r->print($line);
+ }
+ } else {
+ while (defined(my $line = $body->getline)) {
+ $r->print($line);
+ }
+ $body->close;
+ }
+ $r->rflush;
+
+ return $res->[0];
+}
+
1;
__END__
diff -ur nginx-0.7.61-original/src/http/modules/perl/nginx.xs nginx-0.7.61/src/http/modules/perl/nginx.xs
--- nginx-0.7.61-original/src/http/modules/perl/nginx.xs 2009-09-13 12:55:21.000000000 +0900
+++ nginx-0.7.61/src/http/modules/perl/nginx.xs 2009-09-13 15:00:41.000000000 +0900
@@ -213,6 +213,37 @@
ST(0) = TARG;
+void
+headers(r)
+ PPCODE:
+
+ ngx_http_request_t *r;
+ ngx_uint_t i, c;
+ ngx_table_elt_t *h;
+ ngx_list_part_t *part;
+
+ ngx_http_perl_set_request(r);
+
+ c = 0;
+ part = &r->headers_in.headers.part;
+ h = part->elts;
+ for (i = 0; /* void */ ; i++) {
+ if (i >= part->nelts) {
+ if (part->next == NULL) {
+ break;
+ }
+
+ part = part->next;
+ h = part->elts;
+ i = 0;
+ }
+
+ // use mXPUSHp idea by gfx++
+ mXPUSHp((char *)h[i].key.data, h[i].key.len);
+ mXPUSHp((char *)h[i].value.data, h[i].value.len);
+ c += 2;
+ }
+ XSRETURN(c);
void
header_in(r, key)
diff -ur nginx-0.7.61-original/src/http/modules/perl/ngx_http_perl_module.c nginx-0.7.61/src/http/modules/perl/ngx_http_perl_module.c
--- nginx-0.7.61-original/src/http/modules/perl/ngx_http_perl_module.c 2009-09-13 12:55:21.000000000 +0900
+++ nginx-0.7.61/src/http/modules/perl/ngx_http_perl_module.c 2009-09-13 12:22:10.000000000 +0900
@@ -21,6 +21,7 @@
typedef struct {
SV *sub;
ngx_str_t handler;
+ ngx_str_t psgi_handler;
} ngx_http_perl_loc_conf_t;
@@ -60,6 +61,7 @@
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_psgi(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)
@@ -93,6 +95,13 @@
0,
NULL },
+ { ngx_string("psgi"),
+ NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_TAKE1,
+ ngx_http_perl_psgi,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
{ ngx_string("perl_set"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
ngx_http_perl_set,
@@ -188,7 +197,7 @@
void
ngx_http_perl_handle_request(ngx_http_request_t *r)
{
- SV *sub;
+ SV *sub, **asv;
ngx_int_t rc;
ngx_str_t uri, args, *handler;
ngx_http_perl_ctx_t *ctx;
@@ -216,6 +225,7 @@
dTHXa(pmcf->perl);
PERL_SET_CONTEXT(pmcf->perl);
+ plcf = NULL;
if (ctx->next == NULL) {
plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module);
sub = plcf->sub;
@@ -227,7 +237,15 @@
ctx->next = NULL;
}
- rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, NULL, handler,
+ if (plcf != NULL && plcf->psgi_handler.data != NULL) {
+ asv = ngx_pcalloc(r->pool, sizeof(SV *) * 2);
+ asv[0] = (SV *) 1;
+ asv[1] = newSVpvn((char *) plcf->psgi_handler.data, plcf->psgi_handler.len);
+ } else {
+ asv = NULL;
+ }
+
+ rc = ngx_http_perl_call_handler(aTHX_ r, pmcf->nginx, sub, asv, handler,
NULL);
}
@@ -944,7 +962,9 @@
}
}
- plcf->handler = value[1];
+ plcf->handler = value[1];
+ plcf->psgi_handler.data = NULL;
+ plcf->psgi_handler.len = 0;
{
@@ -973,6 +993,61 @@
static char *
+ngx_http_perl_psgi(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;
+ ngx_str_t psgi_handler = ngx_string("nginx::psgi_handler");
+
+ 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 = psgi_handler;
+ plcf->psgi_handler = value[1];
+
+ {
+
+ dTHXa(pmcf->perl);
+ PERL_SET_CONTEXT(pmcf->perl);
+
+ ngx_http_perl_eval_anon_sub(aTHX_ &plcf->handler, &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 *) psgi_handler.data, psgi_handler.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;
Jump to Line
Something went wrong with that request. Please try again.