黑族論壇

黑族論壇

黑族論壇目錄 / 程式設計 / 網頁/網站程式 / PHP /

Apache mod_rewrite RewriteRule Flags

發表新主題
隨機主題
上個主題
下個主題
|
Apache mod_rewrite RewriteRule Flags

In standard regular expression syntax, there are a number of flags that can be added to the end of a regex pattern. In mod_rewrite, some of these standard regular expression flags, as well as some others more specific to URL handling, may appear at the end ofthe rule in square brackets in order to modify the behavior of a rewrite rule:

RewriteRule monkey http://monkeys.com/ [R,L]

When no flag is provided, a default behavior will be used, depending on the nature of the arguments provided. It is my recommendation that you always use an explicit rewrite flag, so that there is never any chance of confusion, either for you or for the mod_rewrite engine.

In this section, the flags are introduced in alphabetical order, rather in any kind of logical order. So, you may want to read through the list quickly once, and then go through it again in more detail the second time, so that you know what other flags are available.

Flags can be used in either their verbose form, or in their one- or two- (and, in one case three-) letter abbreviations. It is much more common to use the abbreviation, but using the more verbose form will tend to make your rules more readable. I'll tend to use the abbreviated notation, since that is the notation that you’ll encounter more often "in the wild."

Chain: C

The [chain], or [C], flag indicates that a series of rules are chained together into a single logical unit. This construct is most commonly used when a transformation is sufficiently complex that it makes sense to break it into several smaller transformations.

If a given rule succeeds, then the next rule is run as well. However, if a given rule fails, then all following rules within that chain are skipped.

Cookie: CO

Using the [cookie], or [CO], flag allows you to set a cookie as part of a rewriting transaction. You must specify three values: the name, value, and domain of the cookie. You may additionally set the duration and path of the cookie:

'cookie|CO=Name:Value:Domain[:Lifetime[:Path]]'

For example, consider the following rewrite rule:

RewriteRule ^/index.html - [CO=frontdoor:yes:.example.com]

This example will set a cookie called frontdoor with a value of yes when someone visits the URL /index.html on our server. This may be used to verify that someone came in through the "front door," rather than via another link.

Note: Remember that the - value for the substitution means that the requested URL should not be modified.

The Lifetime argument indicates, in minutes, how long the cookie should be retained. If this value is not set, or if it is set to 0, the cookie will be a session cookie. Which is to say, it will last only for the lifetime of the browser session, and then it will be discarded.

The Path argument, by default, is set to /, meaning that the cookie will be valid for the entire site. Setting this value to something else can cause a cookie to be restricted to a smaller portion of the website.

Thus, a more complete example, containing all of the available variables, might look like the following:

RewriteRule ^/index.html - [cookie=frontdoor:yes:.example.com:10080:/]

This example will set a cookie lasting for one week (10,080 minutes is one week), and valid for any host in the .example.com domain.

As mentioned earlier, things are slightly different when operating out of an .htaccess file. Supposing the preceding rule was placed in an .htaccess file within the document directory containing the index.html file, you would need to modify it slightly, as follows:

RewriteRule ^index.html - [CO=frontdoor:yes:.example.com:10080:/]

In this case, I've used the short form (CO) rather than the long form (cookie). You should use whichever one makes the most sense to you.

Env: E

The [env], or [E], flag allows you to set the value of any environment variable. This environment variable will then be available in a variety of contexts, so that it can be used in PHP code, or CGI programs, or in various configuration directives within the Apache configuration.

It is generally most useful to create your own environment variables, since using one that is already in use tends to be unreliable. In particular, the variable may be assigned its value after your rewrite rules run, undoing your hard work.

The following rather simple example sets an environment variable based on the name of the file being served. Then we use that environment variable in our logging directive to ignore certain entries in the log file:

RewriteEngine On
RewriteRule \.jpg$ - [env=dontlog:1]
CustomLog /var/log/apache/access_log combined env=!dontlog

The preceding block will set the dontlog environment variable to 1 whenever the requested URL ends in .jpg, and, in conjunction with the CustomLog directive, it will ensure that these requests don't end up getting logged.

You can also set several environment variables, if you like, within a commaseparated list:

RewriteRule \.png$ [E=image:true,E=png:true]

In this case, two environment variables are set. The environment variable image is set to the value true, and the environment variable png is also set to the value true.

Forbidden: F

The Forbidden, or [F], flag forces an HTTP 403 Forbidden status code. This is extremely useful, as it allows you to forbid access to various resources based on any arbitrary criterion, such as a pattern in the request, the browser type, or the time of day. The following example2 demonstrates how to block access to a request from a machine that is infected with the Nimda IIS worm (or one of its many variants):

RewriteEngine On
RewriteRule (cmd|root)\.exe - [F]

The rewrite pattern in this example looks for a request that contains either cmd.exe or root.exe, which are two of the target URLs of that worm. Using this technique in conjunction with the [E] flag just introduced, you could also eliminate these entries from your log files, since you already know that your Apache server is not susceptible to this worm:

RewriteRule (cmd|root)\.exe - [F,E=dontlog:1]

Gone: G

The Gone, or [G], flag causes Apache to send an HTTP 410 Gone status code, indicating that the requested URL no longer exists on the server. Among other things, this is an easy way to get search engines to remove certain URLs from their indexes:

RewriteRule \.cfm$ - [G]

Handler: H

The Handler, or [H], flag is new with Apache 2.2 and forces the target URL to be handled with the specified content-handler. You could, for example, force particular files to be handled by the mod_php handler:

RewriteRule ^/thread/(.*) /var/www/index.php?threadID=$1 [H=application/x-httpd-php]

This example is one of a larger class of rewrite rules, which are collectively referred to as clean URLs or as a variety of other similar names. The general goal of these sorts of rules is to make URLs easier to type, remember, and read. A URL that looks like http://example.com/thread/2 is much easier for the average person to remember than one that looks like http://example.com/index.php?threadID=2, and the preceding rule makes exactly that transition.

Forcing the handler type prevents the condition in which the resulting file target is served as plain text, bypassing the PHP handler. The same technique can be used for any other handler, such as the cgi-script handler.

If you are using a version of Apache earlier than 2.2, this behavior can usually be replicated using the [T] flag to set a MIME type, forcing a particular behavior. For example, whereas with 2.2 you would use [H=cgi-script] to force a particular target to be handled by mod_cgi, in earlier versions of Apache, you would instead use [T=application/x-httpd-cgi] to accomplish the same thing.

Last: L

The Last, or [L], flag indicates that the end of the rewriting process has been reached, and no further transitions should be applied to the requested URL. This is equivalent to the break or last statement in many programming languages. This flag is only useful when several rules are chained together in a single logical unit. However, it is good form to use this flag even when just a single rule is used. This is more of a reminder for you than for mod_rewrite.

Next: N

The Next, or [N], flag can be somewhat dangerous and should not be used unless you're really sure that this is what you want to do. Use of the [N] flag indicates that the rewriting process should be started all over again from the beginning. The next run through the rewriting process is done with the rewritten URL, not the originally requested URL.

This technique is typically used in order to do a modification that appears multiple times in a URL. Thus, it is run through the rewrite process several times to ensure that all occurrences were caught.

The danger with this technique is that it is very easy to get caught in an infinite loop when using the [N] flag. In many cases, the RewriteMap directive might be a better way to handle these scenarios.

However, to offer one simple example, consider this rule, which replaces - (dash) with _ (underscore) throughout a URI:

RewriteRule (.*)-(.*) $1_$2 [N]

This rule will run repeatedly until there are no more dashes in the requested URI. For example, if a requested URI looks like /x--y-z, the rule will be run three times - once for each dash in the URI - and then exit when there are no more dashes.

No Case: NC

Adding the No Case, or [NC], flag to any RewriteRule makes that rule case insensitive. That is, a rule with this flag will not care whether the text that it is considering is uppercase or lowercase. The default behavior of the RewriteRule directive is to be case sensitive.

RewriteRule ^/article/(\d*) /var/www/index.php?articleID=$1 \ [NC,H=application/x-httpd-php]

This example will look for URLs that look like /article/12 or perhaps like /Article/173 and rewrite those URLs to be an argument to another URL - in this case, a PHP file.

No Escape: NE

If the target URL of a RewriteRule contains special characters (generally speaking, any nonalphanumeric characters), those characters will be converted into their hexcode equivalents. For example, if a target URL contains a percentage sign (%), that character will instead be converted to its equivalent representation, %25.

There are, of course, times when this is not desirable, and you do in fact want the literal character that you have specified to appear in the rewritten URL. One common example of this is the # character, which, in HTML, allows you to jump to a particular named section of a document. By default, if a # character appears in a rewrite target, it will be converted to %23, which will cause the rewritten URL to fail. By using the [NE] flag, this can be avoided:

RewriteRule ^/docs/(.*) /usr/docs/directives.html#$1 [NE]

This rule takes a request for a particular configuration directive and maps that to the exact location within a larger document listing all of the directives. And the [NE] flag ensures that the # is actually treated as an anchor.

No Subrequest: NS

The No Subrequest, or [NS], flag is extremely useful when one file includes another file via a subrequest. For example, when an HTML file includes other HTML files via the Server-Side Include (SSI) mechanism, the included files are requested from Apache via a subrequest. Generally, you don’t want your RewriteRules applying to these subrequests, since that would cause the request paths to be broken. The [NS] flag specifies that the rule should not be applied to requests if they are subrequests.

Images and CSS files embedded in an HTML page are not retrieved via subrequests.

RewriteRule ^/ssi/(.*) /includes/files/$1 [NS]

Proxy: P

Using the Proxy, or [P], flag forces the rewritten URL to be fetched from another server via the proxy mechanism provided by mod_proxy. You must have mod_proxy installed in order to use the [P] flag. The rewrite target argument must be a fully qualified URL.

We will return to the topic of proxying in Chapter 11, and so just one example is offered here. In this example, we wish to have all images served from a dedicated image server:

RewriteRule ^/images/(.*) http://images.example.com/$1 [P]
ProxyPassReverse /images http://images.example.com

Passthru: PT

As mentioned earlier, by default, a rewrite target not starting with http:// or other protocol indicator is interpreted to mean a file path. If the path does not start with a leading slash, it is interpreted to be a file path relative to the current directory. If it does start with a slash, it is interpreted as an absolute file system path. This can be exceedingly inconvenient in many cases. Two particular cases bear describing.

The most common case is when you want to provide a URL path, and it is inconvenient to provide a full file system path.

The more serious case is when the target of a rewrite is a CGI program or other dynamic content. When a URL request is rewritten to a file path, the usual mechanisms for handling this content are bypassed, and the file is served to the client in its raw form:

RewriteRule ^/images/(.*)\.gif /usr/local/apache/cgi-bin/images.pl?gif=$1

This example, as given here, has the rather unexpected result of serving unexecuted Perl code to the browser, because it has bypassed the ScriptAlias mechanism, which relies on the URL starting with /cgi-bin/.

To get around these cases, the [PT] flag causes the rewrite target to be passed back to the URL mapping engine, so that it is treated like a URL rather than like a file path. The preceding example would become:

RewriteRule ^/images/(.*)\.gif /cgi-bin/images.pl?gif=$1 [PT]

Similarly, whenever Alias is used to map a URI to a directory, it is very useful to use [PT] so that the rewrite target can use the Alias path, rather than the full directory path. Many people, once aware of the [PT] flag, start using it all the time. It tends to be far more convenient than providing file paths, and, as a bonus, it ensures that the target is treated the way that most people expect it to be treated: as a URL. This flag’s greater ease of use may make up for what it lacks in efficiency for many server administrators.

Query String Append: QSA

By default, the RewriteRule directive ignores QUERY_STRING arguments. To remedy this deficiency, the Query String Append, or [QSA], flag causes the QUERY_STRING to be retained exactly as it is and tacked onto the end of the resulting request, in addition to anything that may have been put there during the rewriting of the URL. The default behavior, without the [QSA] flag, is to replace the existing QUERY_STRING with the new one.

Since the use of the ordinary Redirect (and RedirectMatch) directive does not retain QUERY_STRING arguments at all, it is often useful to use the [QSA] flag in attempts to construct

redirects that retain these arguments:

RewriteRule ^/example.php$ /cgi-bin/index.cgi [PT,QSA]

In this case, any QUERY_STRING arguments sent to the URL /example.php will instead be sent to /cgi-bin/index.cgi.

Redirect: R

The Redirect, or [R], flag forces an HTTP 302 Redirect to be sent to the client. This means, among other things, that the new URL will appear in the browser’s address bar, whereas most of the other uses of RewriteRule leave the end user completely unaware that any rewriting occurred.

Most of the time when people use mod_rewrite to do URL redirection, the Redirect or RedirectMatch directives are actually a better choice than RewriteRule. However, there are certainly many cases when doing a redirect via RewriteRule is appropriate. In this example, a redirect is necessary so that the browser is not confused about the type of the image being served:

RewriteRule ^/images/(.*)\.gif /jpegs/$1.jpg [L,R]

You will usually want to use an [L] flag in conjunction with the [R] flag, to ensure that the redirection happens immediately and further rewriting does not occur.

If you want to have a different redirection status code used, you can specify this as an argument to the [R] flag:

RewriteRule ^/images/(.*\.gif) /jpegs/$1.jpg [L,R=301]

Skip: S

The Skip, or [S], flag causes the rewrite engine to skip the next n rules, when the current rule matches. This may be used to build an if/else structure. The rules skipped become the else clause, since they are skipped when the if clause matches.

The motivation for this might become more apparent once the RewriteCond directive has been introduced, so explaining this flag will require a bit of a preview. RewriteCond allows you to apply a condition to the running of a RewriteRule. However, the RewriteCond directive only applies to one following RewriteRule. To force it to apply to multiple RewriteRule directives, you could use the [S] flag.

In the example that follows, we want to run the RewriteRules only if the requested filename doesn't exist:

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [S=2]
RewriteRule ^journal/(.*)$ index.php?arg=$1
RewriteRule ^feed/(.*)$ rss.php?arg=$1

This example causes the next two rules to be skipped if the requested URI corresponds with an actual file or directory. This can be thought of as a GOTO statement of sorts, if there are more rules following the two in the example.

Type: T

The Type, or [T], flag forces the resulting URL to be served with the content-type set to whatever is specified as the argument. The example given in the documentation causes URL requests ending in .phps to be answered by the source code of the associated PHP file, passed through the syntax highlighting functionality provided with mod_php:

RewriteRule ^(.+\.php)s$ $1 [T=application/x-httpd-php-source]

This technique can be used to force a particular document type on any requested URL.

Read more: http://www.techmetica.com/howto/apache-mod_rewrite-rewriterule-flags/#ixzz17H2Q5a9k

  • 本文為轉載文章 [原文]
  • 關鍵字 : example, RewriteRule, rewrite, cookie, target, rules, requested, index, images, environment, value, other, directive, variable, these, particular, which, using, there, should
0 0
2010-12-05T21:07:00+0000


  • 當您未登入黑族時,可以利用臉書 Facebook 登入來發表迴響。若使用黑族會員身份發表迴響則可獲得經驗值及虛擬金幣,用來參加黑族推出的活動。
發表迴響
驗證字串
留言