two small questions about embedded perl

Sven 'Darkman' Michels sven at darkman.de
Thu Dec 16 23:58:30 MSK 2010


Hi,

i'm replying to myself because after playing around a lot i think i found
something i would call "solution" ;)

The problem was (or is) that the location matches etc. did match multiple
times, so that the perl module was called twice. The second call ended up
into "nothing" or something like a loop (it was no loop or similar reported)
and thus nginx didn't deliver any content nor contacted the upstream.

Now i've rewritten the module and the config like this:

module:
internal_redirect("/somethinginternal/$file");

nginx.conf:
location ^~ /somethinginternal/ {
	internal;
	rewrite ^/somethinginternal/(.+)$ /$1 break;
	proxy_pass http://internal-host;
	...
}
location ~* \.(png|jpg|gif)$  {
	perl testpackage::handler;
}
location / {
	proxy_pass http://other-internal;
	...
}

The keypoints where: the ^~ and ~* are for the priority, so that somethinginternal
stops processing of the locations. Another thing is: rewrite... break; instead of
rewrite... last; - last seems to abort the processing and the request doesn't get
forwarded to the proxy.

This is probably not the best solution, and since its perl, maybe its slow, too.
But if this will work (will need some more testing) i'll probably "force" ;)
someone to rewrite this as nginx module. Should things make more easy... i think.

Talking about performance: the perl module is quick, but as far as i know, it
blocks processing, right? Are there some statistics how the speed decreases?
Like "processing 1500r/s with plain nginx, using a small embedded perl module,
the rate drops to 250r/s"?

Just to be clear: the module just does some comparing and rewrite, its no database
involved or so, just some internal math and stuff (all hopefully as quick as
possible).

Last question: is it possible to pass some variable to a perl module? like
"set $myvar 123;" and accessing $myvar somehow in the module?

Thanks for all the support so far.

Many regards,
Sven


Am 15.12.2010 06:42, schrieb Sven 'Darkman' Michels:
> Hi,
> 
> Am 14.12.2010 23:38, schrieb Igor Sysoev:
>> You should "return DECLINED;", in this case nginx will continue to
>> process usual handler chain: index, static files, etc.
> 
> ok, did that but now i get nothing returned again *sigh*
> The log says "GET /file.jpg HTTP/1.0" 0 0 "-" "-"
> which is not exactly what i would expect...
> the perl module just "return DECLINED;" in this case.
> 
>>      location ~ \.(png|jpg|gif)$  {
>>        perl testpackage::handler;
>>        # do $r->internal_redirect("/new/...");
>>      }
>>
>>      location /new/ {
>>         proxy_pass  http://internal/;
>>      }
>>
>>      location / {
>>         proxy_pass  http://internal/;
>>      }
>>
>>
> 
> ok, this is what i have done now:
>     location ~ \.(png|jpg|gif)$  {
>       perl testpackage::handler;
>     }
>     location /intredirremoved/ {
>         rewrite ^/intredirremoved/(.+)$        $1      last;
>             proxy_pass             http://internal/;
>             proxy_set_header       Host $host;
>             proxy_cache            STATIC;
>             proxy_cache_valid      200  1d;
>             proxy_cache_use_stale  error timeout invalid_header updating
>                                    http_500 http_502 http_503 http_504;
>         }
>     location / {
> 
>             proxy_pass             http://internal/;
>             proxy_set_header       Host $host;
>             proxy_cache            STATIC;
>             proxy_cache_valid      200  1d;
>             proxy_cache_use_stale  error timeout invalid_header updating
>                                    http_500 http_502 http_503 http_504;
>     }
> 
> maybe its some extra work now, but my module should remove old parts of the
> uri. I now add this intredirremoved to get a new location as suggested, but
> have to remove it again before passing it to the proxy. "Should" work, but
> is probably not the best. Anyway, the config doesn't work at all. I'll post
> some more of the module:
> #!/usr/bin/perl -w
> package testpackage;
> use nginx;
> 
> sub handler {
> 	$r = shift;
> 	if(($r->uri=~m%^/oldstuff/(.+\.(jpg|png|gif))$%) &&
> $r->uri!~m%^/intredirremoved/$%)) {
> 		$file = $1;
> 		$r->internal_redirect("/intredirremoved/$file");
> 		# return OK
> 		# return DECLINED;
> 	} else {
> 		return DECLINED;
> 	}
> }
> 
> this is what it basicly does, except that the real module is a bit more
> complex, not just doing some rewrites. As you can see, i tried with returning
> ok, declined, nothing, but nothing worked.
> 
> Regards,
> Sven
> 
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://nginx.org/mailman/listinfo/nginx



More information about the nginx mailing list