Why Apache PerlModule directive doesn't set custom environment variables? - perl

I am building a mod_perl website, and I need to set an environment variable that will be used in the Perl code.
Until now I was using the PerlSetEnv directive to set this variable:
PerlSetEnv MYVAR myvalue
<LocationMatch /perlpath/>
SetHandler modperl
PerlResponseHandler myhandler
Header set Cache-control "no-cache"
</LocationMatch>
This works fine, but I'd like to preload my mod_perl handler, because the first call is very slow. So I changed my Apache virtualhost file to:
PerlSetEnv MYVAR myvalue
PerlModule myhandler <- add this line
<LocationMatch /perlpath/>
SetHandler modperl
PerlResponseHandler myhandler
Header set Cache-control "no-cache"
</LocationMatch>
But if I do this, my custom environment variable MYVAR is not set when preloading myhandler, and my code fails.
So is it possible to set an environment variable that will be exported by the PerlModule directive?

You could use PerlPassEnv to forward the env variables to the programs running in the server. However, they take effect in the first phase of apache request cycle unlike the setEnv & PassEnv which don't take effect until fixup phase.
In the past, I have used BEGIN Clause to set the env variable like ORACLE_HOME that I want to be visible much before the request phase.
Try setting the variable inside a perl BEGIN block in your httpd.conf that might expose it much ahead of the traditional directives.

Maybe you have to move the setenv inside your virtualhost config?
<LocationMatch /perlpath/>
SetHandler modperl
PerlSetEnv MYVAR myvalue
PerlResponseHandler myhandler
Header set Cache-control "no-cache"
</LocationMatch>

Related

Getting folder application runs from in Mojolicious Lite

I want to be able to run my Mojolicious Lite app on shared hosting either from root (www.domain.com/) or subfolder (www.domain.com/misc/mymojoapp/).
The app's .pl file always goes to cgi-bin folder of the domain (www.domain.com/cgi-bin/myapp.pl) and I want to use mod_rewrite rules in .htaccess to point to the app. Images/css/js files would be under www.domain.com/misc/mymojoapp/support.
But I cannot figure out how I reliably get misc/mymojoapp/ part of the path so I can pass it into templates. Is there a way?
# set apache handler to treat your specified script name(s) as a CGI program
Options +ExecCGI
<Files ~ "(mymojoapp)$">
SetHandler cgi-script
</Files>
# rewrite any requests into the appRewriteEngine onRewriteCond %{REQUEST_FILENAME}
!-fRewriteRule ^(.*)$ misc/mymojoapp/$1 [L]
and in your App
# set env variable to use root for pretty URLs
$ENV{SCRIPT_NAME} = '/';
Change the above setting for pretty URL

Apache : Display perl script as a text

I have Perl files with no extension (not in the format of .pl)
I need to execute them when I click them not open them as a plain text.
when I add pl extension to them. they work successfully. (when I added in apache.conf
AddHandler cgi-script .cgi pl
)
but I need to know if there's a way to execute them without adding the extension
You can use SetHandler to decide what Apache treats as a cgi-script.
In apache configuration, add this and reload/restart Apache:
<Directory /path/to/directory/with/perl-files>
SetHandler cgi-script
</Directory>
# Or <DirectoryMatch>, <Location>, <FilesMatch> or similar directives
or
In the directory itself, add file .htaccess with content:
SetHandler cgi-script
This will make Apache treat everything in the directory as a cgi-script and try to execute it regardless of file extension.
The .htaccess solution might need additional permissions in apache configuration, (like AllowOverride SetHandler) see Apache Doc for AllowOverride

How to convert perl modules to mod_perl handlers?

I have some perl modules which are intergreted in a cgi script which runs on a web server. How can I simply convert these modules to a mod_perl handler?
Thanks.
If all you want is for mod_perl to make your code cached/faster, then...
Just add the following to your Apache host configuration:
Alias /cgi-bin/ /path/to/your/cgi/script/folder
PerlRequire /path/to/startup-script.pl
<Files ~ (\.cgi)>
Options +ExecCGI
SetHandler perl-script
PerlHandler ModPerl::Registry
PerlSendHeader On
</Files>
In startup-script.pl set up your include path (if needed) with use lib.
Then you can just use CGI::Simple as before.

Perl Apache : Perl script displayed as plain text

While configuring with apache and perl cgi scripts, don't know why index.cgi/index.pl are displayed as plain text instead of executing them.
When I put http://localhost in browser it displays below code, instead of executing it.
List item
#!C:/Dwimperl/perl/bin/perl.exe -w
print "Content-type: text/html\n\n";
print <<HTML;
<html>
<head>
<title>A perl web page</title>
</head>
<body>
<h3>A hello world form perl</h3>
</body>
HTML
exit;
This are parts of httpd.conf file which I have edited most of the times (after reading various online reference, tutorials)
# This should be changed to whatever you set DocumentRoot to.
<Directory "D:\webserver">
Listen 80
ServerName localhost:80
LoadModule cgi_module modules/mod_cgi.so
# First, we configure the "default" to be a very restrictive set of
# features.
<Directory />
Options FollowSymLinks +ExecCGI
AllowOverride None
</Directory>
DirectoryIndex index.html index.html.var index.cgi index.pl
AccessFileName .htaccess
# To use CGI scripts outside of ScriptAliased directories:
# (You will also need to add "ExecCGI" to the "Options" directive.)
#
#AddHandler cgi-script .cgi .pl
ScriptAlias /cgi-bin/ "C:/Apache/Apache2/cgi-bin/"
When browser is printing code of script that means it's unable to find the application to run the script. Below two lines should be your first steps to solve this. AddHandler will make sure files ending with .cgi and .pl to be treated as cgi scripts. And +ExecCGI option will allow to execute the script. Also make sure your script is pointing to correct perl binary location.
AddHandler cgi-script .cgi .pl
Options FollowSymLinks +ExecCGI
Also There are some mistakes/misconfiguration points in your httpd.conf
Alias line should point to cgi-bin directory where your cgi scripts are present.
ScriptAlias /cgi-bin/ "D:\webserver\cgi-bin"
For same cgi-bin directory following configuration should be in httpd.conf. You should replace your <Directory "D:\webserver"> part with below.
<Directory "D:\webserver\cgi-bin" />
AddHandler cgi-script .cgi .pl
Options FollowSymLinks +ExecCGI
AllowOverride None
</Directory>
Try running your cgi script from command line like below. It should print or run from command line first.
perl test.cgi
Make sure you have read-write recursive permissions to cgi-bin directory and your cgi script. And also you can create directory or file with write permissions. If not create a cgi-bin directory at some other place where you can have write permissions and provide rather its path in alias and directory attributes in httpd.conf instead.
Check apache error log for exact error message every time you run into apache conf issues. It will give you good insight into the problem.
Also this link should help you.
(Extra comment, not by the original answerer: You may also need to enable the cgi module. For me, the final step to getting cgi to work on a fresh install of Apache 2 was sudo a2enmod cgi. Before I did that, the website simply showed me the contents of the script.)
sudo a2enmod cgi
The directory/location/file doesn't have the right handler associated with it, or doesn't have the ExecCGI option enabled. See Apache Tutorial: Dynamic Content with CGI.
change new version of apache :
Options +FollowSymLinks +ExecCGI
on mac os x 10.8
i had to do this
<Directory />
Options FollowSymLinks +ExecCGI
AllowOverride None
</Directory>
and
uncomment this
#AddHandler cgi-script .cgi .pl
# use types www.site.com/visible-in-url
# Apache serves /var/path/to/dir
ScriptAlias /visible-in-url/ /var/path/to/dir/
# Note the order of the aliases matters - first cgi than static content
# Note this dir is a symlink pointing to the desirable directory
<Directory "/var/path/to/dir">
AddHandler cgi-script .cgi .pl
AllowOverride Indexes
Options +ExecCGI +MultiViews +SymLinksIfOwnerMatch
Require all granted
</Directory>
<Files ~ "\.(pl|cgi)$">
SetHandler perl-script
PerlResponseHandler ModPerl::PerlRun
Options +ExecCGI +SymLinksIfOwnerMatch
PerlSendHeader On
</Files>
When browser is printing code of script that means it's unable to find
the application to run the script.
With Apache 2.4 (on OSX Yosemite, 10.10.5), if I use a shebang line with the wrong path, my browser displays:
Internal Server Error
But even with a valid shebang line, I could not get my cgi program to execute by following the advice in the accepted answer--Apache just served up the text of the program to my browser. After some experimenting, I found that the only change I needed to make to my /usr/local/apache2/conf/httpd.conf file was uncommenting the line:
LoadModule cgid_module modules/mod_cgid.so
My cgi programs have the extensions .pl, .py, and .rb depending on what language I'm programming in (and the apache cgi-bin directory contains a test cgi script with no extension), and they all execute without having to specify valid extensions anywhere in the httpd.conf file. My default httpd.conf file has only the following relevant lines:
<IfModule alias_module>
#Lots of comments here
ScriptAlias /cgi-bin/ "/usr/local/apache2/cgi-bin/"
</IfModule>
...
...
<Directory "/usr/local/apache2/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
The shebang line that I'm using is, depending on what language my cgi program is written in:
#!/usr/bin/env perl
or:
#!/usr/bin/env python
or:
#!/usr/bin/env ruby
A cgi program has to be an executable file as well, or else you will get an Internal Server error:
$ chmod a+x myprog.pl
a+x => all + executable. In other words, add the executable permission to each of owner, group, other.
And, at a minimum the cgi program has to generate a Content-Type header before outputting the body of the response:
print "Content-Type: text/html\n\n";
print "<h1>Hello, World.</h1>";
(By the way, that exact code will work in perl, python, or ruby.) Otherwise, once again you will get an Internal Server error.
The url to execute the cgi script:
http://localhost:8080/cgi-bin/myprog.pl
This is how I installed apache:
~/Downloads$ tar xvfz httpd-2.4.18.tar.bz2
...
...
~/Downloads$ cd httpd-2.4.18
...
...
~/Downloads/httpd-2.4.18$ ./configure --help
...
...
--enable-so DSO capability. This module will be automatically
enabled unless you build all modules statically.
...
...
I had no idea what the heck that meant, but the php docs say to install apache with that option, so I went ahead and did this:
~/Downloads/httpd-2.4.18$ ./configure --enable-so
...
...
~/Downloads/httpd-2.4.18$ make
...
...
~/Downloads/httpd-2.4.18$ sudo make install
Apache DSO docs here.
If nothing else has worked, be sure that you're displaying the HTML page that calls your executable script from the local server, e.g. http://192.168.0.15/yourPage.html. If you call it by opening the HTML page in your browser as a file, it will always display your executable script as a file.

How to disable mod_deflate for php using .htaccess file?

How to disable mod_deflate for PHP using the.htaccess file
for files in a specific directory
for all files that have extension of, for example .php?
I have tried both:
# for URL paths that begin with "/foo/bar/"
SetEnvIf Request_URI ^/foo/bar/ no-gzip=1
# for files that end with ".php"
<FilesMatch \.php$>
SetEnv no-gzip 1
</FilesMatch>
They don't work, I can't figure out why. At this point I want to disable it completely for all files in the directory.
Check this out. and reply if it works for you:
SetEnvIfNoCase Request_URI ".php$" no-gzip dont-vary
Let's simplify the issue and slowly make it more complicated as you get each piece working.
First, you stated in a comment: "When I try to access a specific php file on the server FF tells me that that there is a compression problem"
First, see if the issue happens when you disable mod_deflate. Comment out the deflate lines from your apache configuration file(s).
If that indeed fixes it, re-enable mod_deflate, then add these to your virtualhost that is hosting your site (don't mess around with .htaccess yet, that just adds another level of complexity):
SetEnvIfNoCase Request_URI "\.(php)$" no-gzip dont-vary
Try PHP files and see if they are still compressed.
If this works, then add the other condition
SetEnvIfNoCase Request_URI "^/foo/bar/.*" !no-gzip !dont-vary
Finally - put this all in your .htaccess file and Ta-dah!