Apache rewriterule examples. Redirect from GET parameters

IN this lesson explains what it is mod_rewrite and how to use it. Three practical examples are described: 301 redirection, creating friendly URLs and blocking the use of image links.

mod_rewrite is a great web module Apache server. It is very flexible and can perform many useful functions.

Using mod_rewrite can be difficult for beginners due to its complex syntax and processing mechanism. However, once you understand a few basic concepts, you can effectively use mod_rewrite for your own server.

In this tutorial we will learn how to create several basic rules mod_rewrite on real examples, which you can use for your own website. It is recommended to carefully study the material about regular expressions if you do not already know what they are.

What is mod_rewrite?

mod_rewrite is an Apache server module for manipulating (changing) URLs. Often this means taking a URL request from a visitor and sending them content from a different URL. For example, a visitor enters the following URL into address bar browser:

http://www.example.com/page.html

Typically Apache sends the contents of the page.html file back to the user. However, using mod_rewrite you can send content from a different URL, like this:

http://www.example.com/another_page.html

It is important to understand that the address change occurs within the Apache server. The browser's address bar will still show http://www.example.com/page.html, but the Apache server will send the contents of the page http://www.example.com/another_page.html. This is different from an HTTP redirect, which tells the browser to visit another URL.

Although using the mod_rewrite module you can perform HTTP redirection and many other functions, such as returning HTTP error codes.

What can you do with mod_rewrite

The mod_rewrite module allows you to create manipulation rules URLs. For example, you can insert the value obtained from the requested URL into a new URL, creating a dynamic URL redirection. Or you can check server variables, such as HTTP_USER_AGENT (browser type), and change the URL only if you are using a browser, such as Safari running on an iPhone.

Here are a few normal functions, which mod_rewrite performs:

  • Generate "friendly" URLs that mask "clunky" URLs. For example, you can mask the real URL www.example.com/display_article.php?articleId=my-article with a great-looking URL www.example.com/articles/my-article/ . And everyone will be able to use a "friendly" URL instead of the real one.
  • Block the use of image links on your site. To stop others from using images hosted on your site, you can use mod_rewrite to send a "Forbidden" error if the referring URL does not belong to your site.
  • Redirecting canonical URLs. Many pages are accessible through multiple URLs—for example, www.example.com/mypage.html and example.com/mypage.html. You can use mod_rewrite to permanently redirect the browser to the "correct" URL, such as www.example.com/mypage.html. Among other things, this use of mod_rewrite ensures that the correct URL is displayed in the search results.
  • Eliminate 404 errors when reorganizing your site. For example, you are redesigning a website and have moved the page www.example.com/myarticle.html to the new URL www.example.com/articles/myarticle.html. With mod_rewrite you can redirect www.example.com/myarticle.html to www.example.com/articles/myarticle.html so that the visitor doesn't get a 404 "not found" error when visiting the old URL. Thanks to the flexibility of mod_rewrite, you can easily create a rule that will redirect requests to old URLs to new URLs.

How to use mod_rewrite

To use mod_rewrite, you need to create Apache directives to tell the module what to do. Directives are simple configuration settings. Often directives are placed in a .htaccess file in the root folder of your website. The directives apply to the entire site.

The two most important mod_rewrite directives are:

  • RewriteEngine: Enables/disables the mod_rewrite mechanism for the current request.
  • RewriteRule: Describes the rule for changing a URL.

Here's a simple example. Create a .htaccess file with the following content and place it on your site:

RewriteEngine on RewriteRule ^dummy\.html$ http://www.google.com/

IN this file the following settings are specified:

  • RewriteRule ^dummy\.html$ http://www.google.com/ - redirect requests to the dummy.html page to the Google website using a 301 redirect.

If you now open your web browser and visit the dummy.html page on your site (for example, by entering http://www.example.com/dummy.html in the address bar), then, if everything was done without errors, you will be redirected to the site http://www.google.com.

If you get a 404 error, then your hosting probably doesn't use mod_rewrite. IN in this case you need to contact your hosting administrator.

How RewriteRule works

You can use the RewriteRule directive to create redirection rules. The general syntax of the directive is:

RewriteRule Pattern Substitution

  • Pattern- regular expression pattern. If the URL matches the pattern, then the rule is executed. Otherwise the rule is skipped.
  • Substitution- a new URL that will be used instead of the address corresponding to the template.
  • - one or more flags that determine the behavior of the rule.

You can add as many RewriteRules as you need to your .htaccess file. The mod_rewrite module goes through all the rules every time a request is made, processing the corresponding URLs.

If the rule changes the requested URL to new address, then the new URL is used further when traversing the .htaccess file, and may match another RewriteRule located further in the file. (If you need to change this behavior, you need to use the L flag ("last rule").)

Some examples of using mod_rewrite

The easiest way to explain mod_rewrite is to show its use in solving practical problems.

Example 1: 404 error exception

Sometimes there's a change Page URL on your website. This can happen when the content is reorganized. If a search engine or other sites link to old address URL, the user will receive a "404" error Not Found" when he tries to use the link.

To solve this problem, you can use the mod_rewrite module to perform a 301 redirect. This sends an HTTP header to any browser that requested the old URL, telling them that the page has moved to the new address. It also tells search engines to update their indexes with the new URL.

The following .htaccess file will redirect requests to the new URL:

RewriteEngine on RewriteRule ^my-old-url\.html$ /my-new-url.html

The RewriteRule works like this:

  • ^my-old-url\.html$ is a regular expression that matches the URL to change. The pattern means: "matches the beginning of a URL (^), followed by the text "my-old-url.html" followed by the end of the URL character ($)." In a regular expression, the dot (.) character matches any character, so we need to use a backslash to indicate that we're looking for a dot (\.).
  • /my-new-url.html - the second part of the RewriteRule, which describes what needs to be changed. In this case it is simply /my-new-url.html.
  • the third part of a rule, which contains one or more flags placed in square brackets. Flags allow you to add specific options or actions to a rule. IN in this example 2 flags are used: R=301 means “use 301 redirect to new URL”; and L stands for "last rule", or in other words "stop processing the URL if it matches the rule".

Example 2: Creating Friendly URLs

Let's say you wrote PHP script display_article.php to display articles on your site. You can link to the article using the following URL:

Http://www.example.com/display_article.php?articleId=my-article

This address looks ugly and the query inside it (?articleId=my-article) may confuse some search engines. It's much better to use a URL like this:

Http://www.example.com/articles/my-article/

You can use mod_rewrite to convert links of the first format to the second, which will make it possible to use friendly links on site pages, and the request will be made to real addresses, not visible to anyone. To do this, the .htaccess file, located in the root directory of your site, must contain the following lines:

RewriteEngine on RewriteRule ^articles/([^/]+)/?$ display_article.php?articleId=$1 [L]

Description of the RewriteRule:

  • ^articles/([^/]+)/?$ is a regular expression that matches any URL in the format articles/(article ID)/ . It reads: "matches the beginning of a URL (^) followed by the text articles/ , followed by one or more non-slash characters ([^/]+) , which may be followed by a slash (/?) , followed by URL ending character ($) ". Note the parentheses around the [^/]+ part of the pattern. This way the text corresponding to the given part, for example "my-article" , is saved for later use.
  • display_article.php?articleId=$1 - this part The rule tells the Apache server to use the display_article.php script, which is passed the text matching the [^/]+ subpattern of the first part of the regular expression (for example, "my-article") as the articleId parameter. $1 is called feedback and stores the text corresponding to the subtemplate. If the regular expression contains another subpattern in parentheses, then the corresponding text will be stored in the variable $2, and so on.
  • [L] - as in the previous example, we use a flag to stop further processing of the URL so that the address does not change by other RewriteRules.

The above RewriteRule takes the requested URL in the format http://www.example.com/articles/my-article/ and converts it into a URL like http://www.example.com/display_article.php?articleId=my-article .

Example 3: Preventing Image Links on Your Site

Another typical task that the mod_rewrite module solves is preventing other web projects from using links to images on your site. Let's say you have a page on your site http://www.example.com/mypage.html that contains the following img tag:

Another site may link directly to your photo on its pages like this:

This means that someone else's site not only "borrows" your image, but uses some of your server traffic to display the image on their pages. And if someone else's site has big flow visitors, then this situation will become a problem!

You can use the following mod_rewrite directives to stop all sites other than your own from using image links. Place the below code in your .htaccess file in root directory your site or in a folder with images that need to be protected. Change example.com to your domain name.

RewriteEngine on RewriteCond %(HTTP_REFERER) !^$ RewriteCond %(HTTP_REFERER) !^http://(www\.)?example\.com/.*$ RewriteRule .+\.(gif|jpg|png)$ - [ F]

Once you are done with all the copying operations, any browser that requests images from your site uses URL request starting with a domain name other than www.example.com or example.com will receive a "403 Forbidden" error. which will stop links to your images on other sites.

Here's how it works this set rules:

  • RewriteEngine on - enable the mod_rewrite mechanism
  • RewriteCond %(HTTP_REFERER) !^$ - RewriteCond is another mod_rewrite directive. It allows you to set a condition that must be met for the following RewriteRule to process a URL. In this case, the condition is the presence of a value in the HTTP_REFERER variable.
  • RewriteCond %(HTTP_REFERER) !^http://(www\.)?example\.com/.*$ - the second RewriteCond directive requires that the value of the HTTP_REFERER variable not begin with http://www.example.com/ or http http://example.com/. The flag sets case sensitivity.
  • RewriteRule .+\.(gif|jpg|png)$ - [F] - if the two above previous RewriteCond conditions are not met, then the rule is skipped. The rule itself returns the error "403 Forbidden" (the [F] flag is used) if the URL contains an image file name (the line ends with .gif , .jpg or .png). The dash in the substitution parameter means "do not replace the URL with another address" .

That is, the entire set of rules in the .htaccess file states that if the HTTP_REFERER variable contains a value and it does not start with http://example.com/ or http://www.example.com/ , and the requested URL contains the name of the image file, then you need to refuse the request with the error "403 Forbidden".

Conclusion

In this tutorial, we provided an introduction to using the Apache mod_rewrite server module to manipulate URLs. The three considered practical examples affect only a small part of all module capabilities. More detailed information about mod-rewrite in Russian can be found.

Basics and features of mod_rewrite, examples of using mod_rewrite, server variables, flags ( RewriteRule Flags), redirection, access denial by time of day or user agent, access denial by referrer or in its absence.

Peace be with you Brothers and Sisters! At the request of workers, today I am here as a type of training program, whose name is Oleg, and today we will try to explain to ourselves, first of all, the basic principles of the mod_rewrite miracle module in order to have a clear understanding of how the conditions and rules work, and not just stupidly copy/paste them. So let's begin...

The Apache mod_rewrite module is a very powerful, yet complex, tool for manipulating URL redirects/transformations/bans. Using this miracle module, you can perform almost any URL conversion/manipulation on the server side.

Please note that some URL manipulations do not require such a powerful and complex (especially for beginners) module as mod_rewrite. For simple tasks you can use mod_alias. The word "powerful" does not only mean ample opportunities for URL conversion, but also increased consumption of server resources compared to other modules.

Regular expressions mod_rewrite

mod_rewrite uses Perl Compatible Regular Expression ( PCRE - Perl compatible regular expressions). In this article, we will not describe in detail the use of regular expressions. IMHO, entire volumes of books are devoted to this topic and it is impossible to cover this topic in one article.

  • Secrets of regular expressions: Part 1. Dialects and capabilities. Writing Regular Expressions

The main thing to remember is that regular expressions use special characters (metacharacters) and regular characters ( literals). The main metacharacters are \ / ^ $ . | ? * + () ( ) . Metacharacters should always be escaped with a backslash "\" - this applies to a space ("\") as well as a backslash ("\\").

One thing to remember is that mod_rewrite uses the original PCRE ( Perl compatible regular expressions), but with some additions:

  • "!Condition" (condition not met)
  • "<Условие " (лексически меньше условия)
  • ">Condition" (lexically more than a condition)
  • "=Condition" (lexically equal to condition)
  • "-d " (is it a directory)
  • "-f" (is regular file)
  • "-s " (is it a regular file with a non-zero size)
  • "-l " (is it a symbolic link)
  • "-F " (check for file existence via subquery)
  • "-U " (check for URL existence via subquery)

Mod_rewrite rules processing order

The order in which mod_rewrite rules are processed is far from obvious. The mod_rewrite rules are composed approximately in this order:

RewriteEngine on RewriteBase / # uncomment this line if web-base dir not root # RewriteBase /you-web-base-dir RewriteCond %(what_to compare) with_what_to compare [flags] RewriteRule source_url target_url [flags]

Now a little more detail:

  • RewriteEngine - there must be one;
  • RewriteBase - can be useful when using relative links in rules, but if relative links refer to the root of the directory, then this directive may not be used; theoretically, it can be used multiple times before each of the rules;
  • RewriteCond - a condition that must be met before the rule is executed; there can be several conditions;
  • RewriteRule is the rule itself, which is executed when the condition is met.

The order in which .htaccess rules are placed is important because the transformation engine processes them in a special order. Line by line is reviewed first RewriteRule directives and if the URL pattern matches ( Pattern, source_url) of a specific rule, conditions are checked ( RewriteCond directives) related to this rule. Terms ( RewriteCond) must always come before the rules ( RewriteRule)! In Fig. Below is how mod_rewrite rules are processed.

As you can see, the Current URL is first compared with the Rule Pattern and, if the pattern matches, the conditions are checked; if the Current URL satisfies the conditions, then the rule and Transform are applied to it. The URL goes further for processing if the [L] flag is not specified ( last).

The [L] flag should be used for each rule, of course, if no further URL transformation is required.

mod_rewrite variables

You can use server variables in conditions (RewriteCond) and rules (RewriteRule).

1. HTTP headers (RqH - Request Header):

  • HTTP_USER_AGENT - contains full line header "User-Agent:";
  • HTTP_REFERER - the address from which the user came;
  • HTTP_COOKIE - access to the browser's COOKIE list;
  • HTTP_FORWARDED - contains the IP address of the proxy or load balancing server;
  • HTTP_HOST - the host/server address that the user requested, for example, example.com;
  • HTTP_PROXY_CONNECTION - contains the connection token ( connection-token) "close" or "Keep-Alive", intended for negotiation permanent connections between the client and the server (analogous to the Connection header);
  • HTTP_ACCEPT - content negotiation header that the user's browser/client supports, for example " text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 " ("type/subtype", separated by commas , where type is the content type and subtype is a refinement of the type.). If the Accept header contains " Accept: */* " (*/*), then this means that the client is ready to accept content of any type.

2. connection & request (connection & request):

  • REMOTE_ADDR - client IP address;
  • REMOTE_HOST - DNS name of the client's IP address;
  • REMOTE_PORT - number of the current client port;
  • REMOTE_USER - contains the name of the authorized (using server means) user;
  • REMOTE_IDENT - the variable will be set only if the mod_ident module is connected and IdentityCheck is set to "on", designed to work with the Ident protocol https://ru.wikipedia.org/wiki/Ident;
  • REQUEST_METHOD - the method by which the request was made, GET|GET|HEAD, etc.;
  • SCRIPT_FILENAME - full path to the requested file, for example /var/www/public_html/script_name.php;
  • PATH_INFO - Contains the user-supplied path that appears after the script name but before the query string (?). For example, if the script was requested from the URL http://www.example.com/php/path_info.php/some/stuff?foo=bar, then the $_SERVER["PATH_INFO"] variable would contain /some/stuff.
  • QUERY_STRING - string GET request, if the requested address is http://example.com/index.php?var=1&var=2, then QUERY_STRING will contain var=1&var=2;AUTH_TYPE - authentication type, if HTTP authentication is performed, it can be Basic or Digest.

3. server internals:

  • DOCUMENT_ROOT - full path to the user's home directory, for example /var/www/public_html/
  • SERVER_ADMIN - server/virtual_host administrator data, usually an email address;
  • SERVER_NAME - server name, usually from the ServerName directive;
  • SERVER_ADDR - server IP address;
  • SERVER_PORT - server port;
  • SERVER_PROTOCOL - version of the protocol used, for example HTTP/1.0 or HTTP/1.1;
  • SERVER_SOFTWARE - name/version of the server.

4. date and time(system, date and time):

  • TIME_YEAR - year, 2014
  • TIME_MON - month, 05
  • TIME_DAY - day, 07
  • TIME_HOUR - hour, 04 (24)
  • TIME_MIN - minutes, 38
  • TIME_SEC - seconds, 55
  • TIME_WDAY - day of the week, 3 (Wednesday)
  • TIME - in the format year-month-day-hour-min-sec, for example 20140514234534

5. specials (special):

  • API_VERSION - in the format "20051115:33"
  • THE_REQUEST - details of the GET/POST request, for example "GET /index.html HTTP/1.1"
  • REQUEST_URI - relative request URL "/index.html"
  • REQUEST_FILENAME - full local path to a file or script in file system, corresponding request
  • IS_SUBREQ - if a subquery is executed, the variable contains true, otherwise false
  • HTTPS - on/off, if HTTPS is used/not used

6. execution result variables:

  • $1 - $1, $2, etc. are formed when (pattern1.*) matches (pattern2.*) from RewriteRule
  • %1 - %1, %2, etc. are formed when (pattern1.*) matches (pattern2.*) from RewriteCond
  • Read more about HTTP headers can be read in the rfc2616 Hypertext Transfer Protocol specification -- HTTP/1.1

mod_rewrite flags

To control the behavior of conditions ( RewriteCond) and rules ( RewriteRule) mod_rewrite uses flags [flags].

  • [B] ( escape backreferences) - forces you to escape (encode) special characters, for example, take the rule “RewriteRule ^search/(.*)$ /search.php?term=$1” which contains a search string that may contain, for example, “x & y/z” " and the result will be the string " search.php?term=x & y/z ", which is not a valid URL and will be converted by the browser to " search.php?term=x%20&y%2Fz= ". With the [B] flag, the string will be converted to " /search.php?term=x%20%26%20y%2Fz ". For this example to work, you will need to set AllowEncodedSlashes to On because httpd by default does not allow encoding slashes in URLs
  • [C] chain- combine several rules into a chain. If the first rule in a chain does not satisfy the conditions, then the entire chain will be ignored
  • cookie- sets cookies in the format, parameters for secure and httponly are set to true|false
  • discardpathinfo- discards PATH_INFO in the converted link, useful in cases where PATH_INFO was already added in a previous conversion
  • [E] env- set a variable or delete it
  • [F] forbidden- returns error 403
  • [G] gone- returns error 410
  • [H] handler- forcefully installs a handler for certain file types, for example the rule "RewriteRule !\. -" will force all files without an extension to be passed through PHP
  • [L] last- indicates that the rule is the last and the process of further transformation stops
  • [N] next- starts the conversion process from the first rule in order, use this flag with caution because it can lead to a closed loop (the so-called loop)
  • nocase- disables case checking
  • noescape- mod_rewrite generally applies URI escaping rules to the result of the rewrite. Special characters (such as "%", "$", ";", etc.) will be escaped by their hexadecimal ( hexcode) substitutions ("%25", "%24", and "%3B", respectively). This flag prohibits this
  • nosubreq- ignore subqueries, execute the rule only for real/direct queries
  • [P] proxy- Apache executes a subquery to the specified page using software module mod_proxy, in which case the client will not know anything about this subrequest. An error will occur if the mod_proxy module is not connected
  • passthrough- stop the conversion and transfer the received new link further
  • qsappend- adds initial request parameters ( query string) for replacement. If the lookup does not include new query parameters, the original query parameters will be added automatically. If new parameters are included in the substitution, then the original request parameters will be lost if the QSA flag is not specified
  • [R] redirect- returns a redirection command to the browser ( The default code is 302 - MOVED TEMPORARY), you can specify the redirect code yourself, for example R=301 ( code 301 - MOVED PERMANENTLY), but within the range 300-399, otherwise the rule will not be processed
  • [S] skip- skips the next rule if this rule it worked. You can specify the number of rules, for example: S=2
  • [T] type- forcefully sets the MIME type of the target file. For example, "RewriteRule \.pl$ -", this rule will display Perl scripts V text format, which means the script code will be output to the browser.

Read more about flags in the original:

Protocols allowed in mod_rewrite

mod_rewrite will define a wildcard URL as external if one of the protocols is specified:

  • ajp:// - Apache JServ Protocol
  • balancer:// - Apache Load Balancer
  • ftp:// - File Transfer Protocol
  • gopher:// - Gopher (protocol)
  • http:// - Hypertext Transfer Protocol
  • https:// - Hypertext Transfer Protocol Secure
  • ldap:// - Lightweight Directory Access Protocol
  • nntp:// - Network News Transfer Protocol
  • ldap: - Lightweight Directory Access Protocol
  • mailto: - The mailto URI scheme
  • news: - News Protocol

.htaccess and rules placement order

In the .htaccess file, theoretically, directives can be specified at random, with the exception of directives related to rewrite_module. However, it is better to follow a certain sequence:

  1. CORE directives;
  2. Module configuration.

The rewrite_module directives that perform a redirection rather than a transformation must come first, otherwise, after the request has been transformed, the desired redirection may not occur unless previous transformations are taken into account.

Examples of mod_rewrite rules

Denying access using mod_rewrite

RewriteCond %(TIME_HOUR)%(TIME_MIN) >2000 RewriteCond %(TIME_HOUR)%(TIME_MIN)<0700 RewriteRule .* - [ F ] # OR RewriteCond %{TIME_HOUR} >=20 RewriteCond %(TIME_HOUR)<07 RewriteRule .* - [ F ]

This rule will block access from 8 pm to 7 am. The above example, especially for copy/paste fans, contains an intentional syntax error, HTTP 500 ( server error), which will result in an entry in the error log RewriteRule: bad flag delimiters . Translated as a bad flag separator - instead of [ F ] you need to use [ F ] , i.e. Avoid spaces and other delimiters other than commas!

2. We strictly prohibit the WBSearchBot bot from touching our site:

RewriteCond %(USER_AGENT) WBSearchBot RewriteRule .* - [F] # Another option, instead of error 403 (FORBIDDEN), we give error 404 (NOT FOUND) RewriteCond %(USER_AGENT) WBSearchBot RewriteRule .* -

Although, by slightly adjusting the rule, you can t.s. transfer the arrows to someone else, so to speak, set the bot on another site, they say...are you crazy!? Go and train on it... :)) (from the film Operation “Y” and other adventures of Shurik):

RewriteRule .* http://kremlin.ru

WBSearchBot ( Mozilla/5.0 (compatible; WBSearchBot/1.1; +http://www.warebay.com/bot.html)) is a rather aggressive bot and you can safely get rid of it.

# BLOCK POST REQUEST FOR OLD HTTP PROTOCOL... RewriteCond %(THE_REQUEST) ^POST RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.|www1\.)?example.com RewriteCond %(THE_REQUEST) POST(.*)HTTP/(0 \ .9|1 \.0) RewriteCond %(HTTP_USER_AGENT) ^$ RewriteRule .* -

In the previous example, the 303 See Other response code is not specified by chance - the fact is that if the redirection method ( usually GET) is different from the request method ( for example POST), then if response codes 301-302 are returned, instead of an automatic redirect, a page with a link for manual navigation will be displayed in the browser! In the case of a 303 See Other response, the redirection is performed automatically using the GET method, regardless of the request method.

4. Hotlink protection - we prohibit the display of our images from other sites:

# # HOTLINK PROTECT... # http://www.htaccesstools.com/hotlink-protection/ RewriteCond %(HTTP_REFERER) !^$ RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.|www1\.)?site RewriteCond %(HTTP_REFERER) !^http(s)?://( www\.)?google.com RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?yandex.ru RewriteCond %(HTTP_REFERER) !^http(s)?://(www\ .)?subscribe.ru RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?feedburner.com RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.) ?mail.ru RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?poisk.ru RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?rambler .ru RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?nigma.ru RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?ask.com RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?qip.ru RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?ukr.net RewriteCond % (HTTP_REFERER) !^http(s)?://(www\.)?conduit.com RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?tut.by RewriteCond %(HTTP_REFERER ) !^http(s)?://(www\.)?bing.com RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?webalta.ru RewriteCond %(HTTP_REFERER) ! ^http(s)?://(www\.)?yahoo.com RewriteCond %(HTTP_REFERER) !^http(s)?://(www\.)?conduit.com RewriteRule \.(jpg|jpeg| png|gif) https://dl.dropboxusercontent.com/u/52572427 / \ images/wrs-hotlink-deny .jpg

  • RewriteRule ^ - RewriteCond %(HTTPS) on RewriteRule ^ - # To redirect all users to access the site WITH the "www." prefix, # (http://example.com/... will be redirected to http://www.example.com/...)# uncomment the following: RewriteCond %(HTTP_HOST) . RewriteCond %(HTTP_HOST) !^www\. RewriteRule ^ http%(ENV:protossl)://www.%(HTTP_HOST)%(REQUEST_URI) # OR # REDIRECT FOR /DOCS Redirect permanent /docs http://docs.example.com

    2. Redirect our RSS/ATOM feeds to FeedBurner

    # REDIRECT blog RSS/ATOM to FeedBurner... RewriteCond %(HTTP_USER_AGENT) !^.*(FeedBurner|FeedValidator) RewriteCond %(QUERY_STRING) ^option=com_content&view=featured&Itemid=()+&format=feed RewriteRule index.php http://feeds.feedburner.com/remote-shaman- blog? # # REDIRECT forum RSS/ATOM to FeedBurner... # if HTTP_USER_AGENT not FeedBurner or FeedValidator RewriteCond %(HTTP_USER_AGENT) !^.*(FeedBurner|FeedValidator) # forum/topics/mode-topics?format=feed # forum/topics/mode-latest?format=feed # forum/topics/posts?format=feed# forum/recent?format=feed RewriteCond %(QUERY_STRING) ^format=feed$ RewriteRule forum/(*/)?()+ http://feeds.feedburner.com/remote-shaman-forum?

    Please note that at the end of each link in the rules ( RewriteRule) there is a "?" symbol - it is required so that QUERY_STRING parameters are not added to the end of the link to which the request will be redirected! if you do not specify the "?" character, then the redirection will end up being http://feeds.feedburner.com/remote-shaman-blog?option=com_content&view=featured&Itemid=... and http://feeds.feedburner.com /remote-shaman-forum?format=feed respectively.

    Results

    mod_rewrite is a powerful tool and it can do wonders - that's a fact! There are not many examples in this article, but there are plenty of them on the Internet, but there is practically no material about what is what and why in a style for complete idiots. Perhaps more examples of using mod_rewrite will be added to this page later.

    In this article I tried to explain as clearly as possible (I hope I succeeded) the basic principles of operation of the miracle module mod_rewrite, in a style like for complete idiots (in the good sense of the word;), IMHO from my own experience I know how difficult it is sometimes to master something with zero and when the mana and principles of this something are described in general vague phrases and deeply technical terms.

    When writing this material, only original mana from the site httpd.apache.org was used (no copy/paste). If I missed something or missed something somewhere, then be sure to write about it in the comments.

What is mod_rewrite mod_rewrite is an Apache web server module used to resolve URLs. Transformation should be understood as virtually any action with a URL. This is a very powerful and at the same time flexible tool with very wide capabilities. The module allows you to perform almost any type of transformation. Using mod_rewrite you can set up redirects, change URLs, block access, etc. It supports an unlimited number of transformation rules, regular expressions, callbacks with grouped parts of the template, different sources of information for transformations (server variables, HTTP headers, time, etc.). Due to this set of capabilities, high functionality and flexibility are achieved. By default, this module is disabled; in order to enable it, you need to add the following directives to .htaccess:

RewriteEngine On
RewriteBase /

RewriteEngine On- the directive enables the module.
RewriteBase— indicates the path from the site root to the .htaccess file. If .htaccess is in the root, then you need to specify this parameter as in the example; if in the internal directory, then specify the path to this directory, for example /images.

How the mod_rewrite module works

The operation of the module is based on a set of rules and conditions according to which the transformation is carried out. When receiving a request, Apache passes mod_rewrite the path to the file starting from the location where the .htaccess file is located, the rest of the path is truncated. If a request is received http://some-url.com/cat/cat2/file.html, and .htaccess is in the root, then mod_rewrite will include cat/cat2/file.html (without the leading slash). If .htaccess is in the /cat directory, then mod_rewrite will contain cat2/file.html. Next, mod_rewrite analyzes the rules in .htaccess and acts according to these rules. It is worth knowing that mod_rewrite does not work with links or URLs, but with ordinary strings. That is, the address that needs to be converted is passed to mod_rewrite as a regular string, and this string can be converted as desired. To build rules, two directives are used, RewriteCond and RewriteRule (these directives are described in more detail below).​
RewriteCond— this directive defines the conditions under which the RewriteRule transformation rule will work. If the condition in RewriteCond is met, we execute the rule in RewriteRule. There can be an unlimited number of such conditions before the RewriteRule rule. RewriteCond is not a required directive to create a conversion rule and may be missing.
RewriteRule— the rule for the transformation itself is already indicated here, which should be the only one for a specific transformation.
An example of what it looks like in .htaccess:

RewriteCond %(REQUEST_URI) !.(ico|css|js|txt)$
RewriteCond %(REQUEST_FILENAME) !^/admin

Even though the RewriteCond directive is higher than the RewriteRule, mod_rewrite first checks the string against the pattern in the RewriteRule, and if the string matches the pattern, it looks at the above conditions in the RewriteCond. If the conditions also match, the transformation occurs according to the RewriteRule. Let's take a closer look at the syntax and purpose of the RewriteCond and RewriteRule directives.

RewriteCond

As mentioned above, this directive specifies the conditions under which the rule in the RewriteRule directive will be executed. This directive looks like this:

RewriteCond [compare_string] [condition] [flag]
RewriteCond %(REQUEST_URI) !.(ico|css|js|txt)$

In this example, the condition rule will be satisfied if the user's request does not contain the ​ico, css, js or txt extension.
String to compare— in addition to plain text, it can contain a regular expression, reverse RewriteCond and RewriteRule connections, and server variables. In practice, this uses server variables and sometimes regular expressions.
Condition- this is actually what the comparison string is compared to. Can contain text, regular expressions and special characters:

  • "-d"— checks the correctness of the path (its existence) and whether this path is a path to a directory.
  • "-f"— checks the correctness of the path (its existence) and whether this path is the path to a regular file.
  • "-s"- same as -f, but additionally checks that the file size is greater than 0 (zero).
  • "-l"— checks the correctness of the path (its existence) and whether this path is a symbolic link.
  • "-F"— checks through an internal subquery whether the string being compared is a real existing file, using all existing server access control lists. This has a negative impact on performance and should be used with caution.
  • "-U"— checks through an internal subquery whether the string being compared is actually a URL, using all existing server access control lists. This has a negative impact on performance and should be used with caution.
Additionally, before the condition, the use of logical symbols is allowed:
  • "!" - value inversion, indicates that the string being compared must not match the condition pattern.
  • "<" - lexically less. For example, the character "a" is lexically smaller than the character "b", "a"< "b".
  • ">" - lexically more.
  • "=" — equality, used by default.

Flag— an optional parameter that specifies additional options (separated by commas if there are several of them). Indicated at the end of the rule in square brackets.

  • — case-insensitive, that is, the case (A-Z or a-z) in the comparison line or condition does not matter.
  • - logical OR. Used when a RewriteRule directive is preceded by multiple RewriteCond directives and the rule in the RewriteRule must be executed when one of the RewriteConds matches. If the OR flag is not specified, the RewriteRule will only fire if all RewriteCond directives match.

RewriteRule

​The RewriteRule specifies the transformation rule, how we want to change the URL. In fact, this directive also contains a condition, if which matches, the conversion will be performed. This is the template against which the resulting mod_rewrite string is checked. It is worth noting that if you do not need to substitute anything, and such cases sometimes occur, you must indicate a dash in the new value "-" . Schematically, the RewriteRule looks like this:

RewriteRule [pattern] [new_value] [flag]
RewriteRule ^(.*)$ /index.php [L]

Sample— what the source string will be compared with. The source string is not necessarily the one the user requested. It may have been previously modified by other RewriteRules. Can contain plain text, regular expressions, and reverse RewriteCond and RewriteRule connections. The source line is the path from the .htaccess file to the file, the domain name is not there.
New meaning is the value to which the original string will be changed after the transformation. Can contain plain text, regular expressions, reverse RewriteCond and RewriteRule connections, and server variables.
Flag— ​optional parameter that specifies additional options (separated by commas if there are several of them). Indicated at the end of the rule in square brackets.

  • - redirect. code is the browser response code, the default is 302 (temporarily moved), so for a permanent redirect use code 301.
  • [F]— blocking access to URL, Forbidden. The server returns an error code 403 to the browser.
  • [G]— returns error 410, URL does not exist.
  • [P]- Apache performs a subrequest to the specified address using another Apache mod_proxy module.
  • [L]- the last rule. Indicates that URL conversion should be stopped at this point.
  • [N]— the transformation process will be started again, starting from the very first rule. The previously modified string will be used.
  • [C]— connection with the next rule, a chain of rules is created. If a rule does not match, all subsequent rules in the chain are skipped.
  • — rules are triggered only for queries, subqueries are ignored.
  • [T]— force the MIME type of the file to be specified.
  • - Ignore character case.
  • — supplement the query string, rather than replace it. The flag should be used when working with GET parameters in the %(QUERY_STRING) variable, so as not to lose them. If this flag is not specified, the data in %(QUERY_STRING) will be completely replaced by the parameters from the RewriteRule. If the flag is specified, new parameters will be added to the beginning of %(QUERY_STRING).
  • — prohibits conversion of special characters to their hex equivalents.
  • — stops the conversion and passes the string on for processing by other directives (Alias, ScriptAlias, Redirect, etc.).
  • [S]— skip the next rule. It is possible to specify several rules in the format S=N, where N is the number of rules.
  • — set an environment variable, where VAR is the name of the variable, and VAL is its value. The value can be the inverse of RewriteCond and RewriteRule or text.
  • — install cookies in the browser. NAME - cookie name, VAL - value, domain - domain name, lifetime - lifetime (optional), path - path for which this cookie is valid, default is "/", secure - if set to 1 or true, cookies will be valid only on https (secure) connection, httponly - if set to 1 or true, cookies will be available to JavaScript.

RewriteCond and RewriteRule feedbacks

Feedbacks are the ability to use a group of characters (enclosed in parentheses "()" ) for their subsequent substitution. For example, you can specify a specific regular expression in brackets and thus cover a large number of addresses.
$N— allows you to use a group of characters from the RewriteRule directive template.
%N— allows you to use a group of characters from the RewriteCond directive template.
Instead of the symbol "N" in both cases a number from 1 to 9 is used.
In practice it looks like this. Let's look at a simple example.
There is an address with a certain nesting, http://some-url.com/cat1/cat2/cat3/cat4/page.html. There is a desire to make the page http://some-url.com/cat1/cat2/cat3/cat4/page.html available at http://some-url.com/page.html, but in addition to page.html, there is a bunch of other files with the html extension that should also be available at the new address. This can be solved very simply:

RewriteRule ^cat1/cat2/cat3/cat4/(.*).html$ $1.html

Now, when accessing the address http://some-url.com/page.html, information from the address http://some-url.com/cat1/cat2/cat3/cat4/page.html will be displayed, and so on all addresses like http://some-url.com/*.html. In the same way, using "%N", you can substitute groups of characters from the template for RewriteCond. In this example, instead of $1, a group of characters in brackets from the template is substituted.

Server Variables

​Server variables can contain a lot of useful information that can and should be used to build rules. Below is a list of these variables:
HTTP_USER_AGENT— provides information about the user’s browser and OS. When a user visits a site, a User Agent is transmitted, in fact this means the software with which the site is accessed.
HTTP_REFERER— the address of the page from which the transition to the site was made.
HTTP_COOKIE— a list of cookies sent by the browser.
HTTP_FORWARDED— the address of the page from which the transition was made. I didn't notice much difference with HTTP_REFERER.
HTTP_HOST— server (site) address.
HTTP_ACCEPT- these are the client’s wishes, according to the type of document he wants to receive. In reality, it looks like this: the browser sends to the server in the http header the types of files it wants to receive (usually this applies to images and other media files), that is, it tells what type of file it can process.
REMOTE_ADDR— IP address of the visitor.
REMOTE_HOST— the address (host) of the user, which is given by the “host” command to the IP address.
REMOTE_IDENT— username in the format name.host.
REMOTE_USER- the same as REMOTE_IDENT, but does not contain the user's host.
​REQUEST_METHOD— type of request to the site (GET, POST, HEAD).
SCRIPT_FILENAME— full path to the requested file or address.
PATH_INFO— data that was transferred to the script.
QUERY_STRING— a string passed as a request to the CGI script, GET parameters.
AUTH_TYPE— user identification type.
DOCUMENT_ROOT— path to the server root directory.
SERVER_ADMIN— email of the server administrator.
SERVER_NAME— server address (name), given by the host command.
SERVER_ADDR— IP of your site.
SERVER_PORT— the port where Apache runs.
SERVER_PROTOCOL— version of the http protocol.
SERVER_SOFTWARE— the version of Apache used.
TIME_YEAR, TIME_MON, TIME_DAY, TIME_HOUR, TIME_MIN, TIME_SEC, TIME_WDAY, TIME- time.
API_VERSION—Apache module API version.
THE_REQUEST— the line contains the entire http request sent by the browser to the server (GET /index.html HTTP/1.1). Additional headers are not included here.
REQUEST_URI— the address requested in the http header.
REQUEST_FILENAME— the full path to the requested file, in fact contains the same data as SCRIPT_FILENAME.
IS_SUBREQ— check for a subquery. If yes, the answer is true, if no, the answer is false.
You can easily find out the list of your server variables by placing a php file with the code in the root of the site:

By typing the address of this file in your browser, at the bottom of the page you will receive information about server variables.

8. RewriteOptions directive, technical details, when NOT to use mod_rewrite

In the previous parts we studied almost all mod_rewrite documentation. Directives left RewriteMap And RewriteOptions. RewriteMap is also used to rewrite URLs, but is used less frequently than others; We will return to it later. Directive RewriteOptions also used infrequently. Feature RewriteMap is that it cannot be used in .htaccess. It can only be used in the context of a server or virtual hosts. By and large, RewriteMap does not add new functionality - it only allows you to move a large array of data that is impractical or too difficult to describe using regular expressions into separate files. Such dedicated databases are obtained. However, we will still consider RewriteMap in one of the subsequent parts.

Now, to reinforce the theory we've learned, we'll move on to practical examples of the most common uses of mod_rewrite, including a detailed description of how they work. If after getting acquainted with the theory and these examples you still have questions, then write them here in the comments.

Please note that many of the examples use specific file paths, query values, etc. - these examples will not work for you without changes to your server configuration, so it is important that you understand them and not simply copy them into your configuration.

Checking mod_rewrite availability

How to enable RewriteEngine

Enabling the mod_rewrite module in the Apache configuration file was discussed in . If the module is enabled, then it must be activated in the file .htaccess directive:

RewriteEngine On

You only need to do this once, even if you use multiple rewrite rules.

For the module to work, the option must also be activated FollowSymLinks. This option can be activated in the Apache configuration file (this was also already discussed in the first part). If this option is disabled at the web server (or virtual host) level, then it can be enabled in the .htaccess file. It must be specified before the directive RewriteEngine:

Options +FollowSymLinks RewriteEngine On

How to check if mod_rewrite is enabled

How to check whether mod_rewrite is enabled or not in PHP

The simplest way is to use the function phpinfo(). If the module is enabled, then in the table apache2handler in the column Loaded Modules will be indicated mod_rewrite(as well as all other modules that are included).

This method is the most universal: you can use it on any system, including shared hosting.

How to check if mod_rewrite is enabled on Windows

Open command prompt ( Win+x, then select Windows PowerShell). Go to the directory where the Apache binaries are located. For example, in my case this is the folder C:\Server\bin\Apache24\bin\:

Cd C:\Server\bin\Apache24\bin\

And run the command there:

./httpd.exe -M

A complete list of modules will be displayed.

How to check if mod_rewrite is enabled on Linux

To list all modules loaded by the Apache web server, use the option -M. The web server executable file may be called apache2ctl or httpd depending on the distribution used.

For Debian, Ubuntu, Kali Linux, Linux Mint and their derivatives, the command to list modules is as follows:

Apache2ctl -M

For Arch Linux, BlackArch and some other distributions the command is:

Httpd-M

Checking if mod_rewrite is enabled using .htaccess

In file .htaccess write down the directive:

RewriteEngine on

And try to open the address of the folder where you saved .htaccess, if the error “500 Internal server error” occurs, it means the mod_rewrite module Not enabled in the Apache configuration file.

How to make rewrite rules only used if mod_rewrite is enabled

Design checks whether the module is enabled. If the module is enabled, then the directives that are located in the section are executed . If the module is disabled, these directives are ignored. As a result, if the module is disabled, then unknown directives will not cause a web server error.

Usage syntax:

…… ……

Instead of ellipses, write down the desired mod_rewrite directives, example:

RewriteEngine On RewriteCond %(HTTP_USER_AGENT) ^HTTrack RewriteCond %(HTTP_USER_AGENT) ^sqlmap RewriteCond %(HTTP_USER_AGENT) ^wpscan RewriteCond %(HTTP_USER_AGENT) ^text RewriteRule ^.* - [F]

Before the module name you can put ! (exclamation point) and then what's inside IfModule will be executed only if the module being checked is NOT enabled.

Sections can be used inside another section and perform simple tests of several modules depending on the condition of previous module tests.

This section should only be used if you need a single configuration file that works regardless of whether a particular module is available. In normal operation, directives should not be placed in sections .

Using mod_rewrite to redirect and redirect URLs

The page has changed its address, how to show a new page at the old address without a redirect

Description:

Let's say we recently renamed the foo.html page to bar.html and now want the old URL to also work for backwards compatibility. However, we want to ensure that users of the old URL don't even know that the pages have been renamed, meaning we don't want the address to change in their browser.

We use RewriteRule to transform a request containing an old address to a new one by setting the following rule:

RewriteEngine on RewriteRule "^/foo\.html$" "/bar.html"

In this example ^/foo\.html$ is a regular expression. Symbols ^ And $ indicate the beginning and end of a line, respectively. The dot is preceded by a slash so that the character is treated literally (as a dot) and not as a wildcard (as a wildcard, a dot means any one character).

The page has changed its address, how to redirect to a new page when requesting an old one (redirect)

Description:

Let's assume again that we recently renamed the foo.html page to bar.html and again want the old URL to work for backwards compatibility. But this time we want users of the old URL to get a hint of the new one, meaning their web browser's address bar should change.

We force an HTTP redirect to the new URL, which causes the page address in the browser to change and therefore what is shown to the user:

RewriteEngine on RewriteRule "^/foo\.html$" "bar.html" [R]

By the way, for simple redirect cases you can use the directive Redirect. This directive could not replace the first example, when we show the contents of another page without changing the address (without a redirect). WITH Redirect the second example would look like this:

Redirect "/foo.html" "/bar.html"

Redirection when changing domain

Description:

If the site has changed its domain, but has retained the same page structure. You want the old URLs to continue to work until users update their bookmarks.

You can use mod_rewrite to redirect these URLs to the new domain, but also consider using directives Redirect or RedirectMatch.

In the following examples, replace example.com with the address of the site where the redirect should be made.

# With mod_rewrite RewriteEngine on RewriteRule "^/docs/(.+)" "http://new.example.com/docs/$1"

The rule means to find queries that contain a string that starts with /docs/(symbol ^ means the beginning of the line, and /docs/ is a literal sequence of characters) which is then followed by anything (a dot means any character, and a plus sign means one or more times). The parentheses form a backlink. Those. what matches the expression in parentheses can be used later by referencing it with $1 .

In the rewrite line http://new.example.com/docs/ is the literal part, and $1 - this is what coincided with the part of the expression in brackets, i.e. back link to (.+) .

Thus, if a request was made to http://another.com/docs/best, a redirect to http://new.example.com/docs/best will be made.

# With RedirectMatch RedirectMatch "^/docs/(.*)" "http://new.example.com/docs/$1" # With Redirect Redirect "/docs/" "http://new.example.com/docs /"

Directives Redirect And RedirectMatch should be “easier” for the server, but complex cases cannot always be described without using mod_rewrite.

Simple redirect to a new site

If the site changed its domain and did not maintain the page structure, i.e. if you need to redirect all requests to a new site (for example, to its main page), then this is done like this:

RewriteEngine on RewriteRule ^ https://newsite.ru

As a result, regardless of the page requested, all requests will be forwarded to the home page of the other domain. Replace https://newsite.ru with the site where you are redirecting requests.

How to forward all requests from one directory to another

Alias ​​for a single directory:

RewriteEngine On RewriteRule ^source-directory/(.*) /target-directory/$1

All calls to the contents of the source-directory will be redirected to the contents of the target-directory.

Use URLs without .php file extensions

This snippet allows you to use a URL without a PHP extension, for example example.com/users instead of example.com/users.php.

RewriteEngine On RewriteCond %(SCRIPT_FILENAME) !-d RewriteRule ^([^.]+)$ $1.php

Generic Error Document for resources not found (404 Not Found error)

The following rule prints the file you specify if a 404 Not Found error occurs. Please note that you yourself need to specify the correct HTTP 404 response code in the response headers (in PHP code, for example).

RewriteEngine On RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule ^ /dir/error.php

If this rewrite rule causes a server error, replace the flag with . The flag works better, but is supported by Apache 2.4 and not supported by Apache 2.2.

Instead of /dir/error.php you need to specify the path to the file that you want to show in case of an error 404 (file not found).

From statics to dynamics

Description:

How can we transform a static page foo.html into a dynamic variant foo.cgi in a seamless manner, i.e. without notifying the browser/user.

We simply rewrite the URL into a CGI script and force the handler to be a CGI script so that it runs as a CGI program. Thus, a request to /~quux/foo.html will internally result in a call to /~quux/foo.cgi.

RewriteEngine on RewriteBase "/~quux/" RewriteRule "^foo\.html$" "foo.cgi"

Backward compatibility for file extension changes

Description:

How can we make URLs (virtually still existing) backwards compatible after migrating document.YYYY to document.XXXX, for example, after migrating a number of .html files to .php?

We rewrite the name to its base name and check for a file with the new extension. If it exists we take it, otherwise the URL is used as is.

# a set of rules for backwards compatibility # to rewrite document.html to document.php # only when document.php exists RewriteEngine on RewriteBase "/var/www/htdocs" RewriteCond "$1.php" -f RewriteCond "$1.html" !-f RewriteRule "^(.*).html$" "$1.php"

Discussion

This example takes advantage of an often-overlooked mod_rewrite feature that arises from the order in which the ruleset is executed. Specifically, mod_rewrite evaluates the left side of the RewriteRule (Search Pattern) before evaluating the RewriteCond directives. Therefore, $1 is already defined by the time the RewriteCond directives are evaluated. This allows us to check for the presence of a source (document.html) and a target (document.php) file using the same base filename.

This set of rules is intended for use in the context of directories (in the block or in the .htaccess file) so that the -f checks look at the directory at the correct path. You may need to set the RewriteBase directive to specify the directory base you are working in.

Replacing images with WebP

If WebP images are supported, and an image with the file extension .webp is found in the same location where a jpg/png image is located on the server, then the WebP image will be sent instead.

RewriteEngine On RewriteCond %(HTTP_ACCEPT) image/webp RewriteCond %(DOCUMENT_ROOT)/$1.webp -f RewriteRule (.+)\.(jpe?g|png)$ $1.webp

Canonical hostnames and URLs. HTTPS

The same page can be accessed in different ways. For example, you can open the site's home page using any of the following methods:

  • http://www.yoursite.com/
  • http://yoursite.com/
  • http://www.yoursite.com
  • http://yoursite.com
  • http://www.yoursite.com/index.php
  • http://yoursite.com/index.php
  • http://yoursite.com/?

There may be even more options if the site is available on both HTTP and HTTPS. Also, variations may arise due to various linking errors, in which the page continues to open. For example:

  • http://www.yoursite.com//index.php

Although most people understand that all these URLs are the same thing, from a technical point of view they are not. For the web server these are different URLs. And if they are open, search engines can index them.

Search engines have become much more advanced, but you shouldn't rely on them alone to combat duplicate pages. In addition, this can cause confusion in the analytics (when for each of the listed examples, income or traffic is considered separately, although this is the same page).

Therefore, the webmaster should take care of the canonical URL. In fact, it makes no difference which form of URL you choose to be canonical. The main thing is to choose one thing and stick to it.

How to redirect from HTTP to HTTPS

Remember that to use the HTTPS protocol it is not enough just to make a redirect; the web server must also be configured. That is, you must obtain certificates and specify them in the host settings. Also, the web server must be configured to listen on port 443. If this is all ready, then to redirect to HTTPS, to the file .htaccess add the lines:

RewriteEngine on RewriteCond %(HTTPS) !on RewriteRule ^ https://%(HTTP_HOST)%(REQUEST_URI)

In this example the variable %(HTTPS) contains on, if the site uses HTTPS and contains off, if HTTP is used. Thus, the page address is rewritten only if it is accessed via HTTP.

IN RewriteRule used as a search pattern ^ – character of the beginning of a line. Those. All rows fall under this condition. The redirect target is specified using a literal string https:// and two environment variables %(HTTP_HOST) And %(REQUEST_URI).

Strict-Transport-Security: max-age=31536000; includeSubDomains

How to redirect from HTTP to HTTPS all pages except some

Let's assume that we need to transfer all pages to HTTPS except those located in the folder /.well-known/, then the following construction is used:

RewriteEngine on RewriteCond %(HTTPS) !on RewriteCond %(REQUEST_URI) !^/.well-known/ RewriteRule ^ https://%(HTTP_HOST)%(REQUEST_URI)

Replace /.well-known/ to the desired folder or page address.

If you need to exclude several pages or directories, then create a regular expression with an alternative choice, i.e. using a pipe ( | ). For example, you need to enable redirection to HTTPS for all pages except those in the /.well-known/ folder, in the /test/ folder, and the /stay-away.php file:

RewriteEngine on RewriteCond %(HTTPS) !on RewriteCond %(REQUEST_URI) !^(/.well-known/|/test/|/stay-away.php) RewriteRule ^ https://%(HTTP_HOST)%(REQUEST_URI)

How to redirect from HTTP to HTTPS only some pages

If you only need to redirect individual pages from HTTP to HTTPS, then the examples shown earlier will work. The only change needed is to remove the exclamation point ( ! ), which serves to deny a match.

To configure a redirect to HTTPS only for the /.well-known/ folder

RewriteEngine on RewriteCond %(HTTPS) !on RewriteCond %(REQUEST_URI) ^/.well-known/ RewriteRule ^ https://%(HTTP_HOST)%(REQUEST_URI)

To configure a redirect to HTTPS only for the /.well-known/ folder, the /test/ folder, and the /stay-away.php file:

RewriteEngine on RewriteCond %(HTTPS) !on RewriteCond %(REQUEST_URI) ^(/.well-known/|/test/|/stay-away.php) RewriteRule ^ https://%(HTTP_HOST)%(REQUEST_URI)

Force HTTPS behind a proxy

Useful if you have a proxy in front of your server that disables TLS.

RewriteCond %(HTTP:X-Forwarded-Proto) !https RewriteRule (.*) https://%(HTTP_HOST)%(REQUEST_URI)

Always use WWW before the domain name

If you want the domain name to always be preceded by www, then use the following rules:

RewriteEngine on RewriteCond %(HTTP_HOST) ^example\.com RewriteRule ^(.*)$ http://www.example.com/$1

Please note that example.com needs to be replaced with the domain of your site, instead of the protocol http:// may be specified https://, and in the line ^example\.com The slash before the dot is not accidental - this line is a regular expression, so that the dot is treated not as a wildcard character, but as a literal dot, a slash is used.

Always use WWW before the domain name - universal option

This option is suitable without changes for any sites: you do not need to specify the host name (domain name), and you also do not need to indicate whether the HTTP or HTTPS protocol is used. Those. this is a more versatile option.

RewriteEngine On RewriteCond %(HTTP_HOST) !="" RewriteCond %(HTTP_HOST) !^www\. RewriteCond %(HTTPS)s ^on(s)| RewriteRule ^ http%1://www.%(HTTP_HOST)%(REQUEST_URI)

The first condition checks whether the value is Host empty (in case of HTTP/1.0). The second one checks if it starts Host on www..

Please note RewriteCond %(HTTPS)s ^on(s)|. A rather clever technique is used here. As mentioned just above, the environment variable %(HTTPS) contains on, if the site uses the protocol HTTPS, and contains off, if used HTTP. Added literal letter to environment variable s, as a result, the line is checked %(HTTPS)s, which, depending on whether HTTPS or not, may come down to ons or offs. This string is compared with a regular expression ^on(s)|, Where ^ is the beginning of a line character. Trumpet symbol ( | ) indicates that any alternative will do, either before or after this symbol. This character is preceded by the line on(s), and then - nothing. The empty string matches any string being compared. Based on this, the result RewriteCond will always come down to the truth. But depending on which part of the regex matched: on(s) or empty string, the backlink will be " s"or will be an empty string. The backlink is specified by brackets containing the letter s.

As a result http%1 at RewriteRule will come down to https or to http.

Thus, this rule is suitable for any site; you do not need to register your domain in it, as you need to do in the previous one. You also don't need to worry about the site's protocol.

Never use WWW before a domain name

If you no need so that there are letters in front of the domain in the browser line www, then use the following rule:

RewriteEngine on RewriteCond %(HTTP_HOST) ^www\.example\.com RewriteRule ^(.*)$ http://example.com/$1

In it, replace http://example.com with your domain name. Also pay attention to the protocol. The second line uses slashes to ensure that periods in the regular expression are treated as literal characters (rather than wildcards).

Never use WWW before a domain name - a universal option

If you need to get rid of www in the address bar of the browser, then the following rule will do this, redirect the request to a similar address, but without www:

RewriteEngine on RewriteCond %(HTTP_HOST) ^www\. RewriteCond %(HTTPS)s ^on(s)|off RewriteCond http%1://%(HTTP_HOST) ^(https?://)(www\.)?(.+)$ RewriteRule ^ %1%3% (REQUEST_URI)

In this set of conditions and rules, you do not need to specify your domain - the design is universal for any site, and is also suitable for sites on HTTP and HTTPS.

Force canonical name with HTTPS and www

If your site runs over HTTPS and you have chosen to use www before the domain name as the canonical name, then any of the following rules will help you. There is no fundamental difference between them; if one of them is not suitable for your conditions, just try another.

First way:

RewriteEngine On RewriteCond %(HTTPS) off RewriteRule .* https://%(HTTP_HOST)%(REQUEST_URI) RewriteCond %(HTTP_HOST) !^www\. RewriteRule .* https://www.%(HTTP_HOST)%(REQUEST_URI)

In this example there are two rewrite rules. The first one redirects to HTTPS. The second rule rewrites any request with an invalid domain to use www. The flag means a match regardless of case.

Second way:

RewriteEngine On RewriteCond %(HTTP_HOST) (?!^www\.)^(.+)$ RewriteCond %(HTTPS) off RewriteRule ^ https://www.%1%(REQUEST_URI)

Third way:

RewriteEngine on RewriteCond %(HTTP_HOST) !^$ RewriteCond %(HTTP_HOST) !^www\. RewriteCond %(HTTPS)s ^on(s)| RewriteRule ^ http%1://www.%(HTTP_HOST)%(REQUEST_URI) RewriteCond %(HTTPS) off RewriteRule ^ https://%(HTTP_HOST)%(REQUEST_URI)

Fourth method (replace domain.ru with your domain):

RewriteEngine On RewriteCond %(HTTP_HOST) !^www\.domain\.ru RewriteRule ^(.*)$ https://www.domain.ru/$1 RewriteCond %(SERVER_PORT) 80 RewriteRule ^(.*)$ https:/ /www.domain.ru/$1

Canonical view with HTTPS and without www

If your site runs on HTTPS but you don't want to see www in your browser's address bar before the domain name, then use:

RewriteEngine on RewriteCond %(HTTPS) !on RewriteRule ^ https://%(HTTP_HOST)%(REQUEST_URI) RewriteCond %(HTTP_HOST) ^www\. RewriteCond %(HTTPS)s ^on(s)|off RewriteCond http%1://%(HTTP_HOST) ^(https?://)(www\.)?(.+)$ RewriteRule ^ %1%3% (REQUEST_URI)

Forced SSL and www for the main domain, forced SSL without www for all subdomains (except local ones)

RewriteEngine On # for subdomains: forced ssl and without www RewriteCond %(HTTP_HOST) !\.local$ RewriteCond %(HTTPS) !=on RewriteCond %(HTTP_HOST) !^(www\.)?domain\.ru$ RewriteCond %( HTTP_HOST) ^(?:www\.|)(.*)$ RewriteRule ^.*$ https://%1%(REQUEST_URI) # for main domains: force ssl without www RewriteCond %(HTTP_HOST) !\.local$ RewriteCond %(HTTPS) !=on RewriteCond %(HTTP_HOST) ^domain\.ru$ RewriteRule ^.*$ https://www.domain.ru%(REQUEST_URI)

Replace domain.ru with your domain name.

Force adding a trailing slash to the site address

If you need to add a trailing slash to the URL (if it is missing), then use this rewriting rule:

RewriteEngine on RewriteCond %(REQUEST_FILENAME) !-f RewriteRule ^(.*[^/])$ /$1/

Removing a trailing slash

This snippet will redirect paths ending in slashes to similar paths without a trailing slash (except for actual directories), for example http://www.example.com/blog/ to http://www.example.com/blog. This is important for SEO as it is recommended to have a canonical URL for each page.

If you need to remove the trailing slash from the URL, then use:

RewriteEngine on RewriteCond %(REQUEST_FILENAME) !-d RewriteRule ^(.*)/$ /$1

Removing trailing slashes from arbitrary paths

Removing trailing slashes from URLs for websites hosted in a directory (like example.org/blog/):

RewriteEngine on RewriteCond %(REQUEST_FILENAME) !-d RewriteCond %(REQUEST_URI) (.+)/$ RewriteRule ^ %1

Removing extra slashes in a URL

For example, the page /catalog///stranica.html is accessible and opens. To avoid this situation and not create an endless number of duplicates, you should write the following redirect:

RewriteEngine on RewriteBase / RewriteCond %(HTTP_HOST) !="" RewriteCond %(THE_REQUEST) ^+\s//+(.*)\sHTTP/+$ RewriteCond %(THE_REQUEST) ^+\s(.*)//+ \sHTTP/+$ RewriteRule .* http://%(HTTP_HOST)/%1 RewriteCond %(REQUEST_URI) ^(.*)//(.*)$ RewriteRule . %1/%2

Here, two rules are used in sequence to remove multiple slashes from any part of the URL: beginning, middle, end.

Htaccess is an additional Apache configuration file that allows you to configure the web server on a per-directory basis without affecting global Apache settings. Local analogy httpd.conf. Typically he is responsible for redirects and directory access control.

The name begins with a dot. We can say that this is an untitled file with the htaccess extension.

The .htaccess settings affect the directory in which it is located and all child directories. Create a file and place it in the directory you need. For example, to the root of the project.

Now you need to fill it. Let's see what .htaccess can do, but first, let's study an example of a simple redirect.

mod_rewrite and redirects

Make sure that in your Apache config file httpd.conf activated mod_rewrite. That is, the corresponding line is uncommented:

LoadModule rewrite_module modules/mod_rewrite.so

Or, if you don't want to open the file in a text editor, you can use the command in the terminal:

Sudo a2enmod rewrite

mod_rewrite is an Apache module designed to rewrite URLs. Let's look at an example of how it works. Let's say the user enters the following address:

Using mod_rewrite you can send content from a different URL, like this:

Http://www.example.com/public/src/view/page.html

Why do we need this? It’s easy to guess that writing the full path to a page is long and simply inconvenient. Site visitors do not need to think about the internal structure of the site - what is important for them is to get to the page they are looking for as quickly as possible.

In the address bar the user will still see what he entered:

http://www.example.com/page.html

This is an example of the simplest redirect.

Straight to practice

Let's analyze the configuration file used in one of our projects. This way we will understand which line to edit if problems arise.

Php_value short_open_tag 1 php_value upload_max_filesize 10M php_value post_max_size 10M RewriteEngine On RewriteBase / RewriteRule ^(application|modules|system) - RewriteCond %(REQUEST_FILENAME) !-f RewriteCond %(REQUEST_FILENAME) !-d RewriteRule .* index.php/$0

  • php_value setting string and numeric values
  • php_flag sets boolean values ​​(yes/no)

General directive syntax

Php_value/php_flag directive_name php flag/value

Directive short_open_tag allows the use of a short syntax for formatting PHP code:

Php_value short_open_tag 1

upload_max_filesize determines the maximum size of an uploaded file.

Php_value upload_max_filesize 10M

A post_max_size sets the maximum allowed size of data sent using the POST method.

Php_value post_max_size 10M

RewriteEngine

Turns the mechanism on/off mod_rewrite.

RewriteEngine On

RewriteRule

RewriteRule simply transforms the string according to regular expressions.

Syntax: RewriteRule regular_expression

# Input RewriteRule "index.php" RewriteRule ^index.php main.php [R] # Output: "index.php" -> "main.php"

We converted index.php to main.php and performed the redirect.

Important: RewriteRule usually takes two arguments: What needs to be replaced and for what needs to be replaced. If we don’t need to perform the replacement, we can write it in the form:

The "-" symbol means "do not convert"

RewriteBase

After all RewriteRules, RewriteBase comes into force. If the resulting query after transformations is relative and different from the original one, RewriteBase will restore it, making it absolute. RewriteBase will simply append itself to the request on the left. Because the RewriteBase value is the path from the site root to .htaccess. In our case, .htaccess is located right in the root, so:

Syntax: RewriteBase URL-path-from-.htaccess-file-to-site-root

For example:

# .htaccess is located in /dir/ # Path from the site root to .htaccess /dir/ RewriteBase /dir/ # Request http://example.com/dir/logo.gif # The RewriteRule input is "logo.gif" RewriteRule ^ logo.gif$ logo-orange.gif # After RewriteRule: "logo.gif" -> "logo-orange.gif" # After RewriteBase: "logo-orange.gif" -> "/dir/logo-orange.gif"

Regular expressions

Regular Expressions, which you may encounter in .htaccess.

Symbol Meaning Example
. Any one symbol c.t is cat, cot, cut, etc.
+ One or more identical characters a+ is a, aa, aaa, etc.
* Zero or several identical characters a* works the same as a+ but in the case of a* the empty string will satisfy the condition
? Match optional colou?r will suit both color and colour.
^ The symbol from which begins line ^a matches a string that starts with a
$ The symbol that ends line a$ matches a string that ends with a .
() Finds and remembers matches groups characters.

Can also be used for Back-Reference(see example)

(ab)+ will satisfy ababab

Back-Reference example:

RewriteRule ^/ (+) /(.*) $ /home?page= $1 &id= $2

/album/123 → /home?page= album&id= 123

One of possible characters ct is suitable cut , cot or cat.

More regular expressions

Flags

Syntax: RewriteRule regular_expression [flag1,flag2,flag3]

Flag Description
[F] Forbidden- returns error 403 Forbidden.
[L] Last- stop the transformation process at this point and do not apply any more transformation rules.
Query String Append- this flag indicates to the conversion mechanism to add, not replace,query strings from URL to existing,in the substitution string.
PassThrough- stops the conversion process and passes the resulting new link further down the chain.
[R] Redirect- stops the conversion process and returns the result to the client browser as a redirect to a new page.
[S] Skip- skips the next rule if the current rule is triggered. You can specify the number of subsequent rules to ignore.