IIS7: Content-Length Mismatch Due to URL Rewrite and OutboundRules Usage - caching

I'm having some issues getting the outbound rules configured to work on IIS7, here's the scenario that's giving me grief. My ultimate goal is to get any outboundRules working within a couple of browsers. For this example, I'm using the rule that strips .aspx from various HTML tags.
Scenario 1 (Content-Length Mismatch):
To get that particular rule to work in IIS7, I had to disable dynamic compression and turn caching off by default. I was successful in getting the HTML rewritten, but another issue cropped up that makes this unusable.
When trying the rewrite content with outboundrules, I'm getting an issue where by Chrome and Firefox are performing a continuous load because of a "content-length mismatch" in the headers (Thanks Fiddler for helping me identify it). The rewrite works, but it causes the content length to be incorrect and so those two browsers look like they're loading forever. Chrome in particular this causes an issue because javascript appears to be hung up and so anything jquery doesn't work until someone physically hits the stop button.
This is the pertinent sections of the web.config that I began with in order to give me that scenario:
<system.webServer>
<rewrite>
<urlCompression doStaticCompression="false" doDynamicCompression="false" dynamicCompressionBeforeCache="false" />
<modules runAllManagedModulesForAllRequests="true" />
<outboundRules>
<rule name="Remove .aspx from links in the response" preCondition="IsHTML" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, IFrame, Link, Img, Script" pattern="(.*)\.aspx(\?.*)?$" />
<action type="Rewrite" value="{R:1}{R:2}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<caching enabled="false" enableKernelCache="false" />
</system.webServer>
While researching this issue, I found this stackedoverflow question which mentioned the rewriteBeforeCache="true" attribute on the outboundRules tag as well as this blog post which laid out the same thing that I was running into with the content-length issues.
If I modify that attribute, that leads me to Outbound Rules failing to work any further.
Scenario 2 (Outbound Rules do not work):
So because of the prior information, I began tweaking the web.config and was able to resolve the content-length mismatch by using the rewriteBeforeCache attribute on the outboundRules tag. To get that attribute to work, I was able to turn caching back on. That fixed the reponse-length mismatch from Scenario 1, but now none of the outboundRules\rule elements appear to work. I have tried a number of the simplest rules and they function just fine when I remove the rewriteBeforeCache attribute, but that causes Scenario 1:
<system.webServer>
<rewrite>
<urlCompression doStaticCompression="false" doDynamicCompression="true" dynamicCompressionBeforeCache="false" />
<modules runAllManagedModulesForAllRequests="true" />
<outboundRules rewriteBeforeCache="true">
<rule name="Remove .aspx from links in the response" preCondition="IsHTML" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, IFrame, Link, Img, Script" pattern="(.*)\.aspx(\?.*)?$" />
<action type="Rewrite" value="{R:1}{R:2}" />
</rule>
<preConditions>
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
Scenario 1 causes one error with browsers in IIS7; Scenario 2 causes outboundrules to stop working.
I have modified any number of options with disabling caching, chunk-mode transfers, and trying every combination I can think to try.
Additional notes on AppPool: IIS7, .NET4.0, Classic pipeline
Does anyone else have any ideas as to what other options I have to address this beyond moving to an IIS7.5 server?

Related

Why is IIS 8.5 URL Rewrite throwing a 404 error?

We have modified our file structure a bit since we've found an issue with the result in my other thread and we now we're back where we've started. I have checked out this thread but there is no answer to that question either.
We want the URL to show: https://devbox.mysite.com/kb/article/test-article-1 on the browser.
Below is my URL Rewrite:
<rule name="Article-rewrite" enabled="true">
<match url=".com/kb/article/(.*)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="https://devbox.mysite.com/kb/article/?artID={R:1}" appendQueryString="false" />
</rule>
I have enabled Failed Request Tracing to trace rewrite rules on the IIS but when I added the rules I do not see the Rewrite as an option even though this instruction showed that it's there. This is my settings and it's not showing option. Anyway, this is just a side issue to diagnose my url rewrite issue.
Okay, so I finally figured out the answer to my question. The match URL will match the folder kb/artitcle/ and the a-ZA-Z- will only allow word and dash. In my situation, there will only be one parameter being passed so I intentionally ignoring the ampersand character because in CommonSpot CMS it adds a &cs_pgIsInLView=1 to the end of the URL which causes the rewrite rule to break. So by ignoring this ampersand, it works in my situation. The query_string pattern 1 will ignore rewrite when I tried to login to the page with the url https://devbox.mysite.com/index.cfm?login=1. I'm guess there may be other better ways than this one but for now, this will have to do.
<rule name="Article-rewrite" enabled="true">
<match url="^kb/article/([a-zA-Z\-]+)$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{QUERY_STRING}" pattern="1" negate="true" />
</conditions>
<action type="Rewrite" url="kb/article/?artID={R:1}" appendQueryString="false" />
</rule>

URL ReWrite Friendly-URL not working for novice programmer

We're using URL ReWrite 64bit version from Microsoft on Windows 2012 R2, ColdFusion 11 Enterprise, IIS 8.5, and SQL 2008.
Forgive me for being redundant and obvious. Writing in detail is the only way I know how to get my point over. I hope it's not too much.
I've searched the site but cannot find an answer that hints at what I'm doing wrong.
So, this is my first question:
URL ReWrite is installed and seems to operate okay with some rules, but I cannot get it to do what I want with the Friendly-URL rewrite. That is the problem. I'm hoping someone will use the same basic parameters I used to see if they get the same problem on Windows or Windows Server.
Our public Announcements section on our website was written to use the ID (PK) from an SQL database table to point the URL of the an
announcement (from a list inside an sql table), with lots of categories such as jobs, events, garage-sale, etc, etc. I know, you all know
this is pretty standard for amateurs. So, as you well know, this URL method is not only clumsy, can be a security risk, but does not
easily allow for me to format the URL as I want.
The selection of announcements starts at the 'select' page:
www.domain.com/event/select.cfm
So, currently when clicking on one of the links on the select.cfm page (the list generated from a cfquery output)
I get this URL and am taken to the view page to display the actual individual announcement:
http://www.domain.com/event/view.cfm?id=23
select.cfm and view.cfm are both in the same directory inside /event/.
The anchor for the link: href="/event/view.cfm?id=#ViewInfo.ID#" (without the brackets of course).
Everything displays and works fine except for the URL I don't want.
Obviously, the folder /event/ is just off the web root, (the announcements directory) which is the only place this rule should operate.
That 'ID' I've been using in the sql table is announcement number 23 in the JOBS category. All categories and announcements are in just
the one table.
For a more friendly URL, I'd prefer to use the 'category' of each announcement and the current 'date' the announcement was saved, which
seems a pretty normal, right?
Except I'm nearly brand new at programming and really hesitated coming here.
Anyway, before attempting to use URL ReWrite, I first tried to do this:
www.domain.com/event/jobs/23/2015-12-2/view.cfm or some variation. Nothing worked the way I wanted.
It was a mess.
I quickly learned the forward slash required an actual directory on the hard drive between each slash and I could find no way around it. I
added another notch to my html synapse. I didn't want to create tons of folders and sub-folders for no good reason. So, I thought by using
the URL ReWrite I could do something like this:
www.domain.com/event/jobs-2015-12-2_3.html or some crazy variation. A couple days later my brain was hurting far too much.
I had figured this way I'd rid myself of the id= and .cfm file, and add a category which makes more sense and is easier for reference. I
may actually use part of a uniqueidentifier instead of the PK ID but that's not important for this problem.
So I stumbled onto URL REWRITE and installed it.
I opened IIS 8.5 Manager, went to the website I was using, and to the /event/ folder and clicked on URL REWRITE. I then selected Add Rule
and User-Friendly URL. I then entered the URL to one of the announcements:
"/event/view.cfm?id=" at the top of the tab, as the "internal URL".
I also tried hard coding the full URL just for a test: "/event/view.cfm?id="23" They did not work.
For each test, I entered the second example suggestion on the second line: /id/184/ just to see if it would work.
But it did not. I checked the 'web.config' file (which I will include here) in the /event/ directory and the code rules had been written
correctly. But there was there was no change to the URL as I expected when I click on the link to view.cfm. It still showed this:
www.domain.com/event/view.cfm?id=23
I tried every combination in URL ReWite I could think of but I cannot get the link to the URL to change at all, to anything, no matter
what I do. I don't get it.
I know that my installed URL ReWrite is working because of another rule I use to forward all discovered .htm files to the .cfm equivalent
when they are found.
I even did a "repair" to the installed URL ReWrite and rebooted but that did not help. Then I uninstalled URL ReWrite and installed again,
rebooted. Still no change. It works, but not with the Friendly-URL rewrite. I'm obviously doing something wrong but am at at a total loss
and might need to hire a real programmers. And that could be the end of my new job.
So, hope someone can steer me in the right direction. If so, I promise to learn and help others as I can.
Here's my web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectUserFriendlyURL1" stopProcessing="true">
<match url="^event/view\.cfm$" />
<conditions>
<add input="{REQUEST_METHOD}" pattern="^POST$" negate="true" />
<add input="{QUERY_STRING}" pattern="^([^=&]+)= ([^=&]+)$" />
</conditions>
<action type="Redirect" url="event/view/{C:1}/{C:2}" appendQueryString="false" />
</rule>
<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
<match url="^event/view/([^/]+)/([^/]+)/?$" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="event/view.cfm?{R:1}={R:2}" />
</rule>
</rules>
<outboundRules>
<rule name="OutboundRewriteUserFriendlyURL1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^(.*/)event/view\.cfm\?id=([^=&]+)$" />
<action type="Rewrite" value="{R:1}event/view/id/{R:2}/" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>

IIS Url Rewrite not working for certain extensions and characters

I am using IIS 7.5 with the Url Rewrite module. Here is my rule.
<rule name="stash.domain.com" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://192.168.5.9:8080/{R:1}" logRewrittenUrl="true" />
<conditions>
<add input="{HTTP_HOST}" pattern="^stash.domain.com$" />
</conditions>
</rule>
Everything works as expected, except if the url contains and extension of ".cs", or if a "+" sign is in the url anywhere.
For example, these don't work
http://stash.domain.com/projects/MDX/repos/medxchange.library/browse/Src/MedXChange.Api/CoreServiceUrls.cs
http://stash.domain.com/projects/MDX/repos/medxchange.library/browse/Src/MedXChange.Api/CoreService+Urls
I get the following response from IIS with those urls.
404 - File or directory not found.
But, these will work, however, the proxy server will return a nice "file not found", which tells me the rule is processed and forwarding requests correctly.
http://stash.domain.com/projects/MDX/repos/medxchange.library/browse/Src/MedXChange.Api/CoreServiceUrls
I suspect the IIS has some top level filtering to either prevent certain file extensions from being served, or attempt to serve them nativelly within IIS, bypassing the rewrite rules. Also, I imagine there are more characters, aside from "+", that cause the rewrite rules to be ignored.
I had this problem too. It turns out the IIS is trying to be helpful and prevent remote users from downloading source code, which was exactly what I was trying to allow!
The fix was to go into Request Filtering and remove all the troublesome entries, although I skipped that and just put this in the web.config:
<system.webServer>
<security>
<requestFiltering>
<fileExtensions>
<clear />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>

How to configure web.config to load resources form external server

I'm developing a web application in Visual Studio 2013 and am getting my data from an external server. For this reason I disable the web securtiy in my browser and define absolute URLs in my application. Now whenever I'm deploying the applicaiton, I have to adopt the URLs (which of course get's forgotten the first time) and also I have to explain the setup to evey person new in the porject.
After getting a bit fimilar with the web.config file, I tried to setup some rules, to rewirte this urls to the data webserver, but failed.
All my relative urls start with the same identifyer, and should be mapped to an external server. This is what I have so far:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite calls to rest.oms to the actuall webserver">
<match url="^/IDENTFIER/([_0-9a-z-]+)" />
<action type="Rewrite" url="http://EXTERNAL_SERVER/IDENTFIER/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
However, it is not working so far. Can somebody help me please.
Best Regards,
Stefan
It is possible to rewrite from external url, if you have ARR module.
1) You need to install ARR module for your IIS
2) In IIS manager you should enable reverse proxy
2.1) On server node click "Application Request Routing Cache"
2.2) Click "Server proxy settings" and click "Enable proxy", then "Apply"
3) Slightly fix your rewrite rule regexp (remove starting slash):
<rule name="Rewrite calls to rest.oms to the actuall webserver">
<match url="^IDENTFIER/([_0-9a-z-]+)" />
<action type="Rewrite" url="http://EXTERNAL_SERVER/IDENTFIER/{R:1}" />
</rule>
Then your rule should work.

Localize error 500 page in mvc3

I've been going through stack overflow but cannot find an answer to this. I can get the 500 page to show up ok like this:
<customErrors mode="On">
<error statusCode="500"
redirect="~/500.html"/>
</customErrors>
What I would like to do is to present a localized version of the page based on the app language. Problem is that I would not like to go through the Error Controller-View solution that I found in lots of other posts, in case there is an actual error in the App (missing DLLs etc.). So I have to serve a pure html page, but I need to be able to choose the localized one, or instruct IIS on how to find it.
Any idea?
This is just off the top of my head, couldn't you use URL rewrite/redirect rules that use the Accept-Language that the browser defines to redirect to ~/500.en-us.html and ~/500.de.html or however you may have the pathing setup?
Example Rule in web.config:
<rule name="HTTP-Language-Error-Redirect" stopProcessing="true">
<match url="^500.html$" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{HTTP_ACCEPT_LANGUAGE}" pattern="^([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?$" />
</conditions>
<action type="Redirect" url="500.{C:1}.html" redirectType="Found" />
</rule>
My thinking is that the redwrite/redirect rule would work as it's part of IIS's processes handling the request and not the app code. So it could still work, theoretically, if the WebApp is broken for some reason. I could be totally wrong in my assumption though, and I thought I'd give it an honest shot.

Resources