Pass variables from htaccess to bash script - linux

I'm trying to pass the value of a cookie to a bash script:
RewriteCond %{HTTP_COOKIE} mycookie=(.*) [NC]
RewriteRule .* script.sh?cookievar=%1
... but can't seem to find out how to read the GET variable in the bash script. (I suppose I'm asking Google the wrong queries, but can't find any info on this).
Is this even possible, and if so, please how?
Thanks, David

You have to look at QUERY_STRING environment variable in Bash in order to access GET variables. In your case it should be set to cookievar=VALUE. To extract a variable's value, use something like this:
COOKIEVAR=$(echo ${QUERY_STRING} | sed -n -e 's/^.*cookievar=\([^&]*\).*$/\1/p' -e 's/%20/ /g')
Good luck!

Related

export .htaccess variable to shell or script

In .htaccess file, I have this line RewriteRule ^(.*)$ script.sh?sub=$1
Is there anyway to show the value of $1 in the shell
command like echo $sub
or can I pass $1 as a parameter to script.sh?
You can set an environment variable - is that readable from your script? For example, to set an environment variable called MY_VARIABLE to the value of the $1 backreference:
RewriteRule ^(.*)$ script.sh?sub=$1 [E=MY_VARIABLE:$1,L]
I've also added the L (last) flag just in case. Maybe you can remove the ?sub=$1 part if it's not being used?

htaccess rewrite path to multiple parameters

I am trying to rewrite URL1 to URL2. Can anybody help?
URL1:
http://www.localhost.de/stellenangebote/ort/hannover/200
URL2:
http://www.localhost.de/path/to/my/script.php?location=hannover&radius=200
Apache uses basic regexes for rewriting so you can use multiple capture groups "()" and reference them using $1 for the contents of the first capture group, $2 for the second and so on. In your case the following should work:
RewriteEngine On
RewriteRule ^stellenangebote/ort/([a-z]+)/([0-9]+) /path/to/my/script.php?location=$1&radius=$2

setting and using owne variable in .htaccess

I set variable in .htaccess like this
SetEnv clubhub_path clubhub-ui
And I can acces it in php with
$_SERVER['clubhub_path];
But I wanted to use it in .htaccess in Rewrite Cond
RewriteCond %{REQUEST_URI} ^(?!/%{SERVER:clubhub_path}/media/).+ [NC]
I found somewhere this(%{SERVER:clubhub_path}) should work but it doesn't. I tried all the combinations with {}, %, $. No success...
Cheers
SetEnv sets environment variables, so it should be available in %{ENV:clubhub_path} but i've tried that and doesn't seem to be working.
However since you can set environment variables with RewriteRules you could write it like this:
RewriteRule ^ - [E=clubhub_path:clubhub-ui]
This rule matches every url, but doesn't rewrite it to anyting just sets an environment variable that will be available in RewriteConds like:
RewriteCond %{ENV:clubhub_path} ^clubhub-ui$
This should look like exactly the same once it gets to php. (in $_SERVER superglobal, or getenv())
Update
However you still can't use your %{ENV:variable} in the right hand side of RewriteCond. I think the only way to do this if you are on apache 2.4 and you can use ap_expr
RewriteCond expr "! '%{REQUEST_URI}' -strcmatch '/%{ENV:clubhub_path}/media/*'"
In my test environment this seem to be doing what you want (negative match on the '/clubhub-ui/media' urls, but apache2.4 is still pretty new, you probably can't have it installed if you are not self-hosted.
Maybe RewriteMap with a prg parameter and a script could implement your idea.

Looking for help with 2-tier clean URL's using .htaccess

I am working on a site which will have two levels the URL reaches
My objective is to have clean URL's like this...
http://domain.com/username/dosomething
My ugly URL's currently look like this...
http://domain.com/index.php?page=username&command=dosomething
My attempt was this
RewriteEngine On
RewriteRule ^([a-zA-Z0-9]+)$ index.php?page=$1&command=$2
RewriteRule ^([a-zA-Z0-9]+)/$1/$2 index.php?page=$1&command=$2
You're not using your backreferences correctly in the first part. Backreferences are parenthesised expressions that will then get filled into $1, $2 et al. in the second part of the rule. e.g.:
RewriteRule ^([^/]+)/([^/]+)$ /index.php?page=$1&command=$2
These parenthesized expressions match one or more non-/ characters and fill them into $1 and $2 respectively.
Your references are just referencing your entire URL so what you are telling it to give you is
index.php?page={entire URL}&command={null}
You need to setup the URL and only use parenthesis around the variables page and command. So
^domain.com/([username]+)/(dosomething)
then rewrite with:
http://domain.com/index.php?page=$1&command=$2
provided that your page and command variables are username and dosomething respectively

mod_rewrite RewriteCond based on Last-modified? (.htaccess)

I know that we can easily base a RewriteCond on any http request header. But can we check (some of) the response headers that are going to be sent? In particular, the Last-modified one?
I want to rewrite a url only when the Last-modified date is older than 30 minutes and I'm trying to avoid the overhead of delegating that check to a php file every single time a file from that directory is requested.
Thanks in advance!
No, that’s not possible. But you could use a rewrite map to get that information from a program with less overhead than PHP, maybe a shell script.
Here’s an example bash script:
#!/usr/bin/env bash
while read line; do
max_age=${line%%:*}
filename=${line#*:}
if [[ -f $filename ]]; then
lm=$(stat -f %m "$filename")
if [[ $(date +%s)-$lm -le $max_age ]]; then
echo yes
else
echo no
fi
else
echo no
fi
done
The declaration of the rewrite map needs to be placed in your server or virtual host configuraion file as the program is just started once and then waits for input:
RewriteMap last-modified-within prg:/absolute/file/system/path/to/last-modified-within.sh
And then you can use that rewrite map like this (.htaccess example):
RewriteCond %{last-modified-within:30:%{REQUEST_FILENAME}} =yes
RewriteRule ^foo/bar$ - [L]
RewriteRule ^foo/bar$ script.php [L]
The outbound headers do not exist until much later than mod_rewrite is acting. There also isn't any file-modification-time checking functionality built into mod_rewrite, so the closest you'd get using it is making a RewriteMap of the External Rewriting Program variety to find out whether the file in question has been modified.
If I understand your application correctly, you could also look into having a cron job delete files in that directory that are older than 30 minutes, and then rewriting on a file-nonexistence condition.
Have you considered using mod_proxy, mod_cache, and/or squid? It sounds like you're trying to roll your own caching...

Resources