How do I bypass Accept header validation in IIS? - asp.net

I have a Nancy website hosted on ASP.Net with a number of custom routes. These routes include mappings which look like file paths (e.g. /path/to/xml_file.xml), but that resolve to HTML files which should display in the browser. For most files, this works correctly. However, with XML files (and possibly other mime types), I am getting a 406.0 HTTP error from IIS 8 Express explicitly stating that
HTTP Error 406.0 - Not Acceptable
The resource cannot be displayed because the file extension is not being accepted by your browser.
The request was rejected because it contained an Accept header for a MIME type that is not supported for the requested file extension.
Verify the MIME settings for the file extension that was requested to make sure this MIME type is acceptable.
Is there any web.config setting or other technique for bypassing this validation so that I don't get this error without having to rewrite the path logic? My Google searching is failing me. For example, I have found this IIS forum post linked from the SO Answer which talks about
map all reqests to ASP.NET and use the ASP.NET's StaticFileHandler to serve them
However, the post does not explain how to do this; nor does it seem applicable.
Edit: (Added error page image above)
As another tidbit, the Nancy route returns an explicit view of the form
return View["view_name", myModel];
And therefore, should bypass content negotiation.

While not a fix or answer per se, my current work around (for anyone who might be interested) is to tweak the routes to use a trailing slash. As an example:
"/path/to/xml_file.xml" // Still returns a 406.0 error
"/path/to/xml_file.xml/" // Works properly (notice the trailing slash)

Here's a link to the Rackspace knowledge center that shows how to change the MIME mapping for static content in the web.config file.
https://www.iis.net/configreference/system.webserver/staticcontent/mimemap
There's also this one from MS that's more in-depth.
https://www.iis.net/configreference/system.webserver/staticcontent/mimemap
They both feature this stanza from the web.config file.
<configuration>
<system.webServer>
<staticContent>
<remove fileExtension=".extension" />
<mimeMap fileExtension=".extension" mimeType="application/example" />
</staticContent>
</system.webServer>
</configuration>
If that's how to actually fix the 406.0 problem...

Related

Can't render style sheet on my Meteor app (MIME error)

This is the error I'm receiving when trying to load CSS/less data:
I looked around StackOverflow for the same problem and I find out that I had to use an absolute URL for the stylesheets. I tried basically every combination of the URL where my stylesheets are located, but I still get the same error but only different link attached.
The stylesheets that I need to render are located in /client/stylesheets/less, but no matter what URL path I type, i get the same MIME/type error.
Can anyone be kind enough to point a fellow in the right direction?
Make sure the .css and .less extension are set up to use text/css as the MIME Type either on the server level or for your web application. You can add this MIME type to your web.config if you do not have access to the server level configuration.
<system.webServer>
<staticContent>
<remove fileExtension=".less" />
<mimeMap fileExtension=".less" mimeType="text/css" />
</staticContent>
</system.webServer>
The remove is included for if the setting is configured at the server level already to not cause a conflict.
Did you forget to install the less compiler?
meteor add less

urlrewritingnet - rewrite URL with subdomain

I have umbraco website setting on an IIS 7 server: WWW.SITE.COM
I would like rewrite the URL WWW.SITE.COM/SIGUNP to WWW.SIGNUP.SITE.COM
is it possible by using urlrewritingnet or should I configure this by using DNS Host?
I would use HTTP Redirect in IIS to achieve this. I'd recommend using permanent (301) as response status, this will also force most search robots to update their indexes.
Add everything inside the configuration elements to your web.config file
<?xml version="1.0"?>
<configuration>
<location path="signup">
<system.webServer>
<httpRedirect enabled="true" destination="http://www.signup.site.com" exactDestination="false" httpResponseStatus="Permanent" />
</system.webServer>
</location>
</configuration>
exactDestination="false" will turn http://www.site.com/signup/anything/example.html into http://www.signup.site.com/anything/example.html
exactDestination="true" will turn http://www.site.com/signup/anything/example.html into http://www.signup.site.com/
There are several approaches to doing this and Eric's approach is a perfectly valid one. You can also use UrlRewriting.Net as you suggest but I think Eric has suggested the baked in <httpRedirect /> approach as it can be configured in the web.config and therefore also in IIS7 manually.
The disadvantages to this approach however are that:
It needs a developer to update the web.config; or
Someone with access to IIS to change the configuration
It requires an application restart to pick up the redirect rules
There are two other approaches you should consider:
A HttpModule that uses a CSV file containing a cached list of 'from' and 'to' URLs;
A Umbraco-managed doc type that can handle specific path redirects.
The HttpModule approach obviously requires a little coding but is very rewarding. Your SEO team/client can provide a list of URLs that need redirecting and your HttpModule can cache the list (using the file as a dependency) and perform the redirects based upon matched URLs. Any update to the file simply clears the cache automatically.
For basic redirects, I like the approach of having a "Redirect" doc type in Umbraco. This doc type will have two fields, a "redirect type" field (301/302) and a "redirect to" field. In the template for this doc type you will need a little cpde that performs a redirect to the "redirect to" node. Any hits on a page created using this doc type will automatically redirect to the target page. You can also use this doc type in conjunction with "umbracoUrlAlias" field. You can add multiple paths to this field separated by a comma (see this article for an explaination). This way you can catch multiple simliar paths and redirect to a single path.
The advantage of this approach is that it is manageable in the CMS, but the disadvantage is that the redirects are not managed centrally like a CSV file, so you need to be careful in how it is implemented.

ASP.Net IgnoreRoutes Does not work

I have an svg file as my assets and in routeconfig, I have mentioned the below code
routes.IgnoreRoute("{*svg}", new { svg = #"(.*/)?.svg(/.*)?" });
This seem to be working fine with cassini (Visual Studio 2012 Buit-in Deployment Server) but when I deploy it to Azure I get a 404.
Is my IgnoreRoute statement right ? or any other solutions ? all other images, style sheets seems to work ok.
Thanks a lot in advance.
You never have to ignore routes for files that physically exist on disk, the routing module will not try to route those requests. You only need to ignore routes to other virtual resources.
Azure web sites do not have a mime type configured for .svg files, at least at the end of last year they didn't. You can configure a mime type for svg in the <system.webserver> section of your web.config file:
<staticContent>
<remove fileExtension=".svg"/>
<mimeMap fileExtension=".svg" mimeType="image/svg+xml"/>
</staticContent>
The remove is there to prevent errors on servers that already have an entry for .svg. It's an error to add a duplicate fileExtension, but not an error to remove a non-existent extension.
More here: Configuration Tips For ASP.NET MVC 4 on a Windows Azure Website
Looking at Phil's Blog I think what you need is something like:
routes.IgnoreRoute("{*allsvg}", new {allsvg=#".*\.svg(/.*)?"});
Hope that helps.
What order are you declaring the routes? It could be that above that one you have default or catch-all a route that actually already handles the request and so your IgnoreRoute never gets hit.

IIS and Static content?

According to Ultra-Fast ASP.NET: Chapter 3 - Caching:
Files that the browser retrieves from the server should be stored in
the browser’s cache as long as possible to help minimize server
round-trips.
But how does IIS know what a static content actually is and is not?
Is it just images, CSS, JS and not ASPX, ashx...?
Where can I see in IIS what is already considered to be static and what is not ?
What about the scenario where a page has been declared with <%# OutputCache header (without location)? Are the images, CSS and JS source files inside of it also being output cached with the same properties?
As a best practice, I should set one year into the future as the maximum expiration time. I should use that as the default for all static content on the site
So I did this :
But later, after pressing OK, I can't find any summary menu which shows me: to whom I already put a response header (in this case: the css folder).
Currently, in order to see that css folder has been applied with response headers - I have to go to the css folder again --> Http Response Header-->Set Common Headers --> and then I see it. It isn't written in the web.config.
But if I do it for a file (Login.aspx for example): I do see it in web.config:
<configuration>
<location path="Login.aspx">
<system.webServer>
<staticContent>
<clientCache cacheControlMode="UseExpires" cacheControlMaxAge="1.00:00:00" httpExpires="Fri, 15 Feb 2013 00:00:00 GMT" />
</staticContent>
</system.webServer>
</location>
</configuration>
I understand your situation. Sometime its confusing how IIS handles a file. Its also different for IIS 6 vs IIS 7 and different for Classic App Pools and Integrated mode app pools. My experience is mostly with Integrated App Pools on IIS 7.5, so thats the environment I can comment on most accurately.
First Question
But how does IIS knows what is actually a static content and what is
not?
Is it just images , css , js and not ASPX , ashx...?
Where can I see in the IIS what is already considered to be static and
what not ?
You can inspect the list of file handlers in IIS by navigating to your website and then click 'Handler Mappings'. By default these are inherited from the .Net base web.config which is in a different location depending on your .Net framework version.
C:\Windows\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config
If a file being requested isn't already explicitly mapped to another handler it falls to a catch all handler (*) as the last option (System.Web.DefaultHttpHandler) which determines if it is a static file or a directory browsing request. So Static files are simply files not bound to another handler already. For example you'll see that *.aspx is already mapped to System.Web.UI.PageHandlerFactory prior to this default handler. So its going to be processed by that handler and not be considered a static file. If you removed that mapping you could technically serve *.aspx as a static file if you really wanted to (just for proof of how it works).
But you can also explicitly list a file type as a static file by adding an entry in your web.config's httpHandlers section mapping the file extensions to System.Web.StaticFileHandler in IIS. For example:
<configuration>
<system.webServer>
<handlers>
<add name="StaticHandler" verb="*" path="*.zip" type="System.Web.StaticFileHandler" preCondition="integratedMode" />
</handlers>
</system.webServer>
</configuration>
This example is using the <system.webServer> config section, so its for an App Pool running in Integrated Mode.
Second Question
What about the scenario where a page has been declared with <%#
OutputCache header(without location) . does the images,css,js src
files inside of it , are also being output cached with the same
properties?
No. Because the page is being server as a separate request (maybe even by a separate handler) it can have totally different cache headers/hints. The host page and the resources it may use are not related from a caching perspective.
In fact you may even want to have a shorter cache period for *.html and a longer cache period for *.jpg or *.png? Something to consider.
Third Question
As a best prcatice , I should set one year into the future as the
maximum expiration time.I should use that as the default for all
static content on the site
Hmm... I might not go as far as one year. How about one month? I would set a global policy like this:
<configuration>
<system.webServer>
<staticContent>
<!-- Set expire headers to 30 days for static content-->
<clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="30.00:00:00" />
</staticContent>
</system.webServer>
</configuration>
This is the same as the sample you showed above, but is not inside a <location> element, instead it is right in the root <configuration> element so it is the default policy. Again this is for an App Pool running in Integrated Mode. Sometimes you also need to turn on:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<!-- stuff -->
</modules>
</system.webServer>
<system.webServer>
This just makes sure that static files are processed through the managed static file handler which respects the above configuration elements.
Edit to Address Comments
The documentation for the configuration dialog you posted above is located here: Configure the HTTP Expires Response Header (IIS 7)
Apparently these settings are saved in C:\Windows\System32\inetsrv\config\applicationHost.config
I do not have IIS7 and personally develop on IIS 7.5 now. So please post a comment if you can verify this location is accurate!
The static content is the one that IIS is read and send to the browser with out any processing. There you can setup IIS to include some Cache-Control Header to cache it on clients browser computers.
You can do that ether by direct setup IIS, ether by commands on web.config as you say. The commands that you add on web.config and concern the IIS, did not have to do with asp.net it self, but the IIS, and IIS saves his configuration on a different file, so when you change that cache control headers direct on IIS you do not see them on web.config.
Now for the static content like images, CSS, JavaScript, and other similar files they say that you can follow the "never expire" policy by adding 10 years expire.
The issue here is that if you can not change the content of the static file, if for example you cache a javascript file with 10 years, and you make a small change on it, then you need ether to change the file name, ether to add some parameter at the end of it.
Now the <%# OutputCache on a control is referred to the server cache and not to the client, and what is actually do is to cache the render of the control on the server so the next time you ask it to not lose time to renders it again but read it from cache - is still send it to the browser.
And you can also read this answer for some more: What are difference between IIS (Dynamic and Static) cache,OutPutCache and browser cache

IIS Wildcard Mapping not working for ASP.NET

I've set up wildcard mapping on IIS 6, by adding "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll", and ensured "Verify that file exists" is not checked :
on the "websites" directory in IIS
on the website
However, after a iisreset, when I go to http://myserver/something.gif, I still get IIS 404 error, not asp.net one.
Is there something I missed ?
Precisions:
this is not for using ASP.NET MVC
i'd rather not use iis 404 custom error pages, as I have a httpmodule for logging errors (this is a low traffic internal site, so wildcard mapping performance penalty is not a problem ;))
You need to add an HTTP Handler in your web config for gif files:
<system.web>
<httpHandlers>
<add path="*.gif" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="true"/>
</httpHandlers>
</system.web>
That forces .Net to handle the file, then you'll get the .Net error.
Server Error in '/' Application.
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /test.gif
Version Information: Microsoft .NET Framework Version:2.0.50727.1433; ASP.NET Version:2.0.50727.1433
You can try use custom errors to do this.
Go into Custom Errors in you Website properties and set the 404 to point to a URL in your site. Like /404.aspx is that exists.
With aspnet_isapi, you want to use a HttpModule to handle your wildcards.
like http://urlrewriter.net/
You can't use wilcard mapping without using ASP.net Routing or URLrewriting or some url mapping mechanism.
If you want to do 404, you have to configure it in web.config -> Custom errors.
Then you can redirect to other pages if you want.
New in 3.5 SP1, you set the RedirectMode to "responseRewrite" to avoid a redirect to a custom error page and leave the URL in the browser untouched.
Other way to do it, will be catching the error in global.aspx, and redirecting. Please comment on the answer if you need further instructions.

Resources