htaccess directories, files and variables - file

I am trying to get something similar to $_SERVER["PATH_INFO"] but weird server issues are preventing me from using it...
In my application, the links can look like
www.domain.com/folder/file/variable
www.domain.com/folder/file
www.domain.com/file/variable or
www.domain.com/file/
With .htaccess, I am trying to get to the proper pages, and not to redirect to the index.php or similar.
So far, I have this, which is not working :)
RewriteRule ^(.+)$ /$1.php # page only
RewriteRule ^(.+)/(.+)$ /$1.php?x=$2 # page + variable
RewriteRule ^(.+)/(.+)$ /$1/$2.php # folder / page
RewriteRule ^(.+)/(.+)/(.+)$ /$1/$2.php?x=$3 # folder / page + variable
I am sure I need to use RewriteCond %{REQUEST_FILENAME} -f to check if the request is a filename, or directory... but I was unable to make it work...
Variables can contain all weird characters - that is why i am matching with dot... Maybe I should try to match file / folder names with a-z only ( since i do not think they will ever contain anything but a-z, _ or - ).
Any help is greatly appreciated, since its been almost two days of agony now :)

Reverse the Rewrite Rule the most specific to the first.
RewriteEngine On
RewriteRule ^(.+)/(.+)/(.+)$ /$1/$2.php?x=$3 [L]
# RewriteRule to check that the file is exists here
RewriteCond %{REQUEST_URI} ^(.+)/(.+)$
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI}.php -f
RewriteRule ^(.+)/(.+)$ /$1/$2.php [L]
# If file is not exists, then check by put to the variable
RewriteRule ^(.+)/(.+)$ /$1.php?x=$2 [L]
RewriteRule ^(.+)$ /$1.php [L]

Most people/frameworks pass everything that does not have an extension specified to a single php front controller that then works out what to do. I think one reason most people go this route is because of simply how complex mod_rewrite is!

thanks to #LazyOne's hint, I was able to solve this.
htaccess file now looks something like this:
RewriteRule ^([-a-zA-Z0-9_]+)/([-a-zA-Z0-9_]+)/([-a-zA-Z0-9_]+)$ /$1/$2.php?x=$3
RewriteRule ^([-a-zA-Z0-9_]+)/([-a-zA-Z0-9_]+)/$ /$1/$2.php
RewriteRule ^([-a-zA-Z0-9_]+)/([-a-zA-Z0-9_]+)$ /$1.php?x=$2
RewriteRule ^([-a-zA-Z0-9_]+)/$ /$1.php
all folder or files paths must end with "/" while variable must not. this is not a problem in my framework - but might not be useful for others.

Related

Apache2 - How to build different site with different web address

I want to create site in the same IP but with different sub folder, for example:
http://192.168.0.1/a/ --> /var/www/site_a/
http://192.168.0.1/b/ --> /var/www/site_b/
The config:
<VirtualHost *:80>
#Site name
ServerName 192.168.0.1
#Root folder
DocumentRoot /var/www/site_a/
#log
ErrorLog /var/www/binapk/logs/error.log
#Access log
CustomLog /var/www/binapk/logs/access.log combined
Alias /a /var/www/site_a/
Alias /b /var/www/site_b/
</VirtualHost>
But if you enter http://192.168.0.1 (without /a or /b), it will show the same page as http://192.168.0.1/a/, I want http://192.168.0.1/ is nothing show up.
How to do that?
The few lines that you have specifying the DocumentRoot:
#Root folder
DocumentRoot /var/www/site_a/
are pointing your http://192.169.0.1/ to the /a folder, you would want to point it at something else in order to have it load a different document.

How to clear the content of multiple files in UNIX

I often have to clear content of all files in a directory (i.e. Apache Tomcat logs). I am using UNIX's redirection operator this way:
> catalina.out
How can I apply it to all files in the current directory (to clear all logs)?
I tried > *.* but it doesn't make sense. Thanks for help.
A little loop can make it:
for file in * .* <---- * for normal files // .* for hidden files
do
echo "clearing $file"
> $file
done

Keep mod_security messages out of Apache's error_log, letting it use a separate file

Having set up a new server, I'm now running v2 of mod_security. I was able to convert all my rules to the new format, and everything seems to run fine so far. Just one thing I didn't manage is to have mod_security using its own logs (instead of logging to Apache's error_log). With v1.9 I was at least able to duplicate the messages, defining an additional log file with
CustomLog /path/to/modsec_log "%h %l %u %t \"%r\" %>s %b %{mod_security-message}i" env=mod_security-relevant
But not even that works anymore. I couldn't find anything browsing the questions tagged mod-security2, aunt Google didn't turn up any useful hints either. Is there anything I might have missed?
Do you mean the audit and debug logs? I have them set at modsec2.conf like this
SecAuditLog logs/modsec_audit.log
SecDebugLog logs/modsec_debug_log
In the modsecurity_crs_10_setup.conf file (on my configuration under /usr/share/modsecurity-crs) you can disable the logs on Apache error.log
# -- [[ Alert Logging Control ]] --
# You have three options -
#
# - To log to both the Apache error_log and ModSecurity audit_log file use: "log"
# - To log *only* to the ModSecurity audit_log file use: "nolog,auditlog"
# - To log *only* to the Apache error_log file use: "log,noauditlog"
Just change SecDefaultAction to
SecDefaultAction "phase:1,deny,nolog,auditlog"
Set the Logpath in the modsecurity.conf file as follows:
SecAuditLog /root/...path../logs/modsec_audit.log ( Relative Path )

Is there such a thing as HeaderMatch for apache?

I am "managing" some file's version by setting their last modified date manually when serving them with apache, like so
<Directory />
(...)
Header set Last-modified "Tue, 01 Jan 2013 00:00:00 GMT"
(...)
</Directory>
This already works fine.
If the client honors the cache standard, it should send me the If-Modified-Since header in the next request, where I'd return 304 instead of 200.
Is there any way to accomplish the following without too much hassle? (I don't need fancy processing or anything, the most hardcoded way will work ok for me)
I need something like this (it's obviously in pseudo code):
<HeaderMatch If-Modified-Since>
(...)
If Equals "Tue, 01 Jan 2013 00:00:00 GMT"
Header set Code 304
Else
// Process Directory section
</HeaderMatch>
Any ideas/workarounds?
Well, it was easy.
Using mod_rewrite, I ended up with this
RewriteEngine on
RewriteCond %{HTTP:if-modified-since} "Tue, 01 Jan 2013 00:00:00 GMT" [NC]
RewriteRule .* . [R=304,L]

PHP-FPM is not working as expected

I am using Debian Squeeze and set up PHP-FPM with fastcgi. I have several virtual hosts defined on the same host. I defined chroot for each pool configuration but somehow it is possible to change directory and go above the root directory definition at the pool conf.
disable_functions at the conf file is not working as well. I haven't figured it out the reason.
Sample files are below:
/etc/php5/fpm/pool.d/foo.conf:
[foo]
user = foo
group = foo
listen = 127.0.0.1:9018
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chroot = /var/www/foo
chdir = /
php_admin_value[disable_functions] = dir,chdir,opendir,readdir
php_admin_value[doc_root] = /var/www/foo
php_admin_value[open_basedir] = /var/www/foo
access.log = /var/log/$pool.access.log
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
/etc/apache2/sites-enables/foo.com:
<VirtualHost 19x.xxx.xxx.xx>
DocumentRoot /var/www/foo
ServerName foo.com
<IfModule mod_fastcgi.c>
FastCgiExternalServer /foocgi/php5-wrapper -host 127.0.0.1:9018 -user foouser -group foogroup
ScriptAlias /foocgi/ /var/www/foo/cgi-bin/
AddHandler php5-fastcgi .php
Action php5-fastcgi /foocgi/php5-wrapper
AddType application/x-httpd-php .php
<Directory /var/www/foo/cgi-bin/>
SetHandler fastcgi-script
Options +ExecCGI
</Directory>
</IfModule>
<Directory /var/www/foo>
allow from all
Options -Indexes SymLinksIfOwnerMatch
</Directory>
</VirtualHost>
/var/www/foo/cgi-bin/php5-wrapper:
#!/bin/sh
PHPRC=/etc/php5/cgi/
export PHPRC
#export PHP_FCGI_MAX_REQUESTS=5000
#export PHP_FCGI_CHILDREN=8
exec /usr/lib/cgi-bin/php
/etc/apache2/mods-enabled/fastcgi.conf:
<IfModule mod_fastcgi.c>
FastCgiConfig -autoUpdate -singleThreshold 100 -killInterval 300 -idle-timeout 240 -maxClassProcesses 1 -pass-header HTTP_AUTHORIZATION
FastCgiWrapper /usr/lib/apache2/suexec
<Directory "/var/www/cgi-bin/">
AllowOverride none
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
</IfModule>
/var/log/foo.access.log is empty though port 9018 is LISTEN at netstat output. The site is being opened without errors also. Any idea about the chroot problem or how to make the disable_functions work?
Can you show your phpinfo()?
May you load PHP.ini from /etc/php5/cgi/php.ini and from your php-fpm config, from pool.d/* or from /etc/php5/fpm/php.ini
I say that for:
#!/bin/sh
PHPRC=/etc/php5/cgi/
export PHPRC
#export PHP_FCGI_MAX_REQUESTS=5000
#export PHP_FCGI_CHILDREN=8
exec /usr/lib/cgi-bin/php
php5-fpm is usually in /usr/sbin/php5-fpm

Resources