Apache RewriteMap and hiding the URL - apache

I'm trying to implement persistent URLs under Apache and I'm having trouble getting the URL passed back from the RewriteMap to remain hidden. That is, if I have the PURL:
http://www.mysite.com/psearch?purl=12345
and the mapped value for it is:
http://www.mysite.com/search?name=test&type=test2
I want the PURL to be the URL displayed in the browser address bar. Unfortunately, it keeps displaying the site that the PURL maps to instead. My rule is the following:
RewriteCond %{REQUEST_URI} /psearch(/)*$
RewriteMap mapper prg:/scripts/rewritetest.pl
RewriteRule ^/(.*)$ ${mapper:$1} [L]
All the mapper does right now is return a URL for a test page on the system, since I'm trying to get the address hiding working. And I know I'm not grabbing the parameters right now, I'm just trying to get the test running using the psearch keywork, and will add the rest later if it's possible to hide the address.
Any help is appreciated, Thanks!

Turns out the problem was that I was returning the full URL, which forced a full redirect. Passing back just the REQUEST_URI portion made things work.
Forcing the headers to expire also helped, since things were getting cached that were obscuring when something was working properly.

Related

htaccess redirect url with anchor tag

I am trying to redirect a URL to a page with an anchor tag. The redirect works but how do I keep the original URL after the redirect rather than the redirected one.
I want to redirect www.example.com/caves/ to www.example.com/trips.html#caves.
When I redirect I get the URL www.example.com/trips.html#caves but want it to keep www.example.com/caves/.
I have spent ages looking for answers but no luck, any help would be appreciated
Here is my code in htaccess
RewriteEngine on
RewriteRule ^Caves/(.*) /trips.html#Caves [NE,L,R]
I doubt it can be done. Anchor is a client side directive and you can't "hide" it with server side rewrite (the browser can't jump to anchor if it doesn't see one), so the anchor has to be in address bar URL.
...how do I keep the original URL after the redirect rather than the redirected one.
You want an internal rewrite, as opposed to an external redirect - which is what you are currently doing with the use of the R (redirect) flag on the RewriteRule.
RewriteRule ^Caves/(.*) /trips.html#Caves [NE,L,R]
Ordinarily you could simply remove the R flag to keep the original URL in the address bar. The request is internally rewritten to /trips.html.
However, the fragment identifier (ie. #Caves - or strictly everything after the #) is lost. The request is rewritten to /trips.html, not /trips.html#Caves. The fragment identifier is evaluated by the client, not the server and is no doubt being used by your client-side JavaScript to display the appropriate content. Because of the internal rewrite, the client-side JavaScript never gets to see the fragment identifier.
However, if you are internally rewriting the request (ie. /Caves/ is still present in the address bar) then your client-side code doesn't need the #Caves fragment identifier. It can simply look at the original URL, ie. /Caves/ instead. But this will require a small change to your client-side code.
(Aside... Note that you are using Caves (capital first letter) in your code, but referring to caves (all lowercase) in your description. The directive you have written is case-sensitive, so it should be /Caves/, not /caves/ in your description?)

Manipulate user's address bar with mod_rewrite

I have a page at example.com/themizer.php, but I want it to appear that it's actually located at example.com/themizer/ (or example.com/themizer/index.php) for all practical purposes. I know how to basically make an alias for it with mod_rewrite, but how do I make it appear that users are being redirected to that alias? Example: a user requests example.com/themizer.php and the address in their browser turns into example.com/themizer/ without actually redirecting. Is this possible?
With server-sided configuration, you can only accomplish this with a redirect. This does not necessarily need to be a problem. Just make sure that the urls on your site point to the fancy url and not to the internal url. Otherwise you generate a lot of requests that have to be redirected, instead of just redirecting the odd request that came in in an other way (e.g. through an external old url or old bookmark). You do it like this:
#External redirect
RewriteCond %{THE_REQUEST} ^GET\ /themizer\.php\ HTTP
RewriteRule ^themizer\.php$ /themizer/ [R,L]
#Internal rewrite
RewriteRule ^themizer/?$ themizer.php [L]
If you really must, you can use javascript to 'push' a new window state into the history, updating the address bar. This causes the "go to previous page" button in your browser to contain bogus though. In other words: Going to the previous page does not work as expected, which I would not recommend since there is a better option available. You can do it with the following javascript statement in browsers that support it:
window.history.pushState( null, document.title, "/themizer" );

Understanding difference between redirect and rewrite .htaccess

I'd like to understand the difference between redirecting and rewriting a URL using .htaccess.
So here's an example: Say I have a link like www.abc.com/ index.php?page=product_types&cat=88 (call this the "original" url)
But when the user types in abc.com/shoes (let's call this the "desired" url), they need to see the contents of the above link. To accomplish this, I would do this:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)shoes(.*)$ index.php?page=product_types&cat=88
Nothing wrong with this code and it does the trick. However, if I type in the original url in the address bar, the content comes up, but the url does not change. So it remains as www.abc.com/index.php?page=product_types&cat=88
But what if I wanted the desired url (/shoes) to show up in the address bar if I typed in www.abc.com/ index.php?page=product_types&cat=88? How would this be accomplished using .htaccess? Am I running into a potential loop?
Some of the explanation can be found here: https://stackoverflow.com/a/11711948/851273
The gist is that a rewrite happens solely on the server, the client (browser) is blind to it. The browser sends a request and gets content, it is none the wiser to what happened on the server in order to serve the request.
A redirect is a server response to a request, that tells the client (browser) to submit a new request. The browser asks for a url, this url is what's in the location bar, the server gets that request and responds with a redirect, the browser gets the response and loads the URL in the server's response. The URL in the location bar is now the new URL and the browser sends a request for the new URL.
Simply rewriting internally on the server does absolutely nothing to URLs in the wild. If google or reddit or whatever site has a link to www.abc.com/index.php?page=product_types&cat=88, your internal server rewrite rule does absolutely nothing to that, nor to anyone who clicks on that link, or any client that happens to request that URL for any reason whatsoever. All the rewrite rule does is internally change something that contains shoes to /index.php?page=product_types&cat=88 within the server.
If you want make it so a request is made for the index.php page with all of the query strings, you can tell the client (browser) to redirect to the nicer looking URL. You need to be careful because rewrite rules loop and your redirect will be internally rewritten which will cause a redirect which will be internally rewritten, etc.. causing a loop and will throw a 500 Server Error. So you can match specifically to the request itself:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\?page=product_types&cat=88
RewriteRule ^/?index.php$ /shoes [L,R=301]
This should only be used to make it so links in the wild get pointed to the right place. You must ensure that your content is generating the correct links. That means everything on your site is using the /shoes link instead of the /index.php?page=product_types&cat=88 link.

Prevent users from accessing files using non apache-rewritten urls

May be a noob question but I'm just starting playing around with apache and have not found a precise answer yet.
I am setting up a web app using url-rewriting massively, to show nice urls like [mywebsite.com/product/x] instead of [mywebsite.com/app/controllers/product.php?id=x].
However, I can still access the required page by typing the url [mywebsite.com/app/controllers/product.php?id=x]. I'd like to make it not possible, ie. redirect people to an error page if they do so, and allow them to access this page with the "rewritten" syntax only.
What would be the easiest way to do that? And do you think it is a necessary measure to secure an app?
In your PHP file, examine the $_SERVER['REQUEST_URI'] and ensure it is being accessed the way you want it to be.
There is no reason why this should be a security issue.
RewriteCond %{REDIRECT_URL} ! ^/app/controllers/product.php$
RewriteRule ^app/controllers/product.php$ /product/x [R,L]
RewriteRule ^product/(.*)$ /app/controllers/product.php?id=$1 [L]
The first rule will redirect any request to /app/controllers/product.php with no REDIRECT_URL variable set to the clean url. The Rewrite (last rule) will set this variable when calling the real page and won't be redirected.

How does URL rewriting work?

I am new to URL rewriting and I have an .htaccess file that looks like this:
RewriteEngine On
RewriteRule /*\.(css|js|gif|png|jpe?g)$ - [NC,L]
RewriteRule "^(.*)$" "www/index.php?_url=$1" [QSA,L]
Does this code just rewrite the code internally, or is it supposed to change to URL in the address bar? As of now it does not change the address bar, and I'm not really sure yet but I am thinking that I will probably want the option to do so for bookmarking purposes. So if there is a way could you please let me know or direct me to a pretty noob friendly guide on URL rewriting where I can figure it out on my own because I haven't been able to find one.
Thanks for the help!
As it stands, it will just do an internal rewrite. To redirect the user (thereby changing their address bar), add R to the flags (e.g. [NC,R,L] or [R,QSA,L])
URL rewriting is completely server-side (unless you do a redirect). The client (and thus their address bar) will not know what the server is doing with the URL.
Here's a good beginner tutorial that explains URL rewriting and goes through progressively more complex examples.