Forum Moderators: phranque

Message Too Old, No Replies

How to escape slash (/)

         

daily

3:41 pm on Oct 13, 2005 (gmt 0)

10+ Year Member



Hi I've been trying to get this work for a while now. I would like to redirect every request with following conditions:
- not file or directory
- includes only alphanumeric character and slashes

to index.php?query=$1

So far I have used this:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME}!-d
RewriteCond %{REQUEST_FILENAME}!-f
RewriteRule ^(.*)$ index.php?query=$1

But this allows all characters. So how to escape slash (/) properly? When only needs to allow alphanumeric characters and slash. I have tried to use this:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME}!-d
RewriteCond %{REQUEST_FILENAME}!-f
RewriteRule ^([a-zA-Z0-9/])$ index.php?query=$1

But since slash isn't escaped properly it runs internal server error.

I use php to parse the query string and thats why I only need to allow the alphanumeric characters and slash and nothing else. So address like www.domain.com/directory/subdirectory/page/ would send a query string to php directory/subdirectory/page/.

jdMorgan

4:14 pm on Oct 13, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



daily,

Welcome to WebmasterWorld!

It should not be necessary to escape a forward slash. However, you could try something like this:


RewriteRule ^([a-z0-9\/]+)$ index.php?query=$1 [NC,L]

Your pattern as it was written would only accept a single character. "+" here means "one or more of any of the preceding grouped characters."

If you are getting a server error, then examine your server error log to find out why.

Jim

daily

7:36 pm on Oct 13, 2005 (gmt 0)

10+ Year Member



"It should not be necessary to escape a forward slash. However, you could try something like this: "

I thought so too, but i guess it needs to be escaped anyway.

"Your pattern as it was written would only accept a single character."

Yeah, noticed that too... and fixed it.

Now it works like this: (and it also accepts -)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME}!-d
RewriteCond %{REQUEST_FILENAME}!-f
RewriteRule ^([-a-zA-Z0-9\/]+)$ index.php?q=$1

One question about the RewriteCond. Why is that if i add RewriteCond %{REQUEST_FILENAME}!-d [OR] it doesn't work anymore? Or it works but ignores directories?

jdMorgan

7:41 pm on Oct 13, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



You might want to investigate two points:

1) What does the [NC] flag on RewriteRule [httpd.apache.org] do?
2) What does "RewriteCond [httpd.apache.org] %{REQUEST_FILENAME} !-d" mean?

The answers are in the mod_rewrite documentation.

Jim

daily

8:41 pm on Oct 13, 2005 (gmt 0)

10+ Year Member



You might want to investigate two points:

1) What does the [NC] flag on RewriteRule do?
2) What does "RewriteCond %{REQUEST_FILENAME}!-d

And I did that, before entering anything here. Maybe I understood that wrong but for my opion this:

RewriteCond %{REQUEST_FILENAME}!-d
RewriteCond %{REQUEST_FILENAME}!-f
RewriteRule ^([-a-zA-Z0-9\/]+)$ index.php?q=$1

means:
-if not directory then
-if not file then
-if match any alphanumeric character or /, - then

and this:
RewriteCond %{REQUEST_FILENAME}!-d [OR]
RewriteCond %{REQUEST_FILENAME}!-f
RewriteRule ^([-a-zA-Z0-9\/]+)$ index.php?q=$1

means:
- if not directory or file then
- if match any alphanumeric character or /, - then

And I got it all from the same site you mentioned. As it follows:

Notice: All of these tests can also be prefixed by an exclamation mark ('!') to negate their meaning.

'ornext¦OR' (or next condition)
Use this to combine rule conditions with a local OR instead of the implicit AND. Typical example:

RewriteCond %{REMOTE_HOST} ^host1.* [OR]
RewriteCond %{REMOTE_HOST} ^host2.* [OR]
RewriteCond %{REMOTE_HOST} ^host3.*
RewriteRule ...some special stuff for any of these hosts...
Without this flag you would have to write the cond/rule three times.

jdMorgan

9:22 pm on Oct 13, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ah, then your question relates to combinatorial logic, specifically, DeMorgan's Theorem:
and this:
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([-a-zA-Z0-9\/]+)$ index.php?q=$1

means:
- if not directory or file then
- if match any alphanumeric character or /, - then

No, it means if ( (NOT directory) OR (NOT file) ), that is, true if the requested filename is either not a file OR not a directory. This will always evaluate to true, since a resource cannot be both a file and a directory at the same time.

Therefore, your rule will always be applied as long as the pattern-match requirement of the RewriteRule is met.

The unary inversion operator "!" has higher precedence than the RewriteCond-level [OR] operator.

Using the [NC] flag with a pattern of [a-z0-9] will make your rule do a case-insensitive compare, and is faster than using [A-Za-z0-9] pattern, since it eliminates one of three bounded range checks.

Jim

daily

10:17 pm on Oct 13, 2005 (gmt 0)

10+ Year Member



Thanks!

You get a bit narrow sighted after spending too many hours with one problem off course (not directory or not file) is always true. What I was after is AND wich is implicit (as it clearly states in the docs). =)