Forum Moderators: phranque

Message Too Old, No Replies

help escaping a question mark if it is first

         

scottexpo

1:36 am on Sep 9, 2010 (gmt 0)

10+ Year Member



My head is spinning, someone please help me...I have been trying for hours to redirect urls containing a question mark as a directory (the first directory). I have seen tons of examples on how to bypass the question mark but only in the middle of an expression and not when it happens to be first. Here is what I am trying to accomplish:

I need to redirect (or rewrite) these urls:
domainName/?/channels/anything

to this path:
domainName/channels/action/view/channel/anything

I tried this with no luck:
RewriteRule ^/?/channels/([^/]+) /channels/action/view/channel/$1 [NC,L]

I know now I need RewriteCond to get rid of the question mark, but how when it is first?

Thanks in advance,
-Scott

jdMorgan

11:02 am on Sep 9, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Clarification of terms to simplify discussion: Your URLs do not *contain* a question mark or query string. Rather, a question mark and query string are *appended* to your URLs. URLs and query strings, along with the "?" token that demarcates the query string, are three separate things.

RewriteRule in a .htaccess or <Directory> context tests only the local URL-path -- that is, the URL with the protocol, hostname, FQDN indicator, port number, and path to the current .htaccess file's directory removed.

So this is why your rule won't work.

In order to detect the question mark that marks the beginning of a query-string, you have to use the mod_rewrite variable %{THE_REQUEST}, which contains the entire HTTP request line sent by the client -- the same string that appears in quotes in each of your raw server access log file entries. It starts with the HTTP method (e.g. GET, HEAD, or POST) and ends with the requested protocol version (e.g. HTTP/1.1).

Further, if you want an external client redirect, then a full protocol, hostname, and URL-path should be specified:
In example.com/.htaccess:

RewriteCond %{THE_REQUEST} ^[A-Z]+\ /\?/channels/([^/#\ ]+)(#[^\ ]*)?\ HTTP/ [NC]
RewriteRule ^$ http://www.example.com/channels/action/view/channel/%1? [R=301,L]

The second question mark (unescaped) in the RewriteCond is not a literal. It is a regular-expressions quantifier acting on the preceding parenthesized sub-expression. This subexpression is present in case a URL-fragment (an HTML "named anchor" or an AJAX parameter) is appended to the query string -- intentionally, accidentally, or maliciously.

The negative-match subpatterns are used for efficiency; We tell the matching engine what characters to stop on, in order to avoid it matching all the way to the end of the HTTP protocol version and then having to iteratively "back-off" one character at a time to get a match.

The question mark appended to the RewriteRule substitution is not a literal. It functions as an operator which clears (i.e. effectively "removes") the current query string by replacing it with a blank one. This question mark will not appear in the output URL unless a new query string is also specified after it.

Jim

scottexpo

10:47 pm on Sep 10, 2010 (gmt 0)

10+ Year Member



Thank you for your reply but it didn't seem to change anything. Every url "domainName/?/channels/anything" gets redirected to the root index page it's like it treats it as domainName/ because the question mark is telling it to stop right there.

Here is my file (i used your example):
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteOptions MaxRedirects=1
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{THE_REQUEST} ^[A-Z]+\ /\?/channels/([^/#\ ]+)(#[^\ ]*)?\ HTTP/ [NC]
RewriteRule ^$ /channels/action/view/channel/%1? [R=301,L]
RewriteRule ^([a-zA-Z0-9_-]+)/$ /index.php/channels/action/view/channel/$1 [L]
RewriteRule ^([a-zA-Z0-9_-]+)$ /index.php/channels/action/view/channel/$1 [L]
</IfModule>

The second 2 RewriteRules are for something else but I commented them out to see if they were causing the problem and it still did the same thing...redirected to the root index page.

here is a few of my exact urls I am trying to redirect:
ht*tp://blineapps.com/?/channels/asu
ht*tp://blineapps.com/?/channels/niu
ht*tp://blineapps.com/?/channels/cal
ht*tp://blineapps.com/?/channels/ecu

all get redirected to the root index page but need to be redirected to:
ht*tp://blineapps.com/index.php/channels/action/view/channel/asu
ht*tp://blineapps.com/index.php/channels/action/view/channel/niu
ht*tp://blineapps.com/index.php/channels/action/view/channel/cal
ht*tp://blineapps.com/index.php/channels/action/view/channel/ecu

-Scott

[edited by: scottexpo at 10:51 pm (utc) on Sep 10, 2010]

scottexpo

10:50 pm on Sep 10, 2010 (gmt 0)

10+ Year Member



I even tried to make the actual structure of the link to be redirected, ie: ? folder, channels folder, all channels folders. Then I thought I would put the redirect files in the actual folders but it still just goes to the root index page...

-Scott

scottexpo

1:21 am on Sep 11, 2010 (gmt 0)

10+ Year Member



I solved the problem...had to do it without .htaccess and in the index.php itself. The problem with this url, ht*tp://blineapps.com/?/channels/asu, is that the index page sees this as index.php?/channels/asu so here is my fix...
// check for redirect to client channel page first and redirect if found
if (count($_GET) > 0) {
//echo 'count is greater than 0 and = '.count($_GET);
foreach ($_GET as $key => $value){
//echo "<font color='#444444'>".$key." - </font>";
//echo "<font color='#444444'>".gettype($key)."</font>";
//echo "<font color='#444444'>".strpbrk($key, '/channels/')."</font>";
if(preg_match('/channels/', $key)) {
//echo "<font color='#444444'>".strrchr($key, '/')."</font>";
$channel = strrchr($key, '/');
header("Location: /index.php/channels/action/view/channel$channel") ;
//header("Location: $channel") ;
}
else {
//echo "<font color='#444444'>do not redirect</font>";
}
}
}