1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

FAQ: mod_rewrite, 301 redirects, and optimizing Apache.

Discussion in 'Apache' started by Nintendo, Jul 30, 2005.

  1. mail4kaja

    mail4kaja Peon

    Messages:
    100
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #761
    Can you please explain, whats the use of

    RewriteBase /
    Code (markup):
    Thanks in advance..
     
    mail4kaja, Oct 2, 2007 IP
  2. Ladadadada

    Ladadadada Peon

    Messages:
    382
    Likes Received:
    36
    Best Answers:
    0
    Trophy Points:
    0
    #762
    I really don't understand how the section ([^.]+) can possibly work for anyone.

    When you see [^X] it means "NOT X". If you have [^/] it means "NOT /". The caret as the first symbol in a character class indicates negation.

    A single dot on it's own means "anything", a dot with a backslash in front means a literal dot, but without the backslash it will match anything. That's why (.*) matches the whole string.

    A plus means "one or more of the preceding character class". A star means "zero or more of the preceding character class". So (.+) means "match one or more of any character" and (.*) means "match zero or more of any character"

    Putting it all together, the section ([^.]+) means "one or more of not anything" which doesn't make any sense. I'm happy if this has worked for you but it's probably not working the way you think it is working. Maybe Apache is simply ignoring that section because it's impossible to match anything or maybe it's just ignoring the caret and using the dot on it's own. Apache is quite smart after all.

    mod_rewrite is not quite as voodoo-ish as most people think. (It IS still voodoo. Damn cool voodoo, but voodoo none the less.) Most of the confusion stems from a misunderstanding of how regular expressions work.

    I'm considering writing a definitive guide to regular expressions which (I hope) will dispel some of the confusion.
     
    Ladadadada, Oct 6, 2007 IP
  3. kingdolar

    kingdolar Well-Known Member

    Messages:
    404
    Likes Received:
    5
    Best Answers:
    0
    Trophy Points:
    133
    #763
    thanks Nintendo
     
    kingdolar, Oct 12, 2007 IP
  4. qualityhostings

    qualityhostings Well-Known Member

    Messages:
    1,764
    Likes Received:
    9
    Best Answers:
    0
    Trophy Points:
    105
    #764
    Hello

    I would like to share some informations I have collected from net.



    Regular Expression Syntax
    ^ Start of string
    $ End of string
    . Any single character
    (a|b) a or b
    (...) Group section
    [abc] Item in range (a or b or c)
    [^abc] Not in range (not a or b or c)
    a? Zero or one of a
    a* Zero or more of a
    a+ One or more of a
    a{3} Exactly 3 of a
    a{3,} 3 or more of a
    a{3,6} Between 3 and 6 of a
    !(pattern) "Not" prefix. Apply rule when URL does not match pattern
    RewriteRule FLAGS

    I'm going to go a little deeper in this list than what the cheat sheet does as I tend to need a little more of a description on what each flag does (all descriptions are lifted without remorse from Apache.org)...not just the short definition.
    R[=code] Redirect to new URL, with optional code (see below). Prefix Substitution with http://thishost[:thisport]/ (which makes the new URL a URI) to force a external redirection. If no code is given a HTTP response of 302 (MOVED TEMPORARILY) is used. If you want to use other response codes in the range 300-400 just specify them as a number or use one of the following symbolic names: temp (default), permanent, seeother. Use it for rules which should canonicalize the URL and give it back to the client, e.g., translate ``/~'' into ``/u/'' or always append a slash to /u/user, etc.

    Note: When you use this flag, make sure that the substitution field is a valid URL! If not, you are redirecting to an invalid location! And remember that this flag itself only prefixes the URL with http://thishost[:thisport]/, rewriting continues. Usually you also want to stop and do the redirection immediately. To stop the rewriting you also have to provide the 'L' flag.
    F Forbidden (sends 403 header) This forces the current URL to be forbidden, i.e., it immediately sends back a HTTP response of 403 (FORBIDDEN). Use this flag in conjunction with appropriate RewriteConds to conditionally block some URLs.
    G Gone (no longer exists) This forces the current URL to be gone, i.e., it immediately sends back a HTTP response of 410 (GONE). Use this flag to mark pages which no longer exist as gone.
    P Proxy This flag forces the substitution part to be internally forced as a proxy request and immediately (i.e., rewriting rule processing stops here) put through the proxy module. You have to make sure that the substitution string is a valid URI (e.g., typically starting with http://hostname) which can be handled by the Apache proxy module. If not you get an error from the proxy module. Use this flag to achieve a more powerful implementation of the ProxyPass directive, to map some remote stuff into the namespace of the local server.

    Notice: To use this functionality make sure you have the proxy module compiled into your Apache server program. If you don't know please check whether mod_proxy.c is part of the ``httpd -l'' output. If yes, this functionality is available to mod_rewrite. If not, then you first have to rebuild the ``httpd'' program with mod_proxy enabled.
    L Last Rule Stop the rewriting process here and don't apply any more rewriting rules. This corresponds to the Perl last command or the break command from the C language. Use this flag to prevent the currently rewritten URL from being rewritten further by following rules. For example, use it to rewrite the root-path URL ('/') to a real one, e.g., '/e/www/'.
    N Next (i.e. restart rules) Re-run the rewriting process (starting again with the first rewriting rule). Here the URL to match is again not the original URL but the URL from the last rewriting rule. This corresponds to the Perl next command or the continue command from the C language. Use this flag to restart the rewriting process, i.e., to immediately go to the top of the loop.

    But be careful not to create an infinite loop!
    C Chain This flag chains the current rule with the next rule (which itself can be chained with the following rule, etc.). This has the following effect: if a rule matches, then processing continues as usual, i.e., the flag has no effect. If the rule does not match, then all following chained rules are skipped. For instance, use it to remove the ``.www'' part inside a per-directory rule set when you let an external redirect happen (where the ``.www'' part should not to occur!).
    T=mime-type Set Mime Type Force the MIME-type of the target file to be MIME-type. For instance, this can be used to simulate the mod_alias directive ScriptAlias which internally forces all files inside the mapped directory to have a MIME type of ``application/x-httpd-cgi''.
    NS Skip if internal sub-request This flag forces the rewriting engine to skip a rewriting rule if the current request is an internal sub-request. For instance, sub-requests occur internally in Apache when mod_include tries to find out information about possible directory default files (index.xxx). On sub-requests it is not always useful and even sometimes causes a failure to if the complete set of rules are applied. Use this flag to exclude some rules.

    Use the following rule for your decision: whenever you prefix some URLs with CGI-scripts to force them to be processed by the CGI-script, the chance is high that you will run into problems (or even overhead) on sub-requests. In these cases, use this flag.
    NC Case insensitive This makes the Pattern case-insensitive, i.e., there is no difference between 'A-Z' and 'a-z' when Pattern is matched against the current URL.
    QSA Append query string This flag forces the rewriting engine to append a query string part in the substitution string to the existing one instead of replacing it. Use this when you want to add more data to the query string via a rewrite rule.
    NE Do not escape output This flag keeps mod_rewrite from applying the usual URI escaping rules to the result of a rewrite. Ordinarily, special characters (such as '%', '$', ';', and so on) will be escaped into their hexcode equivalents ('%25', '%24', and '%3B', respectively); this flag prevents this from being done. This allows percent symbols to appear in the output, as in

    RewriteRule /foo/(.*) /bar?arg=P1\%3d$1 [R,NE]

    which would turn '/foo/zed' into a safe request for '/bar?arg=P1=zed'.
    PT Pass through This flag forces the rewriting engine to set the uri field of the internal request_rec structure to the value of the filename field. This flag is just a hack to be able to post-process the output of RewriteRule directives by Alias, ScriptAlias, Redirect, etc. directives from other URI-to-filename translators. A trivial example to show the semantics: If you want to rewrite /abc to /def via the rewriting engine of mod_rewrite and then /def to /ghi with mod_alias:

    RewriteRule ^/abc(.*) /def$1 [PT]
    Alias /def /ghi

    If you omit the PT flag then mod_rewrite will do its job fine, i.e., it rewrites uri=/abc/... to filename=/def/... as a full API-compliant URI-to-filename translator should do. Then mod_alias comes and tries to do a URI-to-filename transition which will not work.

    Note: You have to use this flag if you want to intermix directives of different modules which contain URL-to-filename translators. The typical example is the use of mod_alias and mod_rewrite..
    S=x Skip next x rules This flag forces the rewriting engine to skip the next num rules in sequence when the current rule matches. Use this to make pseudo if-then-else constructs: The last rule of the then-clause becomes skip=N where N is the number of rules in the else-clause. (This is not the same as the 'chain|C' flag!)
    E=var:value Set environment variable "var" to "value" This forces an environment variable named VAR to be set to the value VAL, where VAL can contain regexp backreferences $N and %N which will be expanded. You can use this flag more than once to set more than one variable. The variables can be later dereferenced in many situations, but usually from within XSSI (via ) or CGI (e.g. $ENV{'VAR'}). Additionally you can dereference it in a following RewriteCond pattern via %{ENV:VAR}. Use this to strip but remember information from URLs.
    RewriteCond FLAGS
    NC Case insensitive
    OR Allows a rule to apply if one of a series of conditions are true.
    Redirection Header Codes
    301 Moved permanently
    302 Moved temporarily
    403 Forbidden
    404 Not found
    410 Gone
    Server Variables
    Format
    %{NAME_OF_VAR}
    HTTP Headers
    HTTP_USER_AGENT
    HTTP_REFERER
    HTTP_COOKIE
    HTTP_FORWARDED
    HTTP_HOST
    HTTP_PROXY_CONNECTION
    HTTP_ACCEPT
    Request
    REMOTE_ADDR
    REMOTE_HOST
    REMOTE_USER
    REMOTE_IDENT
    REQUEST_METHOD
    SCRIPT_FILENAME
    PATH_INFO
    QUERY_STRING
    AUTH_TYPE
    Server
    DOCUMENT_ROOT
    SERVER_ADMIN
    SERVER_NAME
    SERVER_ADDR
    SERVER_PORT
    SERVER_PROTOCOL
    SERVER_SOFTWARE
    Time
    TIME_YEAR
    TIME_MON
    TIME_DAY
    TIME_HOUR
    TIME_MIN
    TIME_SEC
    TIME_WDAY
    TIME
    Special
    API_VERSION
    THE_REQUEST
    REQUEST_URI
    REQUEST_FILENAME
    IS_SUBREQ
    Directives
    RewriteEngine
    RewriteOptions
    RewriteLog
    RewriteLogLevel
    RewriteLock
    RewriteMap
    RewriteBase
    RewriteCond
    RewriteRule
    Example Rules
    PLAIN TEXT
    CODE:

    1.
    # Site has permanently moved to new domain
    2.
    # domain.com to domain2.com
    3.
    RewriteCond %{HTTP_HOST} ^www.domain.com$ [NC]
    4.
    RewriteRule ^(.*)$ http://www.domain2.com/$1 [R=301,L]

    PLAIN TEXT
    CODE:

    1.
    # Page has moved temporarily
    2.
    # domain.com/page.html to domain.com/new_page.html
    3.
    RewriteRule ^page.html$ new_page.html [R,NC,L]

    PLAIN TEXT
    CODE:

    1.
    # Nice looking URLs (no query string)
    2.
    # domain.com/category-name-1/ to domain.com/categories.php?name=category-name-1
    3.
    RewriteRule ^([A-Za-z0-9-]+)/?$ categories.php?name=$1 [L]

    PLAIN TEXT
    CODE:

    1.
    # Nice looking URLs (no query string) with pagination
    2.
    # domain.com/articles/title/5 to domain.com/article.php?name=title&page=5
    3.
    RewriteRule ^articles/([A-Za-z0-9-]+)/([0-9]+)/?$ article.php?name=$1&page=$2 [L]

    PLAIN TEXT
    CODE:

    1.
    # Block referrer spam
    2.
    RewriteCond %{HTTP_REFERRER} (weight) [NC,OR]
    3.
    RewriteCond %{HTTP_REFERRER} (drugs) [NC]
    4.
    RewriteRule .* - [F]
     
    qualityhostings, Oct 22, 2007 IP
  5. qualityhostings

    qualityhostings Well-Known Member

    Messages:
    1,764
    Likes Received:
    9
    Best Answers:
    0
    Trophy Points:
    105
    #765
    qualityhostings, Oct 22, 2007 IP
  6. mgrohan

    mgrohan Active Member

    Messages:
    671
    Likes Received:
    18
    Best Answers:
    0
    Trophy Points:
    58
    #766
    Trying to rewrite home page to the below page.

    Problem is after rewriting the % are converted to %25. Is there anyway to make this type of rewrite work:

    RewriteRule ^/?$ http://mysite.com/search少妇 [R=301,L]

    Appreciate any help. Thx :)
     
    mgrohan, Oct 25, 2007 IP
  7. paulseeker

    paulseeker Peon

    Messages:
    2
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #767
    Hi there,

    Please help me to solve this problem. Thanks.

    This is my testing...

    In main.php:
    <html>
    <head><title></title></head>
    <body>
    <? include("new.php") ?>
    <? include("detail.php") ?>
    </body>
    </html>


    In new.php:
    <?
    echo "<a href=\"test/artist/paul\">Paul</a><br>";
    echo "<a href=\"test/teacher/kurt\">Kurt</a><br>";
    echo "<a href=\"test/racer/mike\">Mike</a><br>";
    ?>


    In detail.php:
    <?
    if(a == "artist"){
    if(b == "paul"){ echo "Yes, Paul."; }
    else if(b == "kurt"){ echo "Yes, Kurt."; }
    else if(b == "mike"){ echo "Yes, Mike."; }
    else{ echo "Nobody here."; }
    }
    else{ echo "Not artist."; }
    ?>


    In .htaccess:
    Options +FollowSymLinks
    RewriteEngine on
    RewriteRule ^test/(.[^\/]*)/(.[^\/]*)$ main.php?a=$1&b=$2 [L]


    Now, my problem is:

    I hover to any links of the new.php, the links are shown in correct way:
    e.g. Link of Paul shown in status bar is:
    http://www.my_site.com/test/artist/paul
    e.g. Link of Kurt shown in status bar is:
    http://www.my_site.com/test/teacher/kurt
    e.g. Link of Mike shown in status bar is:
    http://www.my_site.com/test/racer/mike

    After I click on the link:
    e.g. http://www.my_site.com/band/artist/paul
    And the output is correct:
    Yes, Paul.

    And I hover to the links in new.php again, the links are shown in INCORRECT way:
    e.g. Link of Paul shown in status bar is:
    http://www.my_site.com/test/artist/test/artist/paul
    e.g. Link of Kurt shown in status bar is:
    http://www.my_site.com/test/artist/test/teacher/kurt
    e.g. Link of Mike shown in status bar is:
    http://www.my_site.com/test/artist/test/racer/mike

    I can't solve this problem and I hope you will tell me what is the mistake. Thanks you.
     
    paulseeker, Nov 2, 2007 IP
  8. Nintendo

    Nintendo ♬ King of da Wackos ♬

    Messages:
    12,890
    Likes Received:
    1,064
    Best Answers:
    0
    Trophy Points:
    430
    #768
    <a href=\"test/artist/paul\">Paul</a><br>
    to
    <a href=\"/test/artist/paul\">Paul</a><br>
    or
    <a href=\"http//3w.domain.com/test/artist/paul\">Paul</a><br>

    it has to be as if the mod_rewrite URLs are the real URLs. The browser has no idea they are fake URLs.
     
    Nintendo, Nov 2, 2007 IP
  9. paulseeker

    paulseeker Peon

    Messages:
    2
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #769
    Thanks a lot, it Work!!!
     
    paulseeker, Nov 2, 2007 IP
  10. mariush

    mariush Peon

    Messages:
    562
    Likes Received:
    44
    Best Answers:
    0
    Trophy Points:
    0
    #770
    I am using the following rule to convert

    /game.php?category=pc&item=2 to /pc/2/game-title.html

    The rule is :


    Rewriterule ^(.*)/([0-9]+)/(.*).html game.php?category=$1&item=$2 [L]

    It works great most of the time, meaning there are certain URL's which have problems, for example this one: /pc/6232/D%2FGeneration.html

    The server says the page was not found on the server.

    Could you advice me in what needs to be changed in the .htaccess file ?

    Later edit: I realize now that %2F is "/" and then the rule may not be correct, but the question still remains, can I make the rule in such a way that it would allow the / character in that title ?

    I have fixed the pages by replacing the "/" with "_" and doing a permanent redirect to those pages but I'd still like to find out if some solution exists for this.
     
    mariush, Nov 3, 2007 IP
  11. tru504187211

    tru504187211 Peon

    Messages:
    287
    Likes Received:
    15
    Best Answers:
    0
    Trophy Points:
    0
    #771
    tru504187211, Nov 8, 2007 IP
  12. krt

    krt Well-Known Member

    Messages:
    829
    Likes Received:
    38
    Best Answers:
    0
    Trophy Points:
    120
    #772
    RewriteBase /

    RewriteCond %{QUERY_STRING} ^cat=([0-9]+)$
    RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$
    RewriteRule ^viewall\.php$ http://subdomain%1.domain.com/viewall.php [R=301,L]

    RewriteCond %{QUERY_STRING} ^$
    RewriteCond %{HTTP_HOST} ^subdomain([0-9]+)\.domain\.com$
    RewriteRule ^viewall.php$ viewall.php?cat=%1 [L]

    The first rule redirects the request to the optimised URL, the second is an internal rewrite to make it compatible with the script.
     
    krt, Nov 10, 2007 IP
  13. Ezo

    Ezo Well-Known Member

    Messages:
    262
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    105
    #773
    Ezo, Nov 13, 2007 IP
  14. nshahidch

    nshahidch Peon

    Messages:
    117
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #774
    Dear how can we configure wamp or phptriad for mod_write at localhost.
    I have both of them Installed but they didn’t works…

    Can you tell me how can we configure it…
     
    nshahidch, Nov 13, 2007 IP
  15. mail4kaja

    mail4kaja Peon

    Messages:
    100
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #775
    I need to redirect

    http://anything.domain.com/path/to/content
    
    to
    
    http://www.domain.com/content-type/anything/path/to/content
    Code (markup):
    I have WildCard enabled in both my DNS Server and Apache Configuration. Please tell me the mod_rewrite stuff to do this.
     
    mail4kaja, Nov 14, 2007 IP
  16. pawoodster

    pawoodster Peon

    Messages:
    3
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #776
    Hi:

    I'm currently moving a blog from its current home - a proprietary php cms to wordpress - and I'd like to do a 301 redirect from each of the old urls to the new ones in Wordpress.

    I've tried reading one or two articles, but I'm not really getting anywhere. Any help would be very much appreciated.
     
    pawoodster, Nov 15, 2007 IP
  17. Nintendo

    Nintendo ♬ King of da Wackos ♬

    Messages:
    12,890
    Likes Received:
    1,064
    Best Answers:
    0
    Trophy Points:
    430
    #777
    Options +FollowSymLinks +Indexes
    RewriteEngine on
    RewriteBase /
    RewriteRule ^wordpress-directory/([^.]+)_([^.]+)\.html$ folder/read-blog.php?article_id=$1&title=$2 [L]

    Though odds are, you won't get it to work, since it's WordPress.
     
    Nintendo, Nov 15, 2007 IP
  18. pawoodster

    pawoodster Peon

    Messages:
    3
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #778
    Thanks for the swift response.

    You're right, it doesn't appear to be working.

    It's a shame it isn't WP to WP as that's a doddle. What would be the cutest way to do what I'm looking to do so I can explain it to our developer?

    Thanks.
     
    pawoodster, Nov 15, 2007 IP
  19. nshahidch

    nshahidch Peon

    Messages:
    117
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #779
    All this is for apache and PHP...
    Is all this is same for tomcat and JSP too...
    If yess then how can we configure tomcat for mod_rewrite....

    Thanks
     
    nshahidch, Nov 20, 2007 IP
  20. Ladadadada

    Ladadadada Peon

    Messages:
    382
    Likes Received:
    36
    Best Answers:
    0
    Trophy Points:
    0
    #780
    @ pawoodster:

    The ugliest way to do this would be to put a single rewrite rule for each of the old URLs manually mapping to the new URLs in one monolithic .htaccess file.

    The cutest way would be to have a single rewrite rule that seamlessly mapped them all using a simple regular expression even your boss could understand. Unfortunately I don't think anything that cute is possible.

    The most pragmatic way is to write a rule that will catch all of the old-style URLs and silently map them to a PHP file which will do a lookup in the database and match the old URL to the equivalent new URL and then send an HTTP header telling them where to go.
     
    Ladadadada, Nov 22, 2007 IP