Proxypass from any subfolder - apache

I'm not that great at proxypass(reverse). So any help would be great.
Here's what I'm trying to do:
I want to pass any subdirectory to the root url.
So hitting mydomain.com/xxxx would get passed to mydomain.com/
What would be the best way to achieve this.
Reasoning is currently we have 55 different variations. And I'd hate to have to create a ProxyPass(Reverse) line for each.

I'm not sure why you want to reverse proxy all of this stuff since the domain never changes. But if for whatever reason you have, you must reverse proxy, you can use ProxyPassMatch which works similar to ProxyPass except you can give it a regex pattern:
ProxyPassMatch ^/(.+)$ http://mydomain.com/
Still, seems to me what you really just want is to internally rewrite instead of sending an entirely new request on behalf of a single request:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/index\.(php|html?)
RewriteRule ^(.+)$ / [L]
Each "sub-folder" is actually used to track where the user obtained the url (think tv, radio, etc) but we don't want to manage 50+ versions of a page. So the idea was to redirect it to the same page, capture the subdirectory value and use that info. Ideally a query string would be nice but we were told not to use them (readability I'm guessing)
If you use a reverse proxy, you lose the info from the landing page. That means if I go to, http://foo.com/bar1, and that gets reverse proxied to http://foo.com/index.php, the index.php script will not know that it was proxied from /bar1 (though I think you can pass that along as proxied headers). So that kind of defeats the purpose. If you internally rewrite, like above, the browser is hidden from it all, and won't know that any internal routing has happened. You can also pass query strings if you like, since everything is completely hidden from the browser:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /index.php?subdir=$1 [L]
So with those rules, if someone goes to http://foo.com/tv and the /tv isn't a folder or file, it gets internally routed to /index.php and the "tv" is passed to the script as the GET parameter "subdir".

Related

htaccess URL rewriting PHP for posts and offers

i've searched for a long time an answer for my issue, I found a lot of ideas, but I can't figure it out and make it work as I expect..
So, I've a website with
"/index.php"
"/posts.php"
What I want is to rewrite the url in order to :
redirect "/index.php", "/index.php/" and "/index/" to "/"
and also :
redirect "/posts/slug-post-1/" to "offers.php" but still display "/posts/slug-post-1/" in which I would split the url to get the slug of the post.
Thanks
What I've tried is :
## To internally redirect /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME}.php -f [NC]
RewriteRule ^ %{REQUEST_URI}.php [L]
It actually display "/offers/" and redirect to "/offers.php"
but when i add a post slug, it doesn't work.
So I've also tried :
RewriteRule ^posts/([^/]*)$ /posts.php?slug=$1 [L]
It works only with ctrl+F5 and not a simple refresh.. I don't understand why. This is the same with different brwoser and computer.
I'll give it a shot :-)
To redirect "/index.php", "/index.php/" and "/index/" to "/".
RewriteRule index(.*)$ / [NC, L]
Edit: I really urge you not to change the default behaviour of a crucial file like index.php in main folder. There will be unforeseen consequences.
And the other one:
RewriteRule posts/slug-post-1(.*)$ offers.php [QSA, NC, L]
In your example:
Your RewriteCond %{REQUEST_FILENAME}.php -f [NC] checks if "requests filename" with .php added is a real existing file.
Use RewriteCond ${REQUEST_FILENAME} !-f to make sure the targeted file is not skipped, although it is existing. !-d would check for directories.
If you want slugs to be added dynamically to the new target, use flag QSA, so [QSA, NC, L] instead of [NC, L], for example. Use the condition before the rule.
This is really a comment - but space is limited.
It looks as if you haven't thought through what you are trying to achieve before trying to implement it.
What I want is to rewrite the url in order to : redirect "/index.php", "/index.php/" and "/index/" to "/"
I think you need to do a lot more searching. Webservers don't serve up directories, they typically have a lot of machinery in place to service up content when presented with a request where the path maps to a directory to change that to a file, a script, or a special handler.
I suspect you want to rewrite /, /index.php/ and /index/ to /index.php
But I suspect there's more to what you are trying to achieve here - that you also want to deal with any string after the pattern you are seeking to match which is implied in your attempts to deal with /posts.
So it looks as if you are trying to implement 2 front controller patterns. Implementing a single front controller pattern appears to be a bit of a stretch for you. Implementing 2 at the same time is unlikely to turn out well and whatever you do finally implement will likely be very fragile. You're going to need a router in /index.php so that is the right place to handle the /posts/ requests.
But this is only PART of the problem you need to solve. Having your PHP code intercepting all requests is rather expensive in terms of CPU and memory (unless you have a really good caching policy implemented on your server and it is sitting behind a caching reverse proxy).

.htaccess vanity url not redirecting properly

I've got a blog subdirectory on my website (foo.com/blog), and I'm following a tutorial that offers a brief explanation of vanity urls.
Basically, I'm trying to get it so that when the user navigates to 'foo.com/blog/xyz' the 'xyz' variable (username) redirects the user to:
foo.com/blog/profile.php?username=xyz
but still displays as:
foo.com/blog/xyz
The code in the tutorial doesn't work, so I've been relying on code in the youtube comments under it:
RewriteBase /
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^(.*)$ http://www.foo.com/blog/profile.php?username=$1 [NC]
The problem is, when I try to navigate to 'foo.com/blog/xyz' it instead redirects to:
foo.com/blog/profile.php?username=blog/xyz
So obviously the username is being set to blog/xyz instead of xyz itself.
Likewise, if navigate to foo.com/xyz, it redirects to where it is supposed to go:
http://www.foo.com/blog/profile.php?username=xyz
But displays this url as it is instead of showing up as foo.com/blog/xyz (like how reddit shows up as reddit.com/u/username for users)
So it appears I have two problems:
1) I can't figure out how to make it so that it only does the rewrite when I navigate to foo.com/blog/xyz rather than foo.com/xyz (.htaccess is in public_html -- I tried moving it to public_html/blog but it didn't work)
2) I can't figure out how to get it to display as blog/xyz instead of blog/profile?php?username=xyz
I don't know much about apache, and I really just need to get this one piece of code right so I can continue bashing my head against the wall with the rest of the tutorial. Does anyone know what I'm doing wrong?
Well, you never mentioned in your rule set anything about how to treat that/bog part of the request path. Do it...
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?blog/(.*)$ /blog/profile.php?username=$1 [L]
I also cleaned up a few other issues with the code you posted which would prevent it from working as you claim at all.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Change URL in browser without redirection with htaccess

I've looked everywhere to find the proper solution/method but I can't seem to find anything that works for me.
I even asked friends and they helped but none prevailed.
What i'm trying to do is, changing the URL displayed in the browser but only that. (No rediraction, page re-loading).
I want to do this to make my UCP just cleaner looking when going through certain pages/files.
What am I trying to achieve?
Heres an example on a profile, the URL would be:
mysite.com/ucp/profile.php?player=Heartfire
However, I want it to look like
mysite.com/ucp/profile/heartfire
Or something else! I just want to get rid of the parameters AFTER the .PHP
I've tried various examples found with google and this website but none seems to work, could somebody please guide me along the way to achieve the result.
what have I tried so far?
Here are a few examples of what I tried before:
RewriteRule ^profile/([0-9]+)/?$ /ucp/profile.php?player=$1
RewriteRule profile.php?player=$1 profile.php [NC,L]
RewriteRule ^profile$ profile.php?player=$1
So what am I doing wrong that it isn't working?
Put the following in .htaccess file inside website's root directory:
RewriteEngine On
RewriteCond %{THE_REQUEST} ^GET\ /ucp/profile\.php?([^=]+)=(\S+) [NC]
RewriteRule ^ucp/profile\.php$ /ucp/%1/%2? [R=301,L,NC]
# Now, deal with internal rewrites (which will not cause redirection):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ucp/([^/]+)/([^/]+)/?$ /ucp/profile.php?$1=$2 [NC,L]
You can use internal redirects what will not change your url but map your request as your wanted.
What you want is impossible because:
Htaccess and rewrite is at server side. The request arrived to the server, need to rewrite at serverside and you need to change it in the clients url bar.
To achieve this the server should send a redirect with the url what you expected. This ia why redirect is mandatory. Server can't rewrite clients urls, just can send a redirect response.
Internal redirect can simulate you something like the request was what you expected but it is transparent at for the clients.
Btw, permanent redirect is the right solution here to notify the user and give the chance to let them know the resource has been changed and update the bookmark / api / whatever.

Simple mod_rewrite for search querystring

I am trying to rewrite
/search?keyword=foobar
to
/search/foobar
without much success.
I currently have the following which seem to produce a 404:
RewriteCond %{QUERY_STRING} ^keyword=(.*)$ [NC]
RewriteRule .* /search/%1? [L,R=301]
Unless you have a resource at /search/foobar then of course you're going to get a 404. Two entirely different things are happening here. The server has a physical resource that gets served (or a script that runs) that apache knows about. If apache sees /search/foobar, it is going to look for a directory called "search" and either a directory or a file called "foobar". If it sees neither, it's going to return a 404. The other part of what's happening is the browser, completely separate from apache, sees a URL (e.g. /search/foobar) and does what it needs to do in order to request for the resource. It talks to the webserver and asks for /search/foobar.
When the request comes in, it's up to the URL-file processing pipeline to turn that into a file which points to where the resource is. If mod_rewrite takes the URL and rewrites it to /blah/blah/blah, there better be a directory called /blah/blah and a file in there called blah or else it's going to 404.
Your rules are saying, if an incoming request is for anything with the query string ?keyword=(something), then redirect the browser to /search/(something). The browser sees this, and does what it's supposed to do; it sends another request for /search/(something). Apache's going to see this and wonder what the request is all about, not knowing what the request is for, and return 404.
What you probably want is to first, handle the /search/(something) URI's
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?search/(.*)$ /search?keyword=$1 [L,QSA]
So when a request comes in as /search/foobar, the rewrite engine internally rewrites it to something apache can understand, /search?keyword=foobar. This internal rewrite happens entirely on the server, the browser is ignorant of it.
Now, when a form is submitted as a GET method, you'll end up with a ?keyword=(something) in the URL, and it looks like you're trying to get rid of that. So apache gets the query string, and there must be something to redirect the browser to the nicer looking URL, at which point the browser does its thing, submits a brand new request, which gets internally rewritten by the above rule back to what it should be.
RewriteCond %{THE_REQUEST} \?keyword=([^\ &]+)&?([^\ ]*)
RewriteRule ^ /search/%1?%2 [L,R=301]
I sorted it out with the following:
RewriteRule search/(.*)$ /search?keyword=$1 [L]
RewriteCond %{THE_REQUEST} \?keyword=([^\ &]+)&?([^\ ]*)
RewriteRule ^ /search/%1?%2 [L,R=301]
but not quite. Having issues where there are multiple querystrings or some other URLs containing search/ in the URL, eg. /search/css/foobar.css?version=152

How do I hide actual directories using mod_rewrite?

I am hosting a couple of domains of the same wordpress installation, now I'd like to have a per-domain folder for some various files I need to put up there.
Essentially I want to map like this:
URL Path
webbfarbror.se/f/* _files/webbfarbror.se/*
grapefrukt.com/f/* _files/grapefrukt.com/*
This little snippet does the job nicely and the RewriteCond let's me enable and disable this on a per domain basis.
ReWriteCond %{HTTP_HOST} webbfarbror.se
ReWriteRule ^f/(.*)$ _files/%{HTTP_HOST}/$1 [L]
However, a file at say, http://grapefrukt.com/f/awesome.jpg is also accessible at it's "real" URL http://grapefrukt.com/_files/grapefrukt.com/awesome.jpg
All my attempts result in infinite redirects back and forth.
How do I disable access through the latter URL?
You can examine the original request as it was sent to the server, which is available as %{THE_REQUEST}. Checking for the /_files/ prefix indicates that the request was of the latter type, and you can then redirect to the appropriate format:
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/_files/
RewriteRule ^_files/[^/]+/(.*)$ http://%{HTTP_HOST}/f/$1 [R=301,L]