We are excited to announce that the IIS.NET Forums are moving to the new Microsoft Q&A experience. Learn more >

Convert Drupal Boost Module Rules [Answered]RSS

14 replies

Last post Jun 19, 2012 02:10 PM by canadaka

  • Convert Drupal Boost Module Rules

    Oct 24, 2009 09:33 PM|mikeytown2|LINK

    Wondering if IIS7 can handle the required rules of the Boost module. I was at the Pacific Northwest Drupal Summit today & this is a concern of mine.

    URL Rewrite Module drupal Boost

  • Re: Convert Drupal Boost Module Rules

    Oct 26, 2009 01:15 PM|rlucero|LINK

    I just tried using the IIS URL Rewrite rules importer and it doesn't look like the flags that are used in the Boost rewrite rules are supported at this time. 

     Someone might know better, or a way to convert the rules to avoid using the unsupported flags.

  • Re: Convert Drupal Boost Module Rules

    Oct 26, 2009 06:05 PM|mikeytown2|LINK

     What does it have trouble with?

  • Re: Convert Drupal Boost Module Rules

    Oct 26, 2009 06:45 PM|ruslany|LINK

    The rewrite rules use the features that are not supported in URL Rewrite:

    The "-s" problem can be worked around by replacing it with "-f".

    The workaround for the other problem is not that trivial. If you do not plan to use gzip complression then you can remove the gzip related rules, replace the   "RewriteRule .* - [S=7]" to   "RewriteRule .* - [L]" and try importing again. If you need to use gzip specific rules, then I do not see a way to import those.

  • Re: Convert Drupal Boost Module Rules

    Oct 26, 2009 09:44 PM|mikeytown2|LINK

     Created thread for IIS 7 support, with rules that I think will work, If someone can test, that would be nice.

    http://drupal.org/node/615474

  • Re: Convert Drupal Boost Module Rules

    Apr 08, 2010 03:01 AM|canadaka|LINK

     There must be a way to get the Boost rules working with Gzip support using the IIS rewrite module. It would go along way to making IIS a viable hosting solution for drupal sites. Without this its a major disadvantage for any drupal site that gets any decent amount of traffic.

  • Re: Convert Drupal Boost Module Rules

    Apr 08, 2010 01:24 PM|ruslany|LINK

    Now that I think about this you might be able to get it to work. Instead of importing the original rule that is right before the GZIP rules try importing this:

    # Caching for anonymous users
    # Skip boost IF not get request OR uri has wrong dir OR cookie is set OR https request

    RewriteCond %{REQUEST_METHOD} !^(GET|HEAD)$ [OR]
    RewriteCond %{REQUEST_URI} (^/(admin|cache|misc|modules|sites|system|openid|themes|node/add))|(/(comment/reply|edit|user|user/(login|password|register))$) [OR]
    RewriteCond %{HTTP_COOKIE} DRUPAL_UID [OR]
    RewriteCond %{HTTPS} on
    RewriteRule .* - [L]

    This way the boost rules will not be executed if this rule was executed.

  • Re: Convert Drupal Boost Module Rules

    Apr 08, 2010 07:17 PM|canadaka|LINK

     Here is what i'm trying to import, I changed all the -s to -f and all the [S] to [L] and replaces the "# Caching for anonymous users" with the lines you pasted above.

    It does try to do the import, before changing the "S" stuff it wouldn't at all. But it is unable to import many of the rules because of the same reason. Unsupported flags: T

     Here is what i'm trying to import:

     

    # Protect files and directories from prying eyes.
    <FilesMatch "\.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl|svn-base)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template|all-wcprops|entries|format)$">
      Order allow,deny
    </FilesMatch>

    # Don't show directory listings for URLs which map to a directory.
    Options -Indexes

    # Follow symbolic links in this directory.
    Options +FollowSymLinks

    # Force simple error message for requests for non-existent favicon.ico.
    <Files favicon.ico>
      # There is no end quote below, for compatibility with Apache 1.3.
      ErrorDocument 404 "The requested file favicon.ico was not found.
    </Files>

    # Various rewrite rules.
    <IfModule mod_rewrite.c>
      RewriteEngine on
         
        ### BOOST START ###
      AddDefaultCharset utf-8
      <FilesMatch "(\.html|\.html\.gz|\.xml|\.xml\.gz)$">
        <IfModule mod_headers.c>
          Header set Expires "Sun, 19 Nov 1978 05:00:00 GMT"
          Header set Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
        </IfModule>
      </FilesMatch>
      <IfModule mod_mime.c>
        AddCharset utf-8 .html
        AddCharset utf-8 .xml
        AddCharset utf-8 .css
        AddCharset utf-8 .js
        AddEncoding gzip .gz
      </IfModule>
      <FilesMatch "(\.html|\.html\.gz)$">
        ForceType text/html
      </FilesMatch>
      <FilesMatch "(\.xml|\.xml\.gz)$">
        ForceType text/xml
      </FilesMatch>
      <FilesMatch "(\.js|\.js\.gz)$">
        ForceType text/javascript
      </FilesMatch>
      <FilesMatch "(\.css|\.css\.gz)$">
        ForceType text/css
      </FilesMatch>

      # Gzip Cookie Test
      RewriteRule boost-gzip-cookie-test\.html  cache/perm/boost-gzip-cookie-test\.html\.gz [L,T=text/html]

      # GZIP - Cached css & js files
      RewriteCond %{HTTP_COOKIE} !(boost-gzip)
      RewriteCond %{HTTP:Accept-encoding} !gzip
      RewriteRule .* - [L]
      RewriteCond %{DOCUMENT_ROOT}/cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.css\.gz -f
      RewriteRule .* cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.css\.gz [L,QSA,T=text/css]
      RewriteCond %{DOCUMENT_ROOT}/cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.js\.gz -f
      RewriteRule .* cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.js\.gz [L,QSA,T=text/javascript]

      # NORMAL - Cached css & js files
      RewriteCond %{DOCUMENT_ROOT}/cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.css -f
      RewriteRule .* cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.css [L,QSA,T=text/css]
      RewriteCond %{DOCUMENT_ROOT}/cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.js -f
      RewriteRule .* cache/perm/%{SERVER_NAME}%{REQUEST_URI}_\.js [L,QSA,T=text/javascript]

      # Caching for anonymous users
      # Skip boost IF not get request OR uri has wrong dir OR cookie is set OR request came from this server OR https request
      RewriteCond %{REQUEST_METHOD} !^(GET|HEAD)$ [OR]
      RewriteCond %{REQUEST_URI} (^/(admin|cache|misc|modules|sites|system|openid|themes|node/add))|(/(comment/reply|edit|user|user/(login|password|register))$) [OR]
      RewriteCond %{HTTP_COOKIE} DRUPAL_UID [OR]
      RewriteCond %{HTTPS} on
      RewriteRule .* - [L]

      # GZIP
      RewriteCond %{HTTP_COOKIE} !(boost-gzip)
      RewriteCond %{HTTP:Accept-encoding} !gzip
      RewriteRule .* - [L]
      RewriteCond %{DOCUMENT_ROOT}/cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.html\.gz -f
      RewriteRule .* cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.html\.gz [L,T=text/html]
      RewriteCond %{DOCUMENT_ROOT}/cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.xml\.gz -f
      RewriteRule .* cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.xml\.gz [L,T=text/xml]

      # NORMAL
      RewriteCond %{DOCUMENT_ROOT}/cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.html -f
      RewriteRule .* cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.html [L,T=text/html]
      RewriteCond %{DOCUMENT_ROOT}/cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.xml -f
      RewriteRule .* cache/normal/%{SERVER_NAME}%{REQUEST_URI}_%{QUERY_STRING}\.xml [L,T=text/xml]

      ### BOOST END ### 
     
     
     
      # Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_URI} !=/favicon.ico
      RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] 
     
    </IfModule>
     

  • Re: Convert Drupal Boost Module Rules

    Apr 09, 2010 03:52 PM|ruslany|LINK

    I can think of two options:

    1. Remove the T=text/html flag from the rules, then import the rules and then add logic to the rules to set the server variable CONTENT_TYPE as per these instructions: http://learn.iis.net/page.aspx/686/setting-http-request-headers-and-iis-server-variables/

    2. A simpler option is to use IIS Static Compression. It is enabled by default. Try using WFetch and make requests to the content with the Accept-Encoding header set and then see if the responses are already compressed.

  • Re: Convert Drupal Boost Module Rules

    Apr 09, 2010 04:31 PM|canadaka|LINK

     I'm confused, I removed the T= flags and I'm able to import the rules. So now I need to add the mime type flags in MS URL Rewrite format. I'm guessing in the GUI that this would go under "server variables"?

    I don't know what I put in there to change the mime or Content-Type.

     

  • Re: Convert Drupal Boost Module Rules

    Apr 09, 2010 04:50 PM|canadaka|LINK

    I think i figured it out, but the rules don't work. Trying to visit any rewritten URL just results in a blank page. If I remove all the boost related rules then the basic drupal "clean url" rules work, but soon as the boost rules are there nothing works.

    The odd thing is the rewritten URLs do work for unauthenticated users, but they are never served one of the boost cached files like they should.

     I'm not worring about the GZIp rules right now, first step is just getting the basic functionality working.

    Here is what i'm working with right now:

     

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <rewrite>
                <rules>
                    <rule name="Imported Rule 13" stopProcessing="true">
                        <match url=".*" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAll">
                            <add input="{DOCUMENT_ROOT}/cache/perm/{SERVER_NAME}{URL}_\.css" matchType="IsFile" />
                        </conditions>
                        <action type="Rewrite" url="cache/perm/{SERVER_NAME}{URL}_\.css" appendQueryString="true" />
                        <serverVariables>
                            <set name="CONTENT_TYPE" value="text/css" />
                        </serverVariables>
                    </rule>
                    <rule name="Imported Rule 14" stopProcessing="true">
                        <match url=".*" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAll">
                            <add input="{DOCUMENT_ROOT}/cache/perm/{SERVER_NAME}{URL}_\.js" matchType="IsFile" />
                        </conditions>
                        <action type="Rewrite" url="cache/perm/{SERVER_NAME}{URL}_\.js" appendQueryString="true" />
                        <serverVariables>
                            <set name="text/javascript" value="text/javascript" />
                        </serverVariables>
                    </rule>
                    <rule name="Imported Rule 15" stopProcessing="true">
                        <match url=".*" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAny">
                            <add input="{REQUEST_METHOD}" pattern="^(GET|HEAD)$" ignoreCase="false" negate="true" />
                            <add input="{URL}" pattern="(^/(admin|cache|misc|modules|sites|system|openid|themes|node/add))|(/(comment/reply|edit|user|user/(login|password|register))$)" ignoreCase="false" />
                            <add input="{HTTP_COOKIE}" pattern="DRUPAL_UID" ignoreCase="false" />
                            <add input="{HTTPS}" pattern="on" ignoreCase="false" />
                        </conditions>
                        <action type="None" />
                    </rule>
                    <rule name="Imported Rule 16" stopProcessing="true">
                        <match url=".*" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAll">
                            <add input="{DOCUMENT_ROOT}/cache/normal/{SERVER_NAME}{URL}_{QUERY_STRING}\.html" matchType="IsFile" />
                        </conditions>
                        <action type="Rewrite" url="cache/normal/{SERVER_NAME}{URL}_{QUERY_STRING}\.html" />
                        <serverVariables>
                            <set name="CONTENT_TYPE" value="text/html" />
                        </serverVariables>
                    </rule>
                    <rule name="Imported Rule 17" stopProcessing="true">
                        <match url=".*" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAll">
                            <add input="{DOCUMENT_ROOT}/cache/normal/{SERVER_NAME}{URL}_{QUERY_STRING}\.xml" matchType="IsFile" />
                        </conditions>
                        <action type="Rewrite" url="cache/normal/{SERVER_NAME}{URL}_{QUERY_STRING}\.xml" />
                        <serverVariables>
                            <set name="CONTENT_TYPE" value="text/xml" />
                        </serverVariables>
                    </rule>
                   
                   
                   
                    <rule name="Imported Rule 18" stopProcessing="true">
                        <match url="^(.*)$" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAll">
                            <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                            <add input="{URL}" pattern="^/favicon.ico$" ignoreCase="false" negate="true" />
                        </conditions>
                        <action type="Rewrite" url="index.php?q={R:1}" appendQueryString="true" />
                    </rule>
                </rules>
            </rewrite>
        </system.webServer>
    </configuration>
     

     The top block of rules are all the Boost rules, which don't work, the bottom small block of rules are the basic clean url rules that do work only for unauthenticated users. If I remove all the boost rules the cleanURL rules work fine alone.

  • Re: Convert Drupal Boost Module Rules

    Apr 09, 2010 04:59 PM|ruslany|LINK

    Do the cached files exist in the cache directory. If yes, then enable the IIS Failed Request Tracing and see if the conditions in the boost rules build the file path correctly for the "isFile" check.

    The problem with unauthenticated users looks like is caused by the "Imported Rule 15", which stops processing if web request contains a cookie with DRUPAL_UID. I think this cookie is set for authenticated users.

  • Re: Convert Drupal Boost Module Rules

    Apr 09, 2010 05:27 PM|canadaka|LINK

    I emtpied the "cache" folder and then when i viewed a page cache files are indeed being created.

    So when logged in and I get the blank page this is the failed request:

     

    ModuleName IIS Web Core
    Notification 16
    HttpStatus 404
    HttpReason Not Found
    HttpSubStatus 0
    ErrorCode 2147942402
    ConfigExceptionInfo
    Notification MAP_REQUEST_HANDLER
    ErrorCode The system cannot find the file specified. (0x80070002)



    When i try as unauthenticated no failed request is written. This is the failed request settings i'm using:

    <tracing>
                <traceFailedRequests>
                    <add path="*">
                        <traceAreas>
                            <add provider="ASP" verbosity="Verbose" />
                            <add provider="ISAPI Extension" verbosity="Verbose" />
                            <add provider="WWW Server" areas="Authentication,Security,Filter,StaticFile,CGI,Compression,Cache,RequestNotifications,Module,FastCGI" verbosity="Verbose" />
                        </traceAreas>
                        <failureDefinitions statusCodes="401-999" />
                    </add>
                </traceFailedRequests>
            </tracing>

     

     

    So the problem with "Imported Rule 15" & DRUPAL_UID, any idea how this can be solved so the rules keep processing? Setting the stopProcessing="False" in that rule seems to allow the rest of the rules to run so then the cleanURL rules at the bottom work, but i'm not sure if that is the correct solution to that.

     

  • Re: Convert Drupal Boost Module Rules

    Apr 09, 2010 07:32 PM|ruslany|LINK

    You do not have "Rewrite" in the failed request tracing. You can use the instructions here: http://learn.iis.net/page.aspx/467/using-failed-request-tracing-to-trace-rewrite-rules/ 

    I did not realize that you were going to have other rules after the boost rules. In that case it works on mod_rewrite because the original rule that skips boost for authenticated requests uses S=7 which means that next 7 rules will be skipped, but anything after that will be processed. In URL Rewrite case there is no equivalent for that, so if you used stopProcessing but had any other rules after boost rules then those will not be processed.

    A possible way of working around this is to set some temporary server variable in the "Imported Rule 15" and then check for value of that server variable in all the boost rules, e.g.

          <rule name="Imported Rule 15" stopProcessing="true">
                        <match url=".*" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAny">
                            <add input="{REQUEST_METHOD}" pattern="^(GET|HEAD)$" ignoreCase="false" negate="true" />
                            <add input="{URL}" pattern="(^/(admin|cache|misc|modules|sites|system|openid|themes|node/add))|(/(comment/reply|edit|user|user/(login|password|register))$)" ignoreCase="false" />
                            <add input="{HTTP_COOKIE}" pattern="DRUPAL_UID" ignoreCase="false" />
                            <add input="{HTTPS}" pattern="on" ignoreCase="false" />
                        </conditions>
                        <serverVariables>
                           <set name="SKIP_BOOST" value="ON">
                        </serverVariables>
                        <action type="None" />
                    </rule>

    In every boost rule add this condition:

    <add input="{SKIP_BOOST}" pattern="ON" negate="true" />

  • Re: Convert Drupal Boost Module Rules

    Jun 19, 2012 02:10 PM|canadaka|LINK

    I never did get Drupal BOOST rules working with IIS Rewrite. I'm setting up a new server and migrating all my sites, I would love to not run ISAPI_Rewrite on the new server, but I have 3 Drupal 6 sites that require Boost. Boost works fine with Drupal 7 and IIS Rewrite.

    It took me some time to get Boost working with Drupal7 and turns out the same rule works with Drupal6. I'm just doing the basic HTML boost only, no css,js,gzip atm.

    <rule name="Boost html" stopProcessing="true">
                        <match url=".*" ignoreCase="false" />
                        <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                            <add input="{REQUEST_METHOD}" pattern="^GET$" ignoreCase="false" />
                            <add input="{URL}" pattern="(^(admin|cache|misc|modules|sites|system|themes|node/add))|(/(comment/reply|edit|user|user/(login|password|register))$)" ignoreCase="false" negate="true" />
                            <add input="{HTTP_COOKIE}" pattern="DRUPAL_UID" ignoreCase="false" negate="true" />
                            <add input="{HTTPS}" pattern="on" ignoreCase="false" negate="true" />
                            <add input="{DOCUMENT_ROOT}/cache/normal/{SERVER_NAME}{URL}_{QUERY_STRING}.html" matchType="IsFile" />
                        </conditions>
                        <serverVariables>
                            <set name="CONTENT_TYPE" value="text/html" />
                        </serverVariables>
                        <action type="Rewrite" url="cache/normal/{SERVER_NAME}{URL}_{QUERY_STRING}.html" />
                    </rule>

     

    One important step is you need to add "CONTENT_TYPE" to the "Allowed Server Variables" in IIS Rewrite or you will get Error 500 pages.