SitePoint Sponsor

User Tag List

Results 1 to 14 of 14

Thread: Mod rewrite

  1. #1
    SitePoint Member
    Join Date
    Jul 2003
    Location
    Germany
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Mod rewrite

    Hi!

    First let me tell you that I do not understand the regex syntax of mod rewrite. In some docs, e.g. at Apache.org, they use escape (\) while obviously in many instances it is not needed, for example

    RewriteRule ^tutorials/(.*)/(.*).php /tutorials.php?req=tutorial&tut_id=$1&page=$2

    contains directory slashes which are not escaped, and the dot in ".php" is not escaped either. Is this really an inconsistency, or have I missed something? I read some regex intros for beginners, but they all tell the story in the same way.

    If you are interested in what my actual goal is: I have inbound links like this:
    http://grassomusic.de/frameset.htm?article.htm

    I want to translate that into article.htm

    Seems easy, but for me it is not.

    Uli

  2. #2
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Moved to a more appropriate forum .
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  3. #3
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,
    one step at a time :-)

    #1
    >> RewriteRule ^tutorials/(.*)/(.*).php /tutorials.php?req=tutorial&tut_id=$1&page=$2

    >> contains directory slashes which are not escaped,
    They *don't have* to

    >> and the dot in ".php" is not escaped either.
    It *has* to

    >> Is this really an inconsistency, or have I missed something?
    Yes they are not formally correct, they will work but they will work even for URIs that you don't want to handle:

    #1 Will work for:
    tutorials/name/file.php
    that's fine

    but will work for:

    tutorials/name/fileAphp
    ( because if the dot is not escaped means ``every character'' )

    tutorials/very/long/path/to.php/another_path/to
    tutorials/name/file.phpetc
    ( because the $ was not used, $ means ``end of string'' while ^ means ``begin of string'' )

    tutorials/very/long/path/to.php
    (because .* means ``all characters even slashes'' )

    tutorials//Aphp
    ( because .* allow an empty string )

    tutorials//.php
    ( because .* allow an empty string )

    and that's not fine

    My suggestion for what wrote into #1 is this:
    RewriteRule ^tutorials/([^/]+)/([^/.]+)\.php$ /tutorials.php?req=tutorial&tut_id=$1&page=$2 [L]

    it will only work for:
    tutorials/all_except_slash/all_except_dot_and_slash.php

    because:

    ([^/]+) means:
    all characters except the slash,
    the + indicates that it's an obbligatory field ( ie at least one character )

    ([^/.]+) means:
    all characters except the slash and the dot


    Thanks,
    Andrea
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  4. #4
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> if you are interested in what my actual goal is: I have inbound links
    >> like this:
    >> http://grassomusic.de/frameset.htm?article.htm
    >>
    >> I want to translate that into article.htm

    I see, my suggestion is:

    RewriteEngine On
    # The query string is composed by the <name of the file>.htm
    RewriteCond %{QUERY_STRING} ^([a-zA-Z]+)\.htm$ [NC]
    # Redirect *internally* frameset.htm to <name of the file>.htm
    # ? Means that the query string is not passed
    RewriteRule ^frameset\.htm$ /%1.htm? [L]

    Rules can be more or less restrictive allowing different extensions etc


    Thanks,
    Andrea
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  5. #5
    SitePoint Member
    Join Date
    Jul 2003
    Location
    Germany
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks you, that works. But when I add paths

    RewriteCond %{QUERY_STRING} ^([a-zA-Z]+)\.htm$ [NC]
    RewriteRule ^deutsch/frameset\.htm$ /deutsch/%1.htm?
    RewriteRule ^english/frameset\.htm$ /english/%1.htm?
    RewriteRule ^polideu/frameset\.htm$ /polideu/%1.htm?
    RewriteRule ^polieng/frameset\.htm$ /polieng/%1.htm?

    it gives me 403 errors.

  6. #6
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> RewriteCond %{QUERY_STRING} ^([a-zA-Z]+)\.htm$ [NC]
    >> RewriteRule ^deutsch/frameset\.htm$ /deutsch/%1.htm?
    >> RewriteRule ^english/frameset\.htm$ /english/%1.htm?
    >> RewriteRule ^polideu/frameset\.htm$ /polideu/%1.htm?
    >> RewriteRule ^polieng/frameset\.htm$ /polieng/%1.htm?
    The RewriteCond will work only for the RewriteRule I marked in bold.

    So you need:

    RewriteEngine On
    RewriteCond %{QUERY_STRING} ^([a-zA-Z]+)\.htm$ [NC]
    RewriteRule ^(polieng|polideu|english|deutsch)/frameset\.htm$ /$1/%1.htm? [L]
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  7. #7
    SitePoint Member
    Join Date
    Jul 2003
    Location
    Germany
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks a thousand times, Pippo!

    But I wonder why it is ^(polieng|polideu|english|deutsch)/frameset\.htm$ /$1/%1?

    instead of

    ^/(polieng|polideu|english|deutsch)/frameset\.htm$ /$1/%1?

    This regex stuff is a pain in the ***, although you seem to have mastered it. Anyway. Now I tried to limit the redirection process to acesses from some external websites:

    RewriteCond %{QUERY_STRING} ^.+$ [NC]
    RewriteCond %{HTTP_REFERER} ^.+decware.+$ [OR,NC]
    RewriteCond %{HTTP_REFERER} ^.+swissquote.+$ [NC]
    RewriteRule ^(polieng|polideu|english|deutsch)/test2\.htm$ /$1/%1? [L,R=301]

    Unfortunatly the redirection still works for internal links. What do I do wrong? Maybe you can answer a last time, Great Pippo!

  8. #8
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> But I wonder why it is
    >> ^(polieng|polideu|english|deutsch)/frameset\.htm$ /$1/%1?
    >> instead of
    >> ^/(polieng|polideu|english|deutsch)/frameset\.htm$ /$1/%1?
    For per-directory contexts], Directory block inside httpd.conf or .htaccess, the Request_Uri is always stripped.
    It means that for a request for example.net/pippo.htm the Request_Uri enviroment variable is /pippo.htm *but* using RewriteRule the previously mentioned per-directory contexts must be considered.

    Examples please...:-)

    Request: example.net/pippo.htm
    REQUEST_URI is /pippo.htm
    *but* to check it with RewriteRule you will have:

    httpd.conf
    PHP Code:
    <VirtualHost...
    ....
    # No per-directory context so [i]slash[/i] must be added
    RewriteRule ^/pippo\.htm$ /etc
    ...

    <
    Directory...
    ...
    # per-directory context so [i]slash[/i] must not be used
    RewriteRule ^pippo\.htm$ /etc 
    /.htaccess
    PHP Code:
    # per-directory context so [i]slash[/i] must not be used
    RewriteRule ^pippo\.htm$ /etc 
    >> This regex stuff is a pain in the ***
    Aye, you are right.

    Thanks,
    Andrea
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  9. #9
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> Anyway. Now I tried to limit the redirection process to acesses
    >> from some external websites:

    >>RewriteCond %{QUERY_STRING} ^.+$ [NC]
    >>RewriteCond %{HTTP_REFERER} ^.+decware.+$ [OR,NC]
    >>RewriteCond %{HTTP_REFERER} ^.+swissquote.+$ [NC]
    >>RewriteRule ^(polieng|polideu|english|deutsch)/test2\.htm$ /$1/%1? [L,R=301]
    >>Unfortunatly the redirection still works for internal links.
    >> What do I do wrong?
    First of all %1 is referring to a previous atom ( something enclosed with parenthesis ), you didn't specify any atom with your RewriteCond so %1 is empty

    Try this:
    PHP Code:
    RewriteEngine On

    RewriteCond 
    %{HTTP_REFERER} ^.+decware.+$ [NC,OR]
    RewriteCond %{HTTP_REFERER} ^.+swissquote.+$ [NC]
    RewriteCond %{QUERY_STRING} ^(.+)$
    RewriteRule ^(polieng|polideu|english|deutsch)/test2\.htm$ /$1/%1? [L,R=301
    Important note:
    RewriteCond %{QUERY_STRING} must be the last RewriteCond.

    >> Maybe you can answer a last time,
    No problem, mod_rewrite is not so easy to learn..I learn something new each time me too :-)...the important thing is that you understand how it worksor at least 95% ;-)

    A good reference to learn some regular expression is this:
    http://netbsd.gw.com/cgi-bin/man-cgi...NetBSD-current


    Thanks,
    Andrea
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  10. #10
    SitePoint Member
    Join Date
    Jul 2003
    Location
    Germany
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello Pippo!

    Now I have

    RewriteCond %{HTTP_REFERER} ^.+libanon.+$ [NC]
    RewriteCond %{QUERY_STRING} ^(http://.+])$ [NC]
    RewriteRule ^(polieng|polideu|english|deutsch)/test2\.htm$ /%1? [L,R=301]

    which is supposed to cover for example http:/restaurant-libanon.de/test.htm linking to http://grassomusic.de/english/test2....glish/test.htm
    But it does not work, it still loads test2.htm.

    The second ruleset is

    RewriteCond %{HTTP_REFERER} ^.+libanon.+$ [NC]
    RewriteCond %{QUERY_STRING} ^[a-zA-Z\.]$ [NC]
    RewriteRule ^(polieng|polideu|english|deutsch

    which should cover external links to http://grassomusic.de/english/test2.htm?test.htm
    This basically works but does not care for referers, for example http://grassomusic.de/test.htm versus
    restaurant-libanon.de/test.htm

    Uli

  11. #11
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    First ruleset must be:

    RewriteCond %{HTTP_REFERER} ^.+libanon.+$ [NC]
    RewriteCond %{QUERY_STRING} ^(http://.+])$ [NC]
    RewriteRule ^(polieng|polideu|english|deutsch)/test2\.htm$ %1? [L,R=301]

    I removed the slash before %1.

    When working with the R flag mod_rewrite can do two things:
    a)
    RewriteRule pattern /redirection [R]
    So it finds a / so he will redirect to http://<servername>/redirection
    Basically it will complete the FQDN adding the servername

    b)
    RewriteRule pattern http://<servername>/redirection [R]
    So it finds that the FQDN is already specified so it won't add the domain name

    In our rules we used %1 that contain the content of the query string that is a FQDN :-)

    >> The second ruleset is
    >>RewriteCond %{HTTP_REFERER} ^.+libanon.+$ [NC]
    >>RewriteCond %{QUERY_STRING} ^[a-zA-Z\.]$ [NC]
    >>RewriteRule ^(polieng|polideu|english|deutsch

    These should do what you requested:

    RewriteCond %{HTTP_REFERER} ^.+libanon.+$ [NC]
    RewriteCond %{QUERY_STRING} ^([a-zA-Z\.]+)$
    RewriteRule ^(polieng|polideu|english|deutsch)/test2\.htm$ /%1? [L,R=301]


    Thanks,
    Andrea
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  12. #12
    SitePoint Member
    Join Date
    Jul 2003
    Location
    Germany
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry if I bug you, Pippo.

    The redirect does not care for referers. When I leave out the query string condition, for example I write

    RewriteCond %{HTTP_REFERER} !^(http://grassomusic.de/.*)$ [NC]
    RewriteRule ^(polieng|polideu|english|deutsch)/test2\.htm$ /? [L,R=301]

    it does care for the referer. So it seems that the rewrite rule cannot handle two rewrite conditions at the same time. My site is run by Apache/1.3.27 on a Linux machine at a webhoster. Maybe I should ask the webhoster about it.

    By the way, I found out that browser caching is incredibly buggy. Mozilla and Opera do not check correctly if the page has been updated or not. Opera is usable for testing redirects only when all caching is disabled. On Mozilla one must edit all browser.cache.* variables in the about:config list.

    Uli

  13. #13
    FreeBSD The Power to Serve silver trophy pippo's Avatar
    Join Date
    Jul 2001
    Location
    Italy
    Posts
    4,514
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Uli,
    I'm getting lost...I'm not following you.

    Could you elaborate what you said at #12 ?


    Thanks,
    Andrea

    p.s.
    I found Konqueror good for the cache, even if I don't like it to browse.
    Mr Andrea
    Former Hosting Team Advisor
    Former Advisor of '03

  14. #14
    SitePoint Member
    Join Date
    Jul 2003
    Location
    Germany
    Posts
    6
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hello Andrea!

    See for example http://bugzilla.mozilla.org/show_bug.cgi?id=47401

    "I want to throw in another issue: Shouldn´t the client for every display of a certain page ask the server if there is an updated version of the document, in other words retrieve the HTTP header? One should also have a look at what RFC documents say about the expires: variable.

    Furthermore I experienced a problem when a server-side redirect (301 or 302) is established inbetween two clicks on the same link; Mozilla will not reflect the changes.

    The fact that Mozilla provides four alternatives for cache behaviour in a rough EXOR ("radio button") manner makes clear that there is still much to do."

    You know, Mozilla does not retrieve the HTTP header and hence does not see when changes have been made to server-sided redirection. The only way to make Mozilla retrieve the HTTP header is to diable cacheing altogether.

    Uli


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •