– Hoping this is the right forum for this –
I have been designing a website for someone over the past month and when it came time to upload it to their site, I was hit with a realization; a realization that they never told me that their host was going to be on an IIS server. Even though they requested a PHP website. So I’m stuck scrambling to learn IIS web.config.
Useful information:
I used This Online .htaccess to Web.Config converter to convert the .htaccess files to web.config at first.
Then I gave in and installed Windows Server 2008 in a VM with URL Rewrite module installed and enabled.
The host my ‘client’ is using is snaphost, with dotNetPanel and is running under shared hosting.
I’ve been wracking my brain over this for the past 2 weeks. Consulted over 50 pages of GOOGLE results as well as yahoo and bing (the latter being the two that I dread the most being that I am Anti-Microsoft).
There are 3 main .htaccess files:
- First is in the document root /.
- Second is in the public directory /public
- Third file is in the /admin directory.
My directory structure looks like this:
/
admin
.htaccess
library
public
.htaccess
.htaccess
Everything works when you view the site at clientsite.dev it works.
When you view a clean URL, such as clientsite.dev/contact, it provides me with a 404 error.(no 404 error after i merge the web.configs together.)
This is the additional information I receive when I view it locally within my Windows 2008 Virtual Machine.
[B]Detailed Error Information [/B]
- [B]Module IIS[/B] Web Core
- [B]Notification[/B] MapRequestHandler
- [B]Handler[/B] StaticFile
- [B]Error Code[/B] 0x80070002
- [B]Requested URL[/B] http://clientsite.dev:80/public/contact
- [B]Physical Path[/B] C:\\inetpub\\clientsite\\wwwroot\\public\\contact
- [B]Logon Method[/B] Anonymous
- [B]Logon Use[/B]r Anonymous
[EDIT]
Merged /public/web.config with /web.config and the 404 is gone and pages display properly. Still not how i’d like it and when I do something like POST a form, or log in, I get an “OBJECT MOVED This document may be found <a href=”“>here</a>”. When that message appears, the rest of the page will not render.
The Requested path should be C:\inetpub\clientsite\wwwroot\public\index.php?pagename=contact
The url before rewriting looks like mysite.com/public/index.php?pagename=contact
After rerouting/ to public/ the url will look like mysite.com/index.php?pagename=contact
Where I’m having the issues is when i want the url to look like mysite.com/contact or mysite.com/admin/settings or, thinking ahead, mysite.com/somedir/somefile (which in my original .htaccess files, would work.)
Personally, I would like each directory to have its own .htaccess (like it does now) and its own web.config. That way the rules in the web.config within root “/” does not get affected later on if I decide to automate the web.config creation.
Here are my three .htaccess files
RewriteEngine On
Options +FollowSymLinks
#if a match for asset is found, do nothing
RewriteRule ^library/ - [F]
RewriteRule ^plugins/ - [F]
RewriteRule ^admin/ - [L]
RewriteRule ^\\.htaccess$ - [F]
RewriteCond %{REQUEST_URI} =""
RewriteRule ^.*$ /public/index.php [NC,L]
RewriteCond %{REQUEST_URI} !^/public/.*$
RewriteRule ^(.*)$ /public/$1
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^.*$ - [NC,L]
RewriteRule ^public/.*$ /public/index.php [NC,L]
RewriteEngine On
IndexIgnore *
# don't show any files in the folder\\
ErrorDocument 403 /library/error.php?code=403
ErrorDocument 404 /library/error.php?code=404
RewriteRule ^(community) - [F]
# #get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^erttraining\\.clients\\.thunderhawksolutions\\.com$ [NC]
RewriteRule ^(.+)/$ http://erttraining.clients.thunderhawksolutions.com/$1 [R=301,L]
############
#CMS RULES #
############
RewriteRule ^registration/register/([0-9]+) index.php?pagename=registration&action=register&cid=$1 [QSA,L]
RewriteRule ^registration/register index.php?pagename=registration&action=register [QSA,L]
# News
RewriteRule ^news/(.*) index.php?pagename=article&articleid=$1 [QSA,L]
RewriteRule ^news/(.*)/page-([0-9]+) index.php?pagename=article&articleid=$1&page=$2 [QSA,L]
RewriteRule ^news index.php?pagename=news&articleid=$1&page=$2 [QSA,L]
# Login
RewriteRule ^login(/)?$ index.php?pagename=login&code=0 [QSA,L]
RewriteRule ^logout(/)?$ index.php?pagename=login&code=1 [QSA,L]
# Admin Rules
RewriteRule ^admin-reg/jsondata.php admin-scripts/jsondata.php [QSA,L]
RewriteRule ^admin-reg/(create|remove|manage|update|view)/([^/+].*)/([^/+].*)(/)? index.php?pagename=admin-reg&action=$2&option=$1§ion=$3 [QSA,L]
RewriteRule ^admin-reg/(create|remove|manage|update|view)/([^+].*)(/)? index.php?pagename=admin-reg&action=$2&option=$1 [QSA,L]
RewriteRule ^inline-register/([^/+].*) inline-register.php?courseid=$1 [QSA,L]
############
#CMS RULES #
############
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) index.php?pagename=$1 [QSA,L]
And then there is the admin section:
RewriteEngine On
DirectorySlash on
RewriteBase /admin
DirectoryIndex index.php
RewriteRule ^$ index.php?pagename=home [L]
RewriteRule ^images - [L]
RewriteRule ^css - [L]
RewriteRule ^js - [L]
RewriteRule ^scripts - [L]
RewriteRule ^db-backups - [L]
RewriteRule ^multiupload - [L]
RewriteRule ^server - [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !^(images|css|js|scripts)
RewriteRule ^(.*)/(.*)/(.*)(/)? index.php?pagename=$1&action=$2&option=$3 [QSA,L]
RewriteRule ^(.*)/(.*)(/)? index.php?pagename=$1&action=$2 [QSA,L]
RewriteRule ^(.*)$ index.php?pagename=$1 [QSA,L]
This is the resulting web.config file, minus the admin rules (didn’t even get that far with public to add them in):
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="Imported Rule 1-1">
<match url="^library/" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
</rule>
<rule name="Imported Rule 2-1">
<match url="^plugins/" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" />
</rule>
<rule name="Imported Rule 3-1" stopProcessing="true">
<match url="^admin/" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="None" />
</rule>
<rule name="blockAccessToPublic" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{URL}" pattern="/public/*" />
</conditions>
<action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." />
</rule>
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^([^/]+)/?$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="public/index.php?pagename={R:1}" />
</rule>
<!-- PUBLIC URL REWRITES -->
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^registration/register/([0-9]+)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=registration&action=register&cid={R:1}" appendQueryString="true" />
</rule>
<rule name="Imported Rule 2" stopProcessing="true">
<match url="^registration/register" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=registration&action=register" appendQueryString="true" />
</rule>
<rule name="Imported Rule 3" stopProcessing="true">
<match url="^news/(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=article&articleid={R:1}" appendQueryString="true" />
</rule>
<rule name="Imported Rule 4" stopProcessing="true">
<match url="^news/(.*)/page-([0-9]+)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=article&articleid={R:1}&page={R:2}" appendQueryString="true" />
</rule>
<rule name="Imported Rule 5" stopProcessing="true">
<match url="^news" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=news&articleid={R:1}&page={R:2}" appendQueryString="true" />
</rule>
<rule name="Imported Rule 6" stopProcessing="true">
<match url="^login(/)?$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=login&code=0" appendQueryString="true" />
</rule>
<rule name="Imported Rule 7" stopProcessing="true">
<match url="^logout(/)?$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=login&code=1" appendQueryString="true" />
</rule>
<rule name="Imported Rule 8" stopProcessing="true">
<match url="^admin-reg/jsondata.php" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="admin-scripts/jsondata.php" appendQueryString="true" />
</rule>
<rule name="Imported Rule 9" stopProcessing="true">
<match url="^admin-reg/(create|remove|manage|update|view)/([^/+].*)/([^/+].*)(/)?" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=admin-reg&action={R:2}&option={R:1}&section={R:3}" appendQueryString="true" />
</rule>
<rule name="Imported Rule 10" stopProcessing="true">
<match url="^admin-reg/(create|remove|manage|update|view)/([^+].*)(/)?" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="index.php?pagename=admin-reg&action={R:2}&option={R:1}" appendQueryString="true" />
</rule>
<rule name="Imported Rule 11" stopProcessing="true">
<match url="^inline-register/([^/+].*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="inline-register.php?courseid={R:1}" appendQueryString="true" />
</rule>
<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
<match url="^public/index\\.php$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^pagename=([^=&]+)$" />
</conditions>
<action type="Redirect" url="{C:1}" appendQueryString="false" />
</rule>
<!-- PUBLIC URL REWRITES -->
<rule name="RewriteRequestsToPublic" stopProcessing="true">
<match url="^(.*)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="public/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
I am sorry that this is such a long posting but I was seriously not expecting it to be this difficult. I am in need of an immense assortment of help. Though, I think that if I were to solve this issue, I could probably cancel my sessions with a therapist and my room at a mental institution.
P.S: If anyone has any code optimization suggestions for my rewrite rules, that would hopefully also translate well into the web.config, please let me know.