Physical Folder Breaks ASP.NET URL Routing on IIS Express - asp.net

IIS Express is producing 403.14 Forbidden errors when a URL that would otherwise be handled through ASP.NET URL routing happens to correspond to a physical folder in my ASP.NET project. (The folder contains only code, and it's coincidental that the folder name happens to match the URL of a page; my URL structure is determined dynamically by a database, and users can edit that structure, so although I could just rename my project folder, in general I can't prevent this sort of collision occurring.)
This seems to be happening because the DirectoryListingModule steps in to handle the request, and then promptly fails it because directory browsing is disabled. I've tried removing this:
<system.webServer>
<handlers>
<remove name="StaticFile" />
<add name="StaticFile" path="*" verb="*"
modules="StaticFileModule" resourceType="Either" requireAccess="Read" />
</handlers>
</system.webServer>
That removes the default StaticFile handler configuration, which has modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule", and replaces it with a configuration that provides just the feature I want. (I want static file serving, but I have no need for directory listing or default documents in this app.) But the effect seems to be that IIS then produces a completely empty (0 byte) response (with a 200 status) when I hit the offending page.
So next, I tried configuring the StaticFile handler to handle only the specific physical folders that I want to make available:
<system.webServer>
<handlers>
<remove name="StaticFile" />
<add name="StaticFileCss" path="style/*.css" verb="*"
modules="StaticFileModule" resourceType="Either" requireAccess="Read" />
<add name="StaticFileScripts" path="Scripts/*" verb="*"
modules="StaticFileModule" resourceType="Either" requireAccess="Read" />
</handlers>
</system.webServer>
But when I hit the offending URL, this then produces a 404.4 - Not found error, with a message of The resource you are looking for does not have a handler associated with it.. (The Detailed Error Information on the error page says that we're in the IIS Web Core module, during the MapRequestHandler notification, the handler is Not yet determined, and there's an Error Code of 0x80070002, which is a COM HRESULT that corresponds to the Win32 ERROR_FILE_NOT_FOUND error.)
The mystifying thing is that it's not even bothering to ask ASP.NET whether it has a handler for it. IIS seems to be deciding all by itself that there definitely isn't a handler.
This only happens when there's a folder that matches the URL. All other resources with dynamically-determined URLs work just fine - IIS asks ASP.NET for a handler, ASP.NET's routing mechanism runs as normal, and if the URL corresponds to one of my dynamically defined pages, it all works fine. It's just the presence of a physical folder that stops this all from working.
I can see it's IIS doing this because I get one of the IIS-style error pages for this 404, and they have a distinctive design that's very different from the 404s produced by ASP.NET. (If I try to navigate to a URL that neither corresponds to a physical folder, nor to a dynamic resource, I get a 404 page generated by ASP.NET. So normally, IIS is definitely handing requests over to ASP.NET, but IIS is definitely getting in the way for these problematic resources.)
I tried adding this inside my <system.WebServer>, in case the problem was that IIS has decided that requests corresponding to physical folders do not meet the managedHandler precondition:
<modules runAllManagedModulesForAllRequests="true">
But that doesn't appear to help - it still doesn't get ASP.NET routing involved for URLs that correspond to physical folders. In any case, it would be suboptimal - I would prefer not to have managed handlers run for the content that I definitely want to handle as static content. I effectively want ASP.NET URL routing to be used as a backstop - I only want it to come into play if the URL definitely doesn't refer to static content.
I don't understand why ASP.NET isn't even asking ASP.NET what it thinks in this scenario. Why is it not calling into ASP.NET during the MapRequestHandler phase if there's a physical folder that happens to correspond to the URL?

When a physical file or folder with the same URL as the route is found, routes will not handle the request and the physical file will be served.
Althrough you can change this behavior by setting the RouteExistingFiles Property from the RouteCollection object to true.
Take a look at the MSDN page Scenarios when routing is not applied

Related

404 Not Found aspx file but it is there

I´m using Plesk and in Web scripting and statistics I have Microsoft ASP support in ON.
I uploaded a application (which works correctly in my PC) to a directory and it can be shown but when I go to the aspx file it shows me the 404 error (The path is the correct).
I noticed that some files in "shtml" extension are neither shown by the server.
This is my very first time with ASP.NET, ISS8 and Plesk. I don´t know what to do. I will thank you for your help
You have to set the HTTP Handler Extension. If you have no access to IIS directly, you could do on the web.config:
Open the Web.config file for the application, locate the httpHandlers element of the system.web section and add an entry for the file-name extension
Example:
<system.webServer>
<handlers>
<add name="SampleHandler" verb="*"
path="SampleHandler.new"
type="SampleHandler, SampleHandlerAssembly"
resourceType="Unspecified" />
</handlers>
</system.webServer>
For more configuration options please refer to:
https://msdn.microsoft.com/en-us/library/bb515343.aspx
and
https://msdn.microsoft.com/en-us/library/46c5ddfy(v=vs.100).aspx
Check also the Custom Handler Policy of Plesk that should not be enabled:
https://docs.plesk.com/en-US/onyx/administrator-guide/plesk-administration/securing-plesk/custom-handlers-policy.76787/
Here I've found also another interesting document:
https://learn.microsoft.com/en-us/iis/configuration/system.webserver/handlers/
Scroll down and you'll find a piece of code to add the handlers programmatically, even if I suggest you to add them in your web.config

Why are Content, Scripts served as static and other directories not?

So this is a bit of asp.net I feel like way too many people don't understand. That is to say, I don't understand it and I've asked a bunch of people/googled and no one else seems to know the specifics either.
By default ASP.Net applications will serve files in Content and Scripts directories as static content. In fact, if I create other directories, I think it will serve static content in these as well.
However, the contents of some directories won't be served - the typical Asp.Net Mvc Controllers directory for example. In addition, you can always configure routes in asp.net (or OWIN handlers) that will pick up certain routes but not either.
Nothing seems to be configured anywhere. I have my suspicions, but I'm really not clear on what exactly is the rule for what gets served as static content and what gets processed by asp.net?
I've always found this graphic helpful: https://web.archive.org/web/20211021221111/https://www.4guysfromrolla.com/images/step2.gif
Specifically, the HttpHandlers mentioned in that graphic correspond to this section of the Web.Config file in your .NET web project's root directory:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
The path attribute of that tag can be used to configure only certain directories being handled by a certain class. At that point, IIS will hand off the HTTP request to the appropriate class, with the proper context and thread etc. My guess is that if you are running IIS with multiple frameworks, each has a distinct path associated with its add-handler tag.
Additionally, IIS has its own default settings for what file extensions are mapped to what handler classes. These can also be modified in the IIS management interface, so it's possible that your super-helpful ops team added that for you there even if it's missing from your web.config. At the end of the day, though, it's a relationship between url-HttpHandler class that determines static-file versus dynamic.
Edit:
There's another set of tags, outlined at this ServerFault answer:
https://serverfault.com/questions/175499/serving-cs-csproj-files-on-iis7-5
That describes a <add fileExtension=".cs" allowed="false" /> tag that operates on the file extension as opposed to a pattern on the entire path. This is what disallows files ending in .cs, and .csproj from being served. Additionally, since you're operating on an installation of IISExpress, you should know that it uses a different configuration file than the standard machine.config. The path for that file is described at this answer:
Where is the IIS Express configuration / metabase file found?
All this gets muddied a little by the notion of self-hosting, aka no IIS. Nancy does this, I believe, and ServiceStack can as well. I have no experience doing that, but the way they handle paths is probably a little different.

HttpHandler for static image is not getting called when file does not exist

I have httpHandler that handles the jpg file. When a request for a jpg image comes to server it is forwareded to handler. This works fine until i implemented finger printing for google page speed rule.
Now it gets called for http://static2.localnatamam.com/Uploaded/Image/Image_Haroon_ur_Rasheed_78.jpg
but not for
http://static2.localnatamam.com/Uploaded/Image/_SFP634229374826528000EFP_Image_Haroon_ur_Rasheed_78.jpg
First file exist in directory but second does not exist as the second URL is finger printed and i want to get the request in Handler but handler never gets evoked.
I think its might be IIS 7 configuration that is returning 404 rather than passing it to handler.
Please any advise or configuration that can route request to httphandler no matter if exist or not.
I am using asp.net MVC 2 with IIS 7 integreated Mode with target framework 4.0 in local enviornment so both of above URL will not open for any body.
My handler is simple IHttpHandler with the following IIS configuration
<add name="CrossDomainResourceHandler" type="MvcApplication3.HttpHandlers.CrossDomainResourceHandler" path="*.jpg" verb="*" resourceType="Unspecified" allowPathInfo="false" modules="IsapiModule" scriptProcessor="%path%\aspnet_isapi.dll"/>
Make sure you have this in your web.config file:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
</system.webServer>
runAllManagedModulesForAllRequests will tell IIS to route every request through the .net pipeline so that your module will pick this request up since by default static resources like .jpg are configured to not run through asp.net.

Understanding the ASP.NET application folders

The application folders in ASP.NET are used for storing various elements critical to running a website. I want to get a handle on understanding these folders in more depth, specifically the folder accessibility. According to the article on ASP.NET Web Site Layout:
The content of application folders,
except for the App_Themes folder, is
not served in response to Web
requests, but it can be accessed from
application code.
Any browser request to these folders results in a "404 - Page Not Found."
So what prevents folders like App_Code, App_Data, App_WebReferences, bin, etc. from being served to users? Is it an IIS hard coded "don't serve this folder?" Is it a permissions configuration? And is there anyway to knowingly/unknowingly circumvent this?
On my IIS7.5 config, found at C:\Windows\System32\inetsrv\config\applicationHost.config there is this section:
<hiddenSegments applyToWebDAV="true">
<add segment="web.config" />
<add segment="bin" />
<add segment="App_code" />
<add segment="App_GlobalResources" />
<add segment="App_LocalResources" />
<add segment="App_WebReferences" />
<add segment="App_Data" />
<add segment="App_Browsers" />
</hiddenSegments>
See also IIS Documentation.
In IIS7 on Windows Server 2008, ASP.NET is more tightly integrated into the entire processing pipeline, so I would imagine that in IIS7, it is very easy for ASP.NET to say "No, I'm not going to touch that."
In IIS6, IIS itself has very little direct knowledge of IIS, instead, it's all controlled through the ISAPI configuration.
In the IIS6 IIS Manager, right click a website, get Properties, go to the Home Directory tab, and then click Configuration in the lower right. This shows the ISAPI application extensions and what is done for each one.
For all the ASP.NET extensions (aspx, ascx, config, browser, a ton of others) it specifies handling to be done by C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll
The ASP.NET system then has registered handlers for each of these file types defined in the global machine.config and/or web.config files at C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG
For instance, in the global web.config file, under httpHandlers element:
<add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="true"/>
So it is not just these special folders, but many types of files, but many types of reserved files that are disallowed from browsing.
The .net framework itself intercepts requests to these folders (along with a bunch of other file types that you should be allowed to browse) and returns a 404 to IIS, which then gets passed back to the browser as "404 - Page Not Found".
So it doesn't happen at the permissions level, or even the IIS level. It's inside the framework -- probably in one of the HttpHandlers in the global web.config.
If you look in there, you can see a ton of file extensions that are explicitly configured to not be served. Presumably you could tweak the settings and cause it to serve, say, web.config files as xml (which is different than the usual behavior of saying that this file type is not served).
It's worth noting that I don't specifically see any of the special folders (app_code, etc) mentioned in the global web.config file. Maybe it's handled inside other HttpHandlers -- for instance, the handler for .aspx might contain some code that prevents serving of .aspx files located in special folders, etc.

URL rewriting problems with ASP .NET 2 on IIS7 and Vista

I've got a website running under ASP .NET 2/IIS7/Vista. I have a URL rewriting module which allows me to have extensionless URLs. To get this to work I have configured the system.webServer section of the config file such that all requests are forwarded to the aspnet_isapi.dll. I have also added the URL rewrite module to the modules section and set runAllManagedModulesForAllRequests to true.
When I start up the website and visit one of the pages that uses the URL rewriting, the page is rendered correctly. However if I then visit another page the site stops working and I get a 404 not found. I also find that my breakpoint in the URL rewriting module is not getting hit. It's almost as if IIS forwards the first request to the rewriter, but subsequent ones go somewhere else - the error page mentions Notification as being MapRequestHandler and Handler as being StaticFile.
If I then make a small change to the web.config file and save it, triggering the website to restart, I can then reload the page in the browser and it all works. Then I click another link and it's broken again.
For the record, here's a couple of snippets from the config file. First, under system.web:
<httpModules>
<add name="UrlRewriteModule" type="Arcs.CoopFurniture.TelesalesWeb.UrlRewriteModule, Arcs.CoopFurniture.TelesalesWeb" />
</httpModules>
and then, under system.webServer:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRewriteModule" type="Arcs.CoopFurniture.TelesalesWeb.UrlRewriteModule, Arcs.CoopFurniture.TelesalesWeb" preCondition="managedHandler" />
</modules>
<handlers>
<add name="AspNet" path="*" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="None" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
</handlers>
<validation validateIntegratedModeConfiguration="false" />
</system.web>
The site is running under classic rather than integrated pipeline mode.
Does anyone out there have any ideas? I suspect my configuration is wrong somewhere but I can't seem to find where.
This is a bit of a long shot, but have you tried actually making the configuration changes inside of IIS?
I know that the web.config way is supposed to be 100% foolproof, but I've seen a few things where it helps to just configure it in IIS to get it working correctly.
You also may want to check out the new IIS7 rewrite module. you can read more about it here http://learn.iis.net/page.aspx/460/using-url-rewrite-module/, but chances are it will be more solid then your homegrown ISAPI filter
Try http://www.codeplex.com/urlrewriter it supports all the Apache mod_rewrite syntax and also supports Reverse Proxy.
If you're runnning in classic pipeline mode you don't need <system.webServer> section it is required for integrated mode
Enable wildcard script mapping
Open the IIS7 Manager and navigate to your site
Click on Handler Mappings
In the Action panel click on "Add Wild Card Script Map"
In the dialog point to aspnet_isapi.dll
Click Yes on the message box that asks you to confirm your mapping
In the action panel click on "View Ordered List" and move your WildcardScriptMap just before StaticFile Handler
This should bee enough.
I'm ashamed to admit this but it was a simple mistake by me :-(
In my URL rewriting module, the code to rewrite the request path was in the Init method, when it should have been inside an Application.BeginRequest handler. This explains why the rewriting worked only the first time the site was hit.
Sorry to have wasted your time people!

Resources