Forum Moderators: phranque

Message Too Old, No Replies

Apostrophe issue

         

wheelie34

4:09 pm on Jan 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi all

A file name that's generated from a db call has an apostrophy it has been changed to without the apostrophy (it shouldn't have been like that in the first place) how do I put that into my htaccess file to redirect 301 to the correct version without the apostrophy, I have tried this in THAT folders htaccess

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /name's
RewriteRule (.*) http://www.example.com/folder/names [R=301,L]

At the top of my php script I have a checker to make sure a name was passed, if not redirect to folder/

The above rule is ignored, any ideas

jdMorgan

5:26 pm on Jan 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Is this the only rule in the .htaccess file? (make sure you've got mod_rewrite enabled)

Also, that apostrophe may be encoded as %27, double-encoded as %2527, or even multiply-encoded as %252527, so you might try:


RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /name\%(25)*27s
RewriteRule ^name http://www.example.com/folder/names [R=301,L]

Note that I added the base URL-path "^name" to the RewriteRule as well; Since RewriteConds are not processed unless the RewriteRule pattern matches (see mod_rewrite documentation for details), this will help reduce unnecessary RewriteCond processing in most cases.

If necessary, you could cover all encoded, multiply-encoded, and non-encoded cases with a subpattern of "(\%(25)*27¦')", replacing the broken pipe character in this pattern with a solid one as usual.

Jim

wheelie34

5:55 pm on Jan 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi Jim

Thanks for your help as always, the htaccess file has multiple

QUERY_STRING rules and mod rewrite is on

Am I still safe to proceed with your example?

Thanks again

EDIT:
Will this be safe?

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /name\%(25)*27s_word_word

As the file name is like name's_of_birds

target is names_of_birds

jdMorgan

6:07 pm on Jan 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Not sure why you're worried -- Get in there and test it!

(There's nothing says you can't "invent" a variation of that URL for testing only -- A URL that doesn't "actually exist" on your server, so that there will be no danger to your site's normal operation while you are testing. Change the patterns to "test-name" instead of just "name" for example, then test by requesting those fake "test" URLs. If it works, take out the "test" part, and then test again with the real URLs.)

If your server doesn't behave, kick it in the teeth! -- It works for you, not the other way 'round!

Jim

wheelie34

6:34 pm on Jan 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Lol Jim, ok tried and failed, I rewrite for nice URL's so I put the new rule above whats already there but I think it gets caught by my php page and goes to folder/ heres what I have

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /name\%(25)*27s_of_birds
RewriteRule ^name http://www.example.com/folder/names_of_birds [R=301,L]

# Internally rewrite search engine friendly static URL to dynamic filepath and query
RewriteRule ^([^./]+)$ /folder/filetouse.php?query=$1 [L]
#
# Externally redirect client requests for old dynamic URLs to equivalent new static URLs
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /folder/filetouse\.php\?query=([^./]+)\ HTTP/
RewriteRule ^filetouse\.php$ http://www.example.com/folder/%1? [R=301,L]

I also tried it below the above but then it tries to produce a nice address from the wrong name

Cheers

Yes I did flush the browser cache each time

jdMorgan

7:37 pm on Jan 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Your rules are not in the correct order, although that may not have anything to do with this specific problem.

I'd suggest:


RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /name\%(25)*27s_of_birds
RewriteRule ^name http://www.example.com/folder/names_of_birds [R=301,L]
#
# Externally redirect client requests for old dynamic URLs to equivalent new static URLs
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /folder/filetouse\.php\?query=([^./]+)\ HTTP/
RewriteRule ^filetouse\.php$ http://www.example.com/folder/%1? [R=301,L]
#
# Redirect non-www to www domain
RewriteCond %{HTTP_HOST} !^(www\.example\.com)?$
RewriteRule (.*) http://www.example.com/$1 [R=301,L]
#
# Internally rewrite search engine friendly static URL to dynamic filepath and query
RewriteRule ^([^./]+)$ /folder/filetouse.php?query=$1 [L]

Also, it's possible that the character is not a single-quote, but rather, one of the 'smart quotes' such as left-single-quote or right-single-quote. If that is the case, then it won't match "%27", and you'll have to find out the exact value of the character before you can "catch" it.

Note that the rules are now in order, redirects first, from most-specific to least-specific, followed by rewrites, again from most-specific to least-specific. (Most-specific means the most-specific pattern, which matches the smallest number of URLs, to least-specific, which matches a larger number of URLs. External redirects must come before internal rewrites in order to avoid 'exposing' your internally-rewritten paths to the client browsers and robots.)

Looking back at this, I notice that your second rule (in this post) contains the path "/folder" in the RewriteCond. If this second rule works as shown, then that indicates that this code might be located in the "/folder" subdirectory. If that is the case, then you may need to use "/folder" in the names-of-birds RewriteCond pattern as well. So check the URL-path of these 'bird' URLs -- The RewriteCond pattern must match the entire URL-path, while the RewriteRule pattern only needs to match the 'localized' path.

Everything depends on the patterns and on the location of this .htaccess file... All must be correct. If your second rule is working, then use it as a "model" to fix the directory-paths in the first rule, if needed.

Jim

[edited by: jdMorgan at 7:39 pm (utc) on Jan. 28, 2009]

wheelie34

8:31 pm on Jan 28, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Jim

Yes this htaccess file IS located in the folder/ directory, I already have the non www to www in the sites root htaccess, so, I added folder like this

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /folder/name\%(25)*27s_of_birds

and got the same redirect, will look into what sort of charcter the ' is.

I am not too concerned with this as its only one page out of 100s if I can't sort it easily google will have to figure it out itself

wheelie34

4:31 pm on Jan 29, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



The plot thickens, after some messing about to find how it's geeting passed to the script I found this, it gets sent as name\s and in the google results it's listed as name%27s and name%34s so I printed it to the page and got name\s I then setup a switch statement on the page, as I found another entry with an apostrophe, before the DB call to convert it to what's actually in the DB and all seems well now, it keeps the old URL in the browser and shows the correct content.

Does it sound like the best way, and, does the 'nice' rewrite actually send a \

jdMorgan

6:33 pm on Jan 29, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Whether using mod_rewrite or doing it in your script, I recommend that you 301-redirect the incorrect URL to the correct one, rather than allowing it to resolve to the same content as the correct URL. Leaving the incorrect URL in the browser address bar implies allowing duplicate-content -- The same content available at more than one absolutely-unique URL.

If Apache does anything at all to your URL, it will be limited to standard encoding of the single-quote to %27, and possibly, double-encoding of existing %27 strings to %2527 if the previously-encoded URL is rewritten or redirected (see RewriteRule [NE] flag). No other changes will be made to characters in the URL, and I cannot imagine where "\s" is coming from. It is most likely something to do with the actual URLs created by your page-generation script and presented on your HTML pages, and that bears some investigation.

Be aware that character restrictions exist at many levels: Some characters cannot be stored literally in your database, some may require special measures to be output by your script, and the HTTP protocol imposes restrictions on allowed character-sets in various parts of URLs. In all cases, the restricted character(s) must be escaped or encoded in some way in order to be considered valid in each of these contexts. (This is a main reason that outside of the characters such as slashes, periods, colons, "#" symbols, question marks, and ampersands used to delimit various 'fields', URLs are composed of letters, numbers, and hyphens only -- At least on sites where the Webmaster does not like headaches)

Although not likely applicable to your current problem, RFC2396 defines character restrictions within the various part and pieces of URLs, if you are interested in researching the subject for its own sake.

Jim

wheelie34

6:54 pm on Jan 29, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks Jim, I did considor the dupe after getting it working again, as the pages get a bit of traffic I was eager to atleast show the user the page that was in the SERPS, I've not done a 301 in php yet but think I have read it here somewhere and will be looking into it hopefully next week as it's only 2 pages with the issue, thanks again

g1smd

7:17 pm on Jan 29, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



PHP driven redirect is very easy:

HEADER ("HTTP/1.1 301 Moved Permanently");
HEADER ("Location: http://" . $_SERVER['HTTP_HOST'] . $folderandpath);
HEADER ("Connection: close");

or something very similar.

wheelie34

9:08 am on Jan 30, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks g1smd, if I set it like this is it correct

case "name\'s":
HEADER ("HTTP/1.1 301 Moved Permanently");
HEADER ("Location: http://www.example.com/folder/names");
HEADER ("Connection: close");
break;

Do I need the Connection: close? there will be 2 case switches like above

wheelie34

10:40 am on Feb 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Not sure if I should continue this thread here or start a new on in the php forum but here goes. I can't get the 301 redirect to work, the 301 header is recognised but not sure what it's passing, I have 2 variable checks, the first one

$variable = $_GET['variable'];
if (!$_GET['variable'])
{
header("Location: http://www.example.com/folder/");
exit;
}
if it's not empty I do a db call and if num_rows is not == '1' I do another redirect to folder/

When I use

if ($variable == "name\'s"){
header ("HTTP/1.1 301 moved permanently");
header ("Location: http://www.example.com/folder/names");
header ("Connection: close");
}

something IS passed as the first check doesn't catch it, the num_rows catches it! and printing the mysql query straight after the db call shows the correct page and address, however, if I take out the print line it bypasses it and redirect to folder/

I am redirecting to the same file location just trying to pass the correct variable. Any ideas

g1smd

12:48 pm on Feb 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The Live HTTP Headers extension for Firefox is invaluable for checking headers.

wheelie34

1:06 pm on Feb 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I know that and that's what I used to check, as I said it gets the correct 301 but the variable is causing a problem, if I print the $query after the db call the page and URI display correctly, if I comment out the print $query the db call comes up empty and redirects to folder/

wheelie34

2:05 pm on Feb 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



here's the live headers report key points are if I have the query print out to screen everything works if I remove it, it doesn't, I added the print query to make sure the variable is getting sent and it is.
##############
WITH $print "$query";

http://www.example.com/folder/name's
GET /folder/name's HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-gb
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: loggersession=57; loggerid=0NR3D1F3GK; loggersession=56; loggersessionlogged=yes
HTTP/1.x 301 moved permanently
Date: Mon, 02 Feb 2009 13:42:18 GMT
Server: Apache/2.0.63 (Unix) mod_ssl/2.0.63 OpenSSL/0.9.8b mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635

PHP/5.2.5
X-Powered-By: PHP/5.2.5
Location: http://www.example.com/folder/names
Connection: close

WITHOUT print "$query";

http://www.example.com/folder/name's

GET /folder/name's HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: en-gb
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: loggersession=57; loggerid=0NR3D1F3GK; loggersession=56; loggersessionlogged=yes

HTTP/1.x 301 moved permanently
Date: Mon, 02 Feb 2009 13:51:07 GMT
Server: Apache/2.0.63 (Unix) mod_ssl/2.0.63 OpenSSL/0.9.8b mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635

PHP/5.2.5
X-Powered-By: PHP/5.2.5
Location: http://www.example.com/folder/
Connection: close

Thanks for your time

jdMorgan

3:38 pm on Feb 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You might want to ask about this in the PHP forum, since it appears to be a PHP-related thing, perhaps related to server-side variable caching, or perhaps to automatic database-access optimization (for example, don't actually call the database if the variable isn't referenced later or some-such).

Jim

wheelie34

3:56 pm on Feb 2, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



thanks Jim, I was going to do that, just waited for a response here first.