Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

first commit

  • Loading branch information...
commit ccf13e63ada6605a6b250dc616405ee917d86665 0 parents
Kazuhiro Osawa authored
Showing with 339 additions and 0 deletions.
  1. +14 −0 Example.pm
  2. +314 −0 nginx.patch
  3. +11 −0 tinyconfig.conf
14 Example.pm
@@ -0,0 +1,14 @@
+package Example;
+use strict;
+use warnings;
+use Data::Dumper;
+
+sub handler {
+ my $env = shift;
+
+ my $body = Dumper($env);
+ [200, ['Content-Type', 'text/plain', 'Content-Length', length($body), 'X-Yappo', 'Hokke'], [$body]];
+}
+
+1;
+
314 nginx.patch
@@ -0,0 +1,314 @@
+Only in nginx-0.7.61: Makefile
+Only in nginx-0.7.61: objs
+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 12:46:26.000000000 +0900
+@@ -99,6 +99,71 @@
+ }
+
+
++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 $max = $r->headers();
++ my @headers;
++ for my $c (0..($max)) {
++ push @headers, $r->header_by_n($c);
++ }
++
++ for my $name (@headers) {
++ next unless $name;
++ my $v = $r->header_in($name);
++ $name =~ s/-/_/g;
++ $name = uc $name;
++ $name = "HTTP_$name" unless $name eq 'CONTENT_LENGTH' || $name eq 'CONTENT_TYPE';
++
++ $env{$name} = $v;
++ }
++
++ 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-12 20:50:10.000000000 +0900
+@@ -213,6 +213,93 @@
+
+ ST(0) = TARG;
+
++void
++headers(r)
++ CODE:
++
++ dXSTARG;
++ ngx_http_request_t *r;
++ ngx_str_t value;
++ ngx_uint_t i, c;
++ ngx_table_elt_t *h;
++ ngx_list_part_t *part;
++
++ ngx_http_perl_set_request(r);
++
++ part = &r->headers_in.headers.part;
++ h = part->elts;
++ c = 0;
++ for (i = 0; /* void */ ; i++) {
++ if (i >= part->nelts) {
++ if (part->next == NULL) {
++ break;
++ }
++
++ part = part->next;
++ h = part->elts;
++ i = 0;
++ }
++ c++;
++ }
++
++ value.data = ngx_pcalloc(r->pool, 10);
++ value.len = ngx_sprintf(value.data, "%d", c) - value.data;
++ ngx_http_perl_set_targ(value.data, value.len);
++
++ ST(0) = TARG;
++
++void
++header_by_n(r, key)
++ CODE:
++
++ dXSTARG;
++ ngx_http_request_t *r;
++ SV *key;
++ ngx_str_t value;
++ ngx_uint_t i, c;
++ u_char *p;
++ STRLEN len;
++ ngx_table_elt_t *h;
++ ngx_list_part_t *part;
++
++ ngx_http_perl_set_request(r);
++
++ key = ST(1);
++
++ if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) {
++ key = SvRV(key);
++ }
++
++ p = (u_char *) SvPV(key, len);
++
++ part = &r->headers_in.headers.part;
++ h = part->elts;
++ c = 0;
++ value.data = ngx_pcalloc(r->pool, 10);
++ for (i = 0; /* void */ ; i++) {
++ if (i >= part->nelts) {
++ if (part->next == NULL) {
++ break;
++ }
++
++ part = part->next;
++ h = part->elts;
++ i = 0;
++ }
++
++ c++;
++ value.len = ngx_sprintf(value.data, "%d", c) - value.data;
++
++ if (len != value.len
++ || ngx_strcasecmp(p, value.data) != 0)
++ {
++ continue;
++ }
++
++ ngx_http_perl_set_targ(h[i].key.data, h[i].key.len);
++ }
++
++ ST(0) = TARG;
+
+ 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;
11 tinyconfig.conf
@@ -0,0 +1,11 @@
+http {
+ perl_modules your/app/lib/dir
+ perl_require Example.pm;
+ server {
+ listen 8011;
+ server_name localhost;
+ location / {
+ psgi Example::handler;
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.