# NGINX perl module to server files

**URL:** <https://www.ruby-forum.com/t/nginx-perl-module-to-server-files/246138>\
**Category:** NGINX\
**Created:** [August 31, 2013, 11:47pm UTC](https://www.ruby-forum.com/t/nginx-perl-module-to-server-files/246138 "2013-08-31T23:47:25Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rafa\_F](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/958977/32.png) [@Rafa\_F](https://www.ruby-forum.com/u/Rafa_F)\
**Post date:** [August 31, 2013, 11:47pm UTC](https://www.ruby-forum.com/t/nginx-perl-module-to-server-files/246138/1 "2013-08-31T23:47:25Z")

</div>

Hello,

I have created perl NGINX module to server static files on the NGINX  
(mainly images). For security reasons I am generating the AES:CBC  
encrypted  
url which I am decrypting on the NGINX and serving the file via NGINX  
perl  
module. The problem is that I am sometimes getting the bellow response  
with  
HTTP response code set to 000:

XX.XX.XX.XX - - [01/Sep/2013:01:20:37 +0400] “GET  
/media/u5OU/NRkImrrwH/TThHe7hns5bOEv+Aou2/VJ8YD/ts= HTTP/1.1” _000_  
39078 "  
[http://XXXX/full/JcbyEJTb8nMh+YH0xSg1jgl4N7vWQi2xBPep7VcJmD8=](http://XXXX/full/JcbyEJTb8nMh+YH0xSg1jgl4N7vWQi2xBPep7VcJmD8=)[http://gruppu.com/full/JcbyEJTb8nMh+YH0xSg1jgl4N7vWQi2xBPep7VcJmD8=](http://gruppu.com/full/JcbyEJTb8nMh+YH0xSg1jgl4N7vWQi2xBPep7VcJmD8=)"  
“Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:23.0) Gecko/20100101  
Firefox/23.0”

The way how I handle the url in the perl module is :

In case the file is found:  
$r-\>sendfile($fileresult[0]);  
$r-\>flush();  
return OK;

else:  
$r-\>status(404);  
return DECLINED;

My question is if I am sending the files correctly or is there any other  
specific value i should send back from perl (besides returning OK).

If needed I can send the nginx.conf.

Thanks for your help.

Regards,

Jorge

---

<div class="post-metadata">

**Author:** ![Jorge\_Sanchez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@Jorge\_Sanchez](https://www.ruby-forum.com/u/Jorge_Sanchez)\
**Post date:** [September 1, 2013, 11:30pm UTC](https://www.ruby-forum.com/t/nginx-perl-module-to-server-files/246138/2 "2013-09-01T23:30:19Z")

</div>

Hello list,

here is the strace of the NGINX serving my media file (Jpg) to the  
client:

Accepting the connection:

25003 accept4(6, {sa\_family=AF\_INET, sin\_port=htons(53907),  
sin\_addr=inet\_addr(“XXX.XXX.XXX.XX”)}, [16], SOCK\_NONBLOCK) = 3

Opening the file:  
25003 open("/usr/site/gruppe/media/t\_pics/images/thumbs/714.jpg",  
O\_RDONLY|O\_NONBLOCK|O\_LARGEFILE) = 15  
25003 fstat64(15, {st\_mode=S\_IFREG|0755, st\_size=5420, …}) = 0

Sending the file to the client with sendfile:  
25003 sendfile64(3, 15, [0], 5420) = 5420

So from above it turns out that there were no headers sent and thus the  
status code probably defaulted to “000” on NGINX.

Adding the send\_http\_header before the $r-\>sendfile() solves the issue.  
$r-\>send\_http\_header();

Now I have the correct HTTP status code, anyway the content type  
defaults  
to “application/octet-stream” which is configured as default content  
type  
on nginx. Well, is there a way to have NGINX correctly set the  
Content-Type  
after handling the request on perl content handler or should I make my  
own  
mapping and set the content-type myself in send\_http\_header ?

HTTP/1.1 200 OK Server: nginx/1.5.5 Date: Sun, 01 Sep 2013 21:17:41 GMT  
Content-Type: application/octet-stream Transfer-Encoding: chunked  
Connection: keep-alive

Regards,

Jorge

---

<div class="post-metadata">

**Author:** ![Jorge\_Sanchez](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@Jorge\_Sanchez](https://www.ruby-forum.com/u/Jorge_Sanchez)\
**Post date:** [September 2, 2013, 3:28am UTC](https://www.ruby-forum.com/t/nginx-perl-module-to-server-files/246138/3 "2013-09-02T03:28:14Z")

</div>

Hello!

On Sun, Sep 01, 2013 at 04:29:46PM -0500, Jorge Sanchez wrote:

[…]

> So from above it turns out that there were no headers sent and thus the  
> status code probably defaulted to “000” on NGINX.
> 
> Adding the send\_http\_header before the $r-\>sendfile() solves the issue.  
> $r-\>send\_http\_header();

Glad to see you’ve solved your problem with perl code.

BTW, there are some examples at  
[Module ngx\_http\_perl\_module](http://nginx.org/en/docs/http/ngx_http_perl_module.html) which may  
help.

> Now I have the correct HTTP status code, anyway the content type defaults  
> to “application/octet-stream” which is configured as default content type  
> on nginx. Well, is there a way to have NGINX correctly set the Content-Type  
> after handling the request on perl content handler or should I make my own  
> mapping and set the content-type myself in send\_http\_header ?

The Content-Type nginx set by itself is based on an extension as  
seen in URI. As there is no extension in URIs you use, it uses  
default type. If a default type isn’t what you want - you should  
either set response type explicitly, or reconsider URIs used.

In your particular case, I would recommend you to use  
$r-\>internal\_redirect() to an internal location instead of trying  
to send files yourself. (Or, alternatively, perl\_set + rewrite  
should also work.) It should be much easier than trying to send  
files yourself from perl.

See here for more details:

> **[Module ngx\_http\_perl\_module](http://nginx.org/en/docs/http/ngx_http_perl_module.html)**

–  
Maxim D.

> **[nginx: donation](http://nginx.org/en/donation.html)**
