How can I proxy a query string URL in Apache? - apache

I'm trying to get an older Apache (2.2.17) to proxy:
http://foo.com/proxy/?url=http%3A%2F%2Fbar.com%2foo
to:
http://bar.com/foo
I have:
RewriteCond %{QUERY_STRING} ^url=(.*)$
RewriteRule ^/proxy/ %1? [P,L]
Unfortunately, this results in Apache trying to proxy the URL-encoded value (log output) :
(3) applying pattern '^/proxy/' to uri '/proxy/'
(4) RewriteCond: input='url='http%3A%2F%2Fbar.com%2foo'' pattern='^url=(.*)$' => matched
(2) rewrite '/proxy/' -> ''http%3A%2F%2Fbar.com%2foo'?'
(3) split uri='http%3A%2F%2Fbar.com%2foo'? -> uri='http%3A%2F%2Fbar.com%2foo', args=
(2) forcing proxy-throughput with http://foo.com/'http%3A%2F%2Fbar.com%2foo'
(1) go-ahead with proxy request proxy:http://foo.com/'http%3A%2F%2Fbar.com%2foo' [OK]
So, it appears there are two problems. One is that there are apostrophes in the result and the other is that the result is not URL decoded. I assume the reason Apache is prepending the original protocol://host is that it doesn't see the result as an URL.

If you have access to vhost/server config (and it looks like you do), you can configure one of apache's built in rewrite maps to unescape for you:
RewriteMap unescape int:unescape
Then you can use the map in your rules:
RewriteCond %{QUERY_STRING} ^url=(.*)$
RewriteRule ^/proxy/ ${unescape:%1}? [P,L]

Related

What does this apache rewrite means?

RewriteCond %{QUERY_STRING} (.*)\?mem=stats$
RewriteRule ^/(.*)$ http://X.X.X.X/$1?%1 [P,L]
If the request is /asdf?mem=stats, will it rewrite to /asdf?mem=stats?asdf ?
since $1 is asdf?mem=stats and %1 is asdf ???
The %{QUERY_STRING} variable contains the query string without the leading ? (or anything before it), so %1 will never contain part of the request before query string.
If you enable mod_rewrite logging by adding LogLevel rewrite:trace6 to your VirtualHost configuration, you will see this for your RewriteCond and /asdf?mem=stats request:
... RewriteCond: input='mem=stats' pattern='(.*)\\?mem=stats$' => not-matched
Also, in your RewriteRule, pattern will be matched against the part of the URL after the hostname and port, and before the query string. Therefore $1will, even on wildcard match, not contain the query string part of the request. You can see that in log as:
... applying pattern '^/(.*)$' to uri '/asdf'

Rewrite condition not kicking in - Apache mod-rewrite based on existence of a query string -

I have a requirement where if a link has a particular querystring parameter then it should be intercepted and redirected to another url
My current config looks like this
<IfModule rewrite_module>
RewriteEngine On
RewriteLog /cfp/apps/t/ts/x/logs/mod_rewrite.log
RewriteLogLevel 9
RewriteCond %{QUERY_STRING} /link_source/
RewriteRule (link_source=email) http://dev1.domain.net:12080/m [R]
</IfModule>
My test url is this
http://dev1.domain.net/web/messages/7029?link_source=email
i expect this url to be caught by this rule(because link_source exists as a query string) and redirected to the new url however that doesn't seem to be happening
On the rewrite logs this is what I see
102.2.81.95 - - [25/Jun/2014:13:41:18 --0400] [devash-ecfpwb01.svr.us.jpmchase.net/sid#d625588][rid#d7aec60/initial] (2) init rewrit
e engine with requested uri /a/messages/7029
102.2.81.95 - - [25/Jun/2014:13:41:18 --0400] [devash-ecfpwb01.svr.us.jpmchase.net/sid#d625588][rid#d7aec60/initial] (3) applying pa
ttern '(link_source=email)' to uri '/a/messages/7029'
102.2.81.95 - - [25/Jun/2014:13:41:18 --0400] [devash-ecfpwb01.svr.us.jpmchase.net/sid#d625588][rid#d7aec60/initial] (1) pass through /a/messages/7029
Why is this rule not coming into effect and also from the logs it prints the url minus the request params.Is there a way to enable the logging of the query params on the request.
Please help
The syntax is not quite right. Change your condition and rule to this:
RewriteCond %{QUERY_STRING} link_source=email
RewriteRule ^ http://dev1.domain.net:12080/m?

Trouble with serving local content while using RewriteRule [P]

I'm trying to write rules that will serve files on the new server, while proxying files that don't exist, to the old server. The proxy rules work fine, sending missing files and directories to the old server.
The problem I'm having is new-server.example.com/blah (/blah/ exists on the new server) is passed through to the proxy rules and routed to the old server.
The reason for attempting the skip is because new-server.example.com/blah falls through to the "proxy section" and passes new-server.example.com/blah/index.php. Index.php doesn't exist on the new server, index.html does. The "proxy section" doesn't follow all the index file possibilities in DirectoryIndex, it just looks at the first one.
So I end up with error message, "The requested URL /blah/index.php was not found on this server."
How can this be written so it actually works? -- Thanks.
RewriteEngine On
# skip, proxy section
RewriteCond /var/www/html%{REQUEST_FILENAME} -f [OR]
RewriteCond /var/www/html%{REQUEST_FILENAME} -d
RewriteRule .? - [S=4]
# proxy section
RewriteCond /var/www/html%{REQUEST_FILENAME} !-f
RewriteCond /var/www/html%{REQUEST_FILENAME} !-d
RewriteRule ^/(.*) http://old-server.example.com/$1 [P]
ProxyPassReverse / http://old-server.example.com/
# rewrite log
pass through /index.php
init rewrite engine with requested uri /
applying pattern '.?' to uri '/'
RewriteCond: input='/var/www/html/' pattern='-f' => not-matched
RewriteCond: input='/var/www/html/' pattern='-d' => matched
pass through /
init rewrite engine with requested uri /index.php
applying pattern '.?' to uri '/index.php'
RewriteCond: input='/var/www/html/index.php' pattern='-f' => matched
pass through /index.php
init rewrite engine with requested uri /blah/
applying pattern '.?' to uri '/blah/'
RewriteCond: input='/var/www/html/blah/' pattern='-f' => not-matched
RewriteCond: input='/var/www/html/blah/' pattern='-d' => matched
pass through /blah/
init rewrite engine with requested uri /blah/index.php
applying pattern '.?' to uri '/blah/index.php'
RewriteCond: input='/var/www/html/blah/index.php' pattern='-f' => not-matched
RewriteCond: input='/var/www/html/blah/index.php' pattern='-d' => not-matched
applying pattern '^/(.*)' to uri '/blah/index.php'
RewriteCond: input='/var/www/html/blah/index.php' pattern='!-f' => matched
RewriteCond: input='/var/www/html/blah/index.php' pattern='!-d' => matched
rewrite '/blah/index.php' -> 'http://old-server.example.com/blah/index.php'
forcing proxy-throughput with http://old-server.example.com/blah/index.php
go-ahead with proxy request proxy:http://old-server.example.com/blah/index.php [OK]
This is the way Apache has worked since version 2.0: It gets a request, runs that request through all of the RewriteRules, then if the resulting request is a directory, it tries to see if the first DirectoryIndex will work, so it runs that through the RewriteRules and tries to serve the result. If the first DirectoryIndex entry doesn't work (i.e. it gets to the point where Apache would have served a 404), the server tries again with the next entry and so on. Your problem, obviously, is that the proxy rules latch on to the nonexistent first DirectoryIndex value and try to send it through the reverse proxy.
I haven't found a general way to fix this behavior server-wide, but there is a workaround. Use either a <Location> section in your httpd.conf file or a .htaccess file and override DirectoryIndex for that location.
In your case, create the file /var/www/html/blah/.htaccess and put the following into it:
DirectoryIndex index.html

mod_rewrite: args lost

I want to do a easy(?) rewriting.
Here is my .htaccess:
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/batiments-[0-9]+/?$
RewriteRule ^batiments-([0-9]+)/?$ a_batiments.php?e=$1
I want this rewriting: http://xyz.com/batiments-123 ==> http://xyz.com/a_batiments?e=123
I obtain only the address: http://xyz.com/a_batiments, without the argument.
In the rewrite log, I see a line containing a split:
192.168.0.2 -(very long line suppressed) (3) split uri=a_batiments.php?e=123 -> uri=a_batiments.php, args=e=123
I understand the split is useful for the matching, but the args is never put back in the address. Why? What to do?
Try adding the [R] flag to the RewriteRule. That way the rewrite results in a HTTP redirection being sent to the client.

mod_rewrite question

I would like to serve /foo and /foo/ locally, but proxy requests for /foo/* to a remote server. However, the following rule matches all of the above. What am I doing wrong?
RewriteRule ^/foo/(.+)$ http://remote.host/$1 [P,L]
You will need to escape for the first couple of conditions so that they don't all send them off to the remote host. Try this:
RewriteEngine On
RewriteRule ^foo$ /$1 [L]
RewriteRule ^foo/$ /$1 [L]
RewriteRule ^foo/([a-zA-Z0-9].*)$ http://example.com/$1 [L]
First rule checks the first condition to be plainly /foo. If so, stay at home.
Next test checks to see if it's not just /foo/. If so, again, stay local.
Last test checks to see if you have anything dangling behind a slash, if so, then you probably want the remote host and sends it there.
Well, since mod_rewrite normally strips leading slashes from the matched text, I suspect you're either transcribing/anonymizing imperfectly or there's a good deal else going on in your rewrite configuration. That seems further borne out by the impossibility of the pattern /foo/.+ matching /foo.
Can you expand and double-check what you're posting from your rewrite config, so we can see what else might be going on?
I think I got it -- somewhere the default docname is being set to index.php, which is silently being appended to my rewrite.
RewriteLog output:
(2) init rewrite engine with requested uri /foo
(3) applying pattern '^/foo(/.+)+$' to uri '/foo'
(1) pass through /foo
(2) init rewrite engine with requested uri /foo/
(3) applying pattern '^/foo(/.+)+$' to uri '/foo/'
(1) pass through /foo/
(2) init rewrite engine with requested uri /foo/index.php
(3) applying pattern '^/foo(/.+)+$' to uri '/foo/index.php'
(2) rewrite '/foo/index.php' -> 'http://remote.host//index.php'
(2) forcing proxy-throughput with http://remote.host//index.php
(1) go-ahead with proxy request proxy:http://remote.host//index.php [OK]