We're running into the nasty sporadic IE6 bug where gzip compression enabled on js and css files makes things go bad (see Can i gzip-compress all my html content(pages) for example).
Therefore, what seems to be the best way to deal with this would be to use the URL Rewrite Module in IIS7/7.5 to check for requests from < IE6 and serve them uncompressed as per http://sebduggan.com/posts/ie6-gzip-bug-solved-using-isapi-rewrite.
I want to use the IIS7 Url Rewrite Module
Only the IIS7 Url Rewrite Module 2.0 RC supports rewriting headers
But the following results in a 500 error for the affected resources:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="IE56 Do not gzip js and css" stopProcessing="true">
<match url="\.(css|js)" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="MSIE\ [56]" />
</conditions>
<action type="None" />
<serverVariables>
<set name="Accept-Encoding" value=".*" /> <!-- This is the problem line -->
</serverVariables>
</rule>
</rules>
</rewrite>
</system.webServer>
What to put in the Server Variable for Accept-Encoding? I've verified that this is the problem line (as everything else has been isolated and operates as required). I've tried everything I can think of and I'm beginning to think that there just isn't support for setting the Accept-Encoding header.
I've tried:
<set name="HTTP_ACCEPT_ENCODING" value=" " />
<set name="HTTP_ACCEPT_ENCODING" value=".*" />
<set name="HTTP_ACCEPT_ENCODING" value="0" />
Specifically, it results in a "HTTP/1.1 500 URL Rewrite Module Error."
Well, it turns out that for security reasons you need to explicitly allow whatever server variables you wish to modify in the applicationHost.config (see http://learn.iis.net/page.aspx/665/url-rewrite-module-20-configuration-reference#Allowed_Server_Variables_List).
Therefore, the following does the trick in the Web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="IE56 Do not gzip js and css" stopProcessing="false">
<match url="\.(css|js)" />
<conditions>
<add input="{HTTP_USER_AGENT}" pattern="MSIE\ [56]" />
</conditions>
<action type="None" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="0" />
</serverVariables>
</rule>
</rules>
</rewrite>
</system.webServer>
As long as the applicationHost.config has:
<location path="www.site.com">
<system.webServer>
<rewrite>
<allowedServerVariables>
<add name="HTTP_ACCEPT_ENCODING" />
</allowedServerVariables>
</rewrite>
</system.webServer>
</location>
See http://www.andornot.com/about/developerblog/2009/11/ie6-gzip-bug-solved-using-iis7s-url.aspx for a blog post detailing everything.
EDIT: Added official documentation link.
EDIT: Added link to blog post summarizing.
Related
I have a problem with Wordpress and running it behind a reverse proxy. I have localized the problem and it was the solution to the question posed here:
Modifying headers with IIS7 Application Request Routing
Before I applied the command in the accepted solution above, I was unable to visit any links on the website and got a too many redirects error. Turning on the option to preserve the original host header fixed those issues. But immediately after I was no longer able to edit individual pages, it would not load and return a ERR_CONNECTION_RESET error.
Since this happened right after I applied the command above I tested by turning it off again and now it works again. And predictably the other errors returned as well. So I am at an impasse here. Anyone know why the connection suddenly resets with this option turned on?
The URL that resets looks like this:
http://www.siteurl.com/wp-admin/post.php?post=19&action=edit
This is the web.config for the reverse proxy site:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://192.168.111.15:8080/{R:1}" />
<serverVariables>
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="[HTTP_ACCEPT_ENCODING]" />
<set name="HTTP_ACCEPT_ENCODING" value="eee" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml2">
<match filterByTags="A, Form, Img" pattern="^http(s)?://192.168.111.15:8080/(.*)" />
<action type="Rewrite" value="http{R:1}://www.siteurl.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml2">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
<add input="{HTTP_HOST}" pattern="siteurl.com" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
I just solved the problem! The answer was found here:
https://forums.iis.net/t/1210664.aspx
I raised the response buffer threshold (in Application Request Routing -> Server Proxy Settings) by a lot and the pages I had issues with started working at once. So it was an IIS related issue.
I hope this helps someone else as it has been a couple of hair pulling days for me!
I need to redirect a lot of URLs like the following
http://localhost/OmniService/foto/18443151-810079.jpg
so, in my web.config I set the following regular expression:
<rewrite>
<providers>
<provider name="DB" type="DbProvider, Microsoft.Web.Iis.Rewrite.Providers, Version=7.1.761.0, Culture=neutral, PublicKeyToken=0545b0627da60a5f">
<settings>
<add key="ConnectionString" value="Driver={SQL Server Native Client 10.0};Data Source=localhost\sqlexpress;Initial Catalog=RewriteDB;Integrated Security=True;Server=localhost;uid=sa;pwd=working2014" />
<add key="StoredProcedure" value="RewriteDB.dbo.GetRewrittenUrl" />
<add key="CacheMinutesInterval" value="0" />
</settings>
</provider>
</providers>
<rules>
<rule name="DbProviderTest" stopProcessing="true">
<match url="(OmniService/foto/([0-9]+)-([0-9]+).jpg)" />
<!--<conditions>
<add input="{DB:{R:1}}" pattern="(.+)" />
</conditions>-->
<action type="Redirect" url="(Omniservice/foto/2017/02/02/18443151-810079.jpg)" />
</rule>
</rules>
</rewrite>
but it's not captured, despite testing with IIS says it's ok:
If I use <match url="(.*)" /> then I am redirected to the corrected new URL but nothing is showed anyway because it says there were too many redirects.
The rule works for me, but it redirects me to http://localhost/(Omniservice/foto/2017/02/02/18443151-810079.jpg) maybe you need to remove () from url attribute in action node? Do you not even see a 301 redirect with above rule?
I have created code to redirect for non www to www, /index.html to "/", 404 to custom page, I am using IIS server and putting this code in web.config file, have a look, its working fine. But I want to know is it good for SEO ? Or It need any modification ?
Thanx
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<rewrite>
<rules>
<rule name="CanonicalHostNameRule1" stopProcessing="true">
<match url="index\.html(?:l)?" />
<conditions>
<add input="{HTTP_HOST}" pattern="example\.com.au$" />
</conditions>
<action type="Redirect" url="http://www.example.com.au/" />
</rule>
<rule name="CanonicalHostNameRule2" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^example\.com.au$" />
</conditions>
<action type="Redirect" url="http://www.example.com.au/{R:1}" />
</rule>
</rules>
</rewrite>
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" />
<error statusCode="404" responseMode="ExecuteURL" path="/404error.html" />
</httpErrors>
</system.webServer>
</configuration>
Your rules look fine. In general, the idea with making your URLs cannonical is to direct all the link juice to a single cannonical address. In the eyes of Google and such, www.mydomain.com and mydomain.com are two different URLs. Same goes for mydomain.com/ and mydomain.com/imndex.html. The only thing I would add to your rules is a statusCode of 302. This will tell both Google and client`s browsers that you would like them to reffer to the target URL from now on. This way Google will sum all link juice to the target and also clients browsers will not need to be re-redirected with each request.
I have some IIS rewrite rules that I want to vary by environment. The development rewrite rules are in the web.config file, then at the end of the web.test.config file I have:
<appSettings>
...Some app settings tranforms here
</appSettings>
<system.webserver>
<rewrite xdt:Transform="Replace">
<rules>
... rules here
</rules>
</rewrite>
</system.webserver>
</configuration>
My app settings are getting transformed when I deploy to test, but by IIS rewrite rules are not. I was hoping the entire <rewrite> section would simply be replaced with the one in the transform file (as per http://msdn.microsoft.com/en-us/library/dd465326.aspx), but nothing is changing.
I have tried putting xdt:Transform="Replace" xdt:Locator="Match(name)"> on the individual rules too:
<rule name="Test rule" stopProcessing="true" xdt:Transform="Replace" xdt:Locator="Match(name)">
But again this makes no difference.
Is it even possible to replace rewrite rules in the web.config and if so, what am I missing?
As I didn't have any rewrite rules in my main web.config, the Replace transform didn't work. I successfully used the Insert transform, as below:
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="CanonicalHostNameRule1">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.mysite\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.mysite.com/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
There is a lot of answers here with examples which is a good thing, but I think few details are missing. I have wrote about this in my website, the key point here is to add xdt:Transform="Insert" in the root tag hierarchy you want to be added for the respective environment.
By default you have your Web.config file, but you have also Web.Debug.config and Web.Release.config as seen in the image below:
Lets say you want to added a redirection from http to https in your release of the application. Then edit Web.Release.config and add following lines:
<?xml version="1.0"?>
.....
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
......
</rules>
</rewrite>
</system.webServer>
</configuration>
So next time you publish your project the tag with rewrite and its sub-content will be added to web.config file.
To see that before you publish, right click on Web.Release.config and click Preview Transform.
You will see the difference between initial version and release version.
Reference:
HTTP to HTTPS Redirect - IIS 8.5 not working properly
Microsoft Web.Config file transformations
Disclaimer: the link of this guideline refer to my personal web site.
The rewrite section worked weirdly to me at first when creating the release configs, errors and sections not showing at all. This is how i solved it.
Microsoft (R) Build Engine version 12.0.31101.0
Microsoft .NET Framework, version 4.0.30319.0
Edit After messing about with this i realized that having the rewrite tag on a server that does not have the rewrite plugin make the webserver return an error. I want different configurations on server and local development machine so the fix is:
The un-transformed web.config only needs a <system.webServer> tag and in the web.config.release for a basic canonical host name rule
<configuration>
<system.webServer>
<rewrite xdt:Transform="Insert">
<rules>
<rule name="CanonicalHostNameRule" xdt:Transform="Insert">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^www\.host\.com$" negate="true" />
</conditions>
<action type="Redirect" url="http://www.host.com/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The action didn't need a name at all but the rewrite tag needs the xdt:Transform="Insert"
Obviously if you want it on your local machine as well, it would need an update instead.
It is possible to transform the rewrite section of system.webServer. I was initially having the same problem and realized that I had inadvertently placed the rewrite node incorrectly under system.web. While this does not look like your problem based on the limited snippet that you provided, I would still suspect that your issue is related to node placement in the transform file.
Here is what my Web.Debug.config looks like (and this version is writing the correct Web.config on a debug build):
<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an atrribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
<system.webServer>
<rewrite xdt:Transform="Replace">
<rules>
<clear/>
<rule name="Canonical Hostname">
<!-- Note that I have stripped out the actual content of my rules for the purposes of posting here... -->
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
A trick I use is give the action a name
then in my transform just add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" like the following
<system.webServer>
<rewrite>
<rules>
<rule name="RedirecttoWWW" enabled="true" >
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.([.a-zA-Z0-9]+)$" />
</conditions>
<action name="AddWWW" type="Redirect" url="http://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
</rule>
</rules>
</rewrite>
The above example is to add www to all requests
-------UPDATE-----
just an update adding name to the action will not work as wanted so I updated the code as the following
<system.webServer>
<rule name="RedirecttoWWW" enabled="true" xdt:Transform="RemoveAll" xdt:Locator="Match(name)" >
</rule>
<rule name="RedirecttoWWW" enabled="true" xdt:Transform="InsertIfMissing" xdt:Locator="Match(name)" >
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.([.a-zA-Z0-9]+)$" />
</conditions>
<action type="Redirect" url="http://{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
I was stuck by a simple outbound rule, I want to modify the HTTP Content-Type to application/atom+xml, if the URL exactly matches http://wayneye.com/Feeds/Atom
My rule XML:
<outboundRules>
<rule name="AtomFeedsIMEType" patternSyntax="ExactMatch">
<match serverVariable="RESPONSE_CONTENT_TYPE" pattern="http://{HTTP_HOST}/Feeds/Atom" />
<action type="Rewrite" value="application/atom+xml" />
</rule>
Need help...
You are matching the server variable against the full URL, including domain name. That's not going to work ;-). It doesn't really matter what the value of the Content-Type is, you're going to replace it anyway so you can match is against anything. To make sure you don't replace it on every page, you need to add a precondition to match only requests starting with /Feeds/Atom (on {REQUEST_URI} ). Here's an example:
<outboundRules>
<rule name="AtomFeedsIMEType" preCondition="Match atom feeds">
<match serverVariable="RESPONSE_Content_Type" pattern="(.*)" negate="false" />
<action type="Rewrite" value="application/atom+xml" replace="true" />
</rule>
<preConditions>
<preCondition name="Match atom feeds">
<add input="{REQUEST_URI}" pattern="^/Feeds/Atom" />
</preCondition>
</preConditions>
</outboundRules>
For this to work, the server has to be set up to allow changing of the Content-Type header. This can be done either on the server level or on the site level but needs to be done by the Administrator. It's set in the applicationHost.config and not in the web.config. Here is a part of the applicationHost.config that allows that:
<location path="your_site_name">
<system.webServer>
<rewrite>
<allowedServerVariables>
<add name="CONTENT_TYPE" />
</allowedServerVariables>
</rewrite>
</system.webServer>
</location>
You can also allow this from the GUI, with the View Server Variables link under actions from the main URLRewrite screen. Hope this helps.