url rewrite & redirect question - redirect

Say currently I have url like :
http://mydomain.com/showpost.php?p=123
Now I want to make it prettier :
http://mydomain.com/123/post-title
I'm using apache rewrite which grabs segment '123' and put the url back to
http://mydomain.com/showpost.php?p=123
OK. Here is the problem. I want to redirect the original non-pretty urls which were indexed by Google to the pretty versions, I want this because I heard that Google may punish me if he sees multiple urls pointing to identical content. So I need to
redirect /showpost.php?p=123 to /123/post-title
This I have to do in my php code coz there's no way Apache to be able to figure out the 'post-title', but if I put the redirect code in php code, then it will be a infinite loop, such as :
Request : /showpost.php?p=123
redirected to : /123/post-title
rewritten to: /showpost.php?p=123
redirected again to : /123/post-title
...
So on and so forth.
Sorry I should Google the solution first but I really don't know how to describe my situation in English to make Google return reasonable results.
Please help me. Thanks.

You can set a request variable in your rewrite rule, by adding something like [E=rewritten:true] at the end of the RewriteRule line, to record the fact that the rewrite was done. In your PHP, you should be able to access this as $_SERVER['rewritten'], and do the redirect only if the flag is absent.
Alternately, you can use a rewrite rule to redirect the non-pretty URL to the pretty one without the post title, then use application code to issue another redirect with the post title added. Using two redirects is less desirable, of course, but it's only a temporary measure until search engines update their indexes, then you can remove it.
Make sure you use 301 Moved Permanently for your redirect, btw.

Related

Amazon S3 Redirect Rule - Preserve Query Params

I noticed Amazon S3 Redirect rule - GET data is missing but after following the accepted answer my query params still are not being preserved.
I have a site that uses React and React Router, meaning I have several URLs that load identical HTML and JS and then the JS figures out which part of the app to load based on the URL.
For example:
/foo, /bar, /baz all should load index.html, which loads bundle.js. Then bundle.js observes the URL and routes to some React component (also in bundle.js).
However no foo, bar, or baz file exists in S3, only index.html. What I want to do is when I get a 404, redirect to /#!/{URL} (eg. /foo redirects to /#!/foo). This works fine with my redirect rule (below). However, I also want to bring query params with me (eg. /foo?ping=pong redirects to /#!/foo?ping=pong) but instead /foo?ping=pong just redirects to /#!/foo.
Here are my redirect rules:
<RoutingRules>
<RoutingRule>
<Condition>
<HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
</Condition>
<Redirect>
<Protocol>http</Protocol>
<HostName>www.mydomain.com</HostName>
<ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
</Redirect>
</RoutingRule>
</RoutingRules>
Any ideas on some way I can achieve this? Ideally without having to go change something in S3/CloudFront every time I add a new page?
The problem was that I had the origin set up in CloudFront not to forward Query Strings so when S3 got the request it would redirect properly without the query params. You can find this setting in CloudFront > Behaviors > Forward Query Strings.
If you want to have clear urls though you can also check out this trick. You need to setup cloudfront distribution and then alter 404 behaviour in "Error Pages" section of your distribution. That way you can again domain.com/foo/bar links :)
The menus and options in CloudFront/S3 change a lot over time.
Here is a December 2021 solution.
Step 1) Create a "Request" Policy in CloudFront that allows QueryStrings
Note: you might want to also add some Headers like Origin or Access-Control-... headers for CORS.
Step 2) Go to your Distribution > Update the Origin request policy
Step 3) Kick a new Invalidation on /*
Additional Notes for Debuging/Testing
I would recommend testing with curl in terminal rather than a browser to avoid caching and also seeing the details. I do curl -v https://example.com/cb?foo=bar1.
Keep increasing the value of the query string (bar1 in the above example, to bar2, bar3) with every test to make such there is no caching again.

Checking user ip address after redirect

As part of a session security feature I am checking $ENV{REMOTE_ADDR} to make sure the users IP is the same during the whole stay on a website.
Some parts of the website show a waiting screen, if for example the rendering of a file takes some seconds, and I redirect the user to a result screen by the use of a meta tag <meta http-equiv="refresh" content="$time; URL=…">.
Unfortunately after this redirect the $ENV{REMOTE_ADDR} variable does not return the users IP but the one from the server.
Is there something I am missing to get this to work properly and/or are there alternatives I could use to redirect the user?
For various reasons htaccess or http-header redirects are not an option and I don't want to use JavaScript for this.
I am already using a 'click me' button to allow the user to manually skipping the wait.
You could try to alter between temporary/permanent type of redirect. Check in server logs, the the http code is 301 or 302?
I misread the accesslogs … it was actually a different script executed on the server, therefore having the servers IP, which caused all this.

Rails redirect issue with HTTPS because of symlink

This is a little different than all the other Rails 3 redirect https questions out there. Let me explain.
In order to publish our site with Phusion Passenger we had to create a subdomain and use a symlink (or softlink or alias) from the www/rails folder to /home/user/app/railsapp.
In order for the HTTPS to work (because of various domains issues) we need to have a rewrite mod that actually creates this route:
https://my.site.com/rails
Notice the trailing /rails route.
This route does not exist on our app. So what I need is a way to redirect anything that comes in with that route to:
https://my.site.com/login
So I thought I'd do this, in the routes.rb file have this:
match '/rails' => 'sessions#redirect_to_login'
In sessions_controllers.rb:
def redirect_to_login
redirect_to login_path, :status => :moved_permanently
end
This results in the app complaining that it can't find /rais/login/ so it's still seeking that /rails bit.
If I add something like redirect_to "/" which in turn will send you to my.site.com/login with a redirect when you're not logged in, I'll get an error of too many redirects in the browser.
redirect_to login_url didn't do the trick either.
It gets a bit more complicated in the sense that whenever I'm using the https protocol for that site, it will append that /rails route so I need a way to remove it from all the links. For example, https://my.site.com/movies will get translated to https://my.site.com/rails/movies.
Either remove the /rails or redirect all https traffic to http except for the login page.
I'm sure there is a relatively easy fix for this, but I can't figure it out.
Help is appreciated.

Codeigniter Facebook app POST method AND query_string

I have a toy facebook app I'm playing with so I can understand how it all works. It's fine if you go the the app like this: http://apps.facebook.com/pushup-challenge/ (and connect it). But if you then go to it from your facebook page, FB uses the URL http://apps.facebook.com/pushup-challenge/?ref=bookmarks.
In my log file, I see that FB is POSTing the data and including the /?ref=bookmarks to it's call to my codeigniter system. This is causing it to either say "invalid URI parameters" or give me a 404, depending on if I've edited the system/core/URI.php file to add rawurlencode() to a particular call.
I've tried using mod_rewrite to get rid of the query_string, too, but since it's POSTing, it doesn't appear to be working (though I'm not exactly sure why).
Has anyone else run into this? How did you fix it?
Thanks in advance,
Hans
try $config['uri_protocol'] = “PATH_INFO”; and set enable_query_strings = TRUE
or
set
$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-?=';
in config.php
Because it isn't calling your file by name (just ?ref=bookmarks) the server runs thru the standard default files: index.htm, index.html, index.asp. Because you need to accept a POST, you need a server that allows POSTs to htm & html if you choose to use those. Index.asp will accept POSTs on most servers, and that works for me.
SOLUTION: Add a file (index.asp), that calls the real app that you named in the App settings.

Bookmarked page redirect

I recently converted a site from asp to CF. Unfortunately, alot of the old users had the "homepage" bookmarked. www.example.com/homepage.asp
Is there a sort of catch all way I could redirect any traffic from that page to the current index.cfm?
I would normally just delete those files, but the owner(s) wanted to keep it around for their own comparison reasons.
Any ideas?
Thanks
Put this in the old homepage.asp
<%# Language=VBScript %>
<%
Response.Status="301 Moved Permanently"
Response.AddHeader "Location", "/index.cfm"
%>
If you don't want run an onerous asp file at all on the new site, you can do a custom 404 on the web server. If you point the 404 page to a .cfm file, you can extract all the various features from the request by including:
<!--- parse out the text in the URL parameters into an array --->
<cfset variables.requestparams = listtoarray(cgi.query_string,'/?&')>
<!--- get rid of the first 2 items in the array since they dont represent request info --->
<cfset foo = arraydeleteat(variables.requestparams,1)>
<cfset foo = arraydeleteat(variables.requestparams,1)>
You'll be left with an array representing the parameters that were passed in the original request. You can follow up on this by doing whatever analysis you need to on the url components to map it against the analogous pages in your CF site.
I'm surprised nobody has mentioned URL Rewriting. You can use mod_rewrite on *nix/apache, or ISAPI Rewrite or Ionics ISAPI Rewrite on Windows/IIS. I prefer Ionics if I'm on IIS.
The best bet is to do either a meta refresh in the actual homepage.asp page, it is quick and dirty, but works.
A better solution would be to have the .asp page do a 301 redirect to the new homepage, that way when search engines access the page as well they know it has moved.
What I do on Linux machines when I run into something like this is to create a symbolic link (ln -s /path/to/source /path/to/target).
Not sure what the Windows equivalent would be, so going with #Patrick's answer is probably best.
EDIT - The NTFS way of making a symlink:
http://en.wikipedia.org/wiki/NTFS_symbolic_link
see also http://en.wikipedia.org/wiki/Symbolic_link