Jump to content

Convert .htaccess to web.config for Microsoft Azure Cloud


VirtuallyCreative
 Share

Recommended Posts

So being a LAMP server guy, recently at my work I've had to use Microsoft's' Azure Cloud to host some micro-apps of ours and I got to playing around with the platform. It's pretty nifty!

Naturally, I tried to install ProcessWire to play around with Web Apps + SQL App Service to see what I can get away with on the Free Tier (rather then spinning up a full LAMP VM machine which is the way Bitnami installs ProcessWire, costing $60CAD/mo).

Turns out installing ProcessWire is pretty smooth sailing except for one part: .htaccess mod_rewrite rules when you're not using Apache, as this is Azure Cloud so it's running PHP7 on IIS Microsoft Server and requires rewrite rules to be in a web.config file instead.

Doing some digging, I found tools that convert .htaccess over to web.config and was curious if anyone with experience using Microsoft .NET could see if the rules from the .htaccess actually do translate in the same way when written in XML for web.config?

Default ProcessWire v3.0 .htaccess file (comments, commented out commands removed):

Options -Indexes
Options +FollowSymLinks
ErrorDocument 404 /index.php
<Files favicon.ico>
  ErrorDocument 404 "The requested file favicon.ico was not found.
</Files>
<Files robots.txt>
  ErrorDocument 404 "The requested file robots.txt was not found.
</Files>
<IfModule mod_headers.c>
  Header always append X-Frame-Options SAMEORIGIN 
  Header set X-XSS-Protection "1; mode=block"
</IfModule>
<FilesMatch "\.(inc|info|info\.json|module|sh|sql)$|^\..*$|composer\.(json|lock)$">
  <IfModule mod_authz_core.c>
    Require all denied
  </IfModule>
  <IfModule !mod_authz_core.c>
    Order allow,deny
  </IfModule>
</FilesMatch>
<IfModule mod_php5.c>
  php_flag magic_quotes_gpc		off
  php_flag magic_quotes_sybase		off
  php_flag register_globals		off
</IfModule>
DirectoryIndex index.php index.html index.htm
<IfModule mod_rewrite.c>
  RewriteEngine On
  AddDefaultCharset UTF-8
  <IfModule mod_env.c>
    SetEnv HTTP_MOD_REWRITE On
  </IfModule>
  RewriteRule "(^|/)\.(?!well-known)" - [F]
  RewriteCond %{REQUEST_URI} !(^|/)site-[^/]+/install/[^/]+\.(jpg|jpeg|png|gif)$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)\.htaccess$ [NC,OR]
  RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets/(cache|logs|backups|sessions|config|install|tmp)($|/.*$) [OR]
  RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/install($|/.*$) [OR]
  RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets.*/-.+/.* [OR]
  RewriteCond %{REQUEST_URI} (^|/)(wire|site|site-[^/]+)/(config|index\.config|config-dev)\.php$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)(wire|site|site-[^/]+)/templates-admin($|/|/.*\.(php|html?|tpl|inc))$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/templates($|/|/.*\.(php|html?|tpl|inc))$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/assets($|/|/.*\.php)$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)wire/(core|modules)/.*\.(php|inc|tpl|module|info\.json)$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)(site|site-[^/]+)/modules/.*\.(php|inc|tpl|module|info\.json)$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)(COPYRIGHT|INSTALL|README|htaccess)\.(txt|md|textile)$ [OR]
  RewriteCond %{REQUEST_URI} (^|/)site-default/
  RewriteRule ^.*$ - [F,L]
  RewriteCond %{REQUEST_URI} "^/~?[-_.a-zA-Z0-9/]*$" [OR]
  RewriteCond %{REQUEST_FILENAME} !-f [OR]
  RewriteCond %{REQUEST_FILENAME} !-d [OR]
  RewriteCond %{REQUEST_FILENAME} !(favicon\.ico|robots\.txt) [OR]
  RewriteRule ^(.*)$ index.php?it=$1 [L,QSA]
</IfModule>

 

Converted web.config file:

<rewrite>
  <rules>
    <rule name="www_mysite_com:non-80">
      <match url="&quot;(^|/)\.(?!well-known)&quot;" ignoreCase="false" />
      <action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
    </rule>
    <rule name="www_mysite_com:80" stopProcessing="true">
      <match url="^.*$" ignoreCase="false" />
      <conditions logicalGrouping="MatchAny">
        <add input="{URL}" pattern="(^|/)site-[^/]+/install/[^/]+\.(jpg|jpeg|png|gif)$" ignoreCase="false" negate="true" />
        <add input="{URL}" pattern="(^|/)\.htaccess$" />
        <add input="{URL}" pattern="(^|/)(site|site-[^/]+)/assets/(cache|logs|backups|sessions|config|install|tmp)($|/.*$)" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(site|site-[^/]+)/install($|/.*$)" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(site|site-[^/]+)/assets.*/-.+/.*" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(wire|site|site-[^/]+)/(config|index\.config|config-dev)\.php$" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(wire|site|site-[^/]+)/templates-admin($|/|/.*\.(php|html?|tpl|inc))$" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(site|site-[^/]+)/templates($|/|/.*\.(php|html?|tpl|inc))$" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(site|site-[^/]+)/assets($|/|/.*\.php)$" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)wire/(core|modules)/.*\.(php|inc|tpl|module|info\.json)$" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(site|site-[^/]+)/modules/.*\.(php|inc|tpl|module|info\.json)$" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)(COPYRIGHT|INSTALL|README|htaccess)\.(txt|md|textile)$" ignoreCase="false" />
        <add input="{URL}" pattern="(^|/)site-default/" ignoreCase="false" />
      </conditions>
      <action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
    </rule>
    <rule name="www_mysite_com:80" stopProcessing="true">
      <match url="^(.*)$" ignoreCase="false" />
      <conditions logicalGrouping="MatchAny">
        <add input="{URL}" pattern="&quot;^/~?[-_.a-zA-Z0-9/]*$&quot;" ignoreCase="false" />
        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
        <add input="{REQUEST_FILENAME}" pattern="(favicon\.ico|robots\.txt)" ignoreCase="false" negate="true" />
      </conditions>
      <action type="Rewrite" url="index.php?it={R:1}" appendQueryString="true" />
    </rule>
  </rules>
</rewrite>
  • Like 1
Link to comment
Share on other sites

  • 1 month later...
1 hour ago, eelkenet said:

That's great, have you also tried to get ProCache running per chance? I had to deal with PW+ProCache+Azure last year and couldn't get it to work properly.

ProCache on IIS is not supported, as far as I know, but it should work with some additional rules. Since I don't have ProCache, I can't say for sure. As this is payed product I don't know if I'm allowed to post this rules here on forum. 

Link to comment
Share on other sites

  • 2 years later...

Hello, thanks for sharing, for everyone who came here like me and the proposal did not work for some reason, I invite you to read the instructions here:

It is also important that they use the following web.config file (which contains minor corrections to the code initially shared by @nikola).

 

I hope it helps you with something like me.


Regards!

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...