Can I put a + sign in a folder with IIS? - asp.net

I'm pretty sure this can't be done, but I'm looking for a hack or way to put a + in a folder name, like
http://www.mysite.com/cats+dogs/Default.aspx
I'm using IIS 7, and have tried creating a virtual directory to achieve this, and it didn't work. I am not allowed to put %2B in the explorer folder or virtual folder name.
Any ideas how I could hack this to make it work? We've already had brochures printed up with a url on it, and wondering if there is some way I can alias it or some trick that might do it.
EDIT: I was able to figure this out, by creating a virtual folder with a + in it, then redirecting to a URL, which points to a virtual directory with the content.

IIS 7.0 Breaking changes for ASP.NET 2.0 applications in Integrated Mode
Here's the relevant excerpt from the page, which shows the workaround/fix.
Request limits and URL processing The
following changes result due to
additional restrictions on how IIS
processes incoming requests and their
URLs.
11) Request URLs containing unencoded
“+” characters in the path (not
querystring) is rejected by default
You will receive HTTP Error 404.11 –
Not Found: The request filtering
module is configured to deny a request
that contains a double escape
sequence.
This error occurs because IIS is by
default configured to reject attempts
to doubly-encode a URL, which commonly
represent an attempt to execute a
canonicalization attack.
Workaround:
1) Applications that require the use
of the “+” character in the URL path
can disable this validation by setting
the allowDoubleEscaping attribute in
the
system.webServer/security/requestFiltering
configuration section in the
application’s web.config. However,
this may make your application more
vulnerable to malicious URLs:
<system.webServer>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
</system.webServer>

You may have some luck with doing a url-rewrite. This can be done very easily in the web.config or with an httpmodule.
Looks like you will still need to use a space or the IIS fix mentioned below for your + character issue, but for some flexibility in the future you can always include URL rewrites for mapping urls to files.
<httpModules>
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
</httpModules>
<rewriter>
<rewrite url="~/cats dogs/Default.aspx" to="~/MyRealFile.aspx" />
</rewriter>

Just put a space in the folder name: "cats dogs".
The space character is encoded using the plus character, so when the server sees the plus character, it will get the folder with the space in it.

Related

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.

Physical Folder Breaks ASP.NET URL Routing on IIS Express

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

Custom Sharepoint webservice requires web.config to be "touched" regularly

We have a site running on MOSS 2007 which makes calls to custom web service asmx methods on the same domain from the client.
At first everything works fine, but after a bit of time has passed the service will start to fail with:
http://[domain]/_layouts/error.aspx?ErrorText=Request format is unrecognized for URL unexpectedly ending in %27%2FIsSuspectWaterLevel%27.
Interestingly enough
http://[Domain]/_vti_bin/Custom/CustomFunctionality.asmx?op=IsSuspectWaterLevel
is still available, but a call to
http://[Domain]/_vti_bin/Custom/CustomFunctionality.asmx/IsSuspectWaterLevel
will fail as described.
We've found that "touching" C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\ISAPI\ web.config will bring the webservice back to life.
The asmx file lives at
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\ECan\MyECan_ComplianceWaterUsage.asmx
Any ideas of what might be going on here and how to resolve them?
Some extra detail:
App pool settings in case they're useful: http://i51.tinypic.com/x51qw.png
The following web.config settings are present in the root and sub directory hosting the asmx:
<system.web>
<webServices>
<protocols>
<add name="HttpSoap" />
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
</webServices>
...
</system.web>
We are calling the web service from javascript (jQuery). I've checked all the settings mentioned in this link and all match. I think calling from javascript may not be the culprit though as going directly to
[domain]/_vti_bin/Custom/CustomFunctionality.asmx/IsSuspectWaterLevel
with parameters supplied also fails with the same error - no javascript involved. Failing after a short period of time has passed, but works fine when web.config has just been "touched" again.
Thanks in advance for any help! Cheers, Gavin
I'm currently working on the same problem, and I think you barked the wrong tree.
The problem is, that in the ISAPI folder of SharePoint is a web.config with the following lines:
<webServices>
<protocols>
<remove name="HttpGet"/>
<remove name="HttpPost"/>
<remove name="HttpPostLocalhost"/>
<add name="Documentation"/>
</protocols>
</webServices>
The problem is, that the desired protocols POST and GET will be removed for the entire ISAPI folder and its subfolders. I also tried to reactivate the protocols via
<location path="[Path to my Web Service].asmx" allowOverride="false">
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
</loaction>
in different places (machine.config, web.config of root folder, web.config app.config, ...), but it didn't last.
The only thing that worked, was, to change the "remove" items in the web.config of the ISAPI folder to "add" items.
But this has the nasty side effect, that the built-in web services, like "Lists.asmx" throw errors if you try to request their documentation pages...
If you can live with that, this would be your solution. I can't, so I still try to figure out a way to make my
<add name="protocol">
items persistent.
By the way: Also adding lockItem="true" to the <add/> items didn't do the trick...
Chris
It has been awhile since I have touched Sharepoint so this is a shot in the dark. If I remember correctly modifying anything in the web.config will restart the website in IIS. So what you may be seeing is IIS restarting the website that hosts the webservice putting it back into a good state.
Do you have the following in the web.config for the web application?
<webServices>
<protocols>
<add name="HttpGet"/>
<add name="HttpPost"/>
</protocols>
</webServices>
This is a strange problem and hard to diagnose due to the number of occcurances of the 12 hives web.config protocols issue which would appear to resolve 99% of the cases of this issue.
There is another issue called URL rewriting that will cause this
problem.
Some reverse proxy devices can modify the path of a request (the
portion of the URL that comes after the hostname and port number) in
such a way that a request sent by the user to
http://www.contoso.com/sharepoint/default.aspx, for example, is
forwarded to the Web server as
http://sharepoint.perimeter.example.com/default.aspx.
This is referred to as an asymmetrical path. Windows SharePoint
Services 3.0 does not support asymmetrical paths. The path of the URL
must be symmetrical between the public URL and the internal URL. In
the preceding example, this means that the "/sharepoint/default.aspx"
portion of the URL must not be modified by the reverse proxy device.
Even more depressing is that microsoft knows about this and actively refuses to support it.
Ref: URL Rewrite + SharePoint = No Support
Also : SharePoint, url rewriter, WebServices
An inelegant workaround to this issue that works for us: We've swapped out the web service asmx end point for a web handler ashx endpoint. This doesn't suffer the same issue for some reason.
I'm guessing from this that there's some issue creeping in after a period of time which is causing urls to resolve incorrectly. I suspect that the / after the .asmx in the url is the curprit. The ashx endpoint implemented is working purely on url parameters and posted data.
Obviously this work around won't always be an option for others who might experience the same issue as we're loosing a lot of the rich web service functionality that's pre-baked in to an asmx endpoint.
Unfortunately I won't be able to test any other solutions that people might put forward from now on as we've moved away from the web service asmx approach. Sorry. Thanks for all the suggestions though - it's been very much appreciated!

Executing a managed module for a rewritten URL in IIS7 Integrated Mode

In my ASP.NET app, I have two HTTP modules. One of them is used for rewriting URLs, the other is used for app-specific stuff (custom authentication .. etc). The URL-Rewriting module is executed for all requests, while the other module is only executed for managed file extensions, like .aspx
Here's how the modules are defined in web.config (note that preCondition is blank for UrlRewriteModule. This cause it to get executed for all requests):
<system.webServer>
<modules>
<add name="UrlRewriteModule" type="MySite.UrlRewriteModule" preCondition="" />
<add name="SiteModule" type="MySite.SiteModule" preCondition="managedHandler" />
</modules>
</system.webServer>
In UrlRewriteModule I use RewritePath() to rewrite some URLs (directory-like) into files with query strings. For example, from "/p/5/some-thoughts-about-the-future/" to "/post.aspx?id=5"
Now, I was under the impression that when a URL gets rewritten, IIS7 executes the managed module (SiteModule in this case) if the new URL is for a managed extension (like .aspx). But, this doesn't seem to be the case. I noticed that SiteModule doesn't get executed for any rewritten URLs.
Am I missing something (or doing something wrong) or is this the normal behavior in IIS7?
I came across Server.TransferRequest() which actually solves the problem (behind the scence, it involves creating a new child request). But, this can also cause a lot of overhead esp. under server load, and I generally prefer to avoid it.
So, is there a way to get SiteModule to execute whenever a URL gets rewritten without using Server.TransferRequest()?
Thanks!

CastleProject *.vm HttpForbiddenHandler not work

I try to use HttpForbiddenHandler to block the file without success. The web.config is as follows:
<httpHandlers>
<add verb="*" path="*.ashx" type="Castle.MonoRail.Framework.MonoRailHttpHandlerFactory, Castle.MonoRail.Framework"/>
<add verb="*" path="*.vm" type="System.Web.HttpForbiddenHandler"/>
</httpHandlers>
I have setup the virtual directory to forward .vm request to aspnet_isapi.dll too. Basically I have followed this guide:
http://support.microsoft.com/kb/815152
Any idea why it doesn't work? I am using Windows XP + IIS 5.1 to test it.
Update: Further diagnostic test pushing me to hell. I try to delete .config binding in ISAPI list, as expected the file is served. The I add everything back, and this time, instead of showing 'File type not served', it shows me 'No http handler was found for request type 'GET' ! I am completely pissed off, is that just IIS 5.1 for XP or I did something fishy?No I just scared myself on this- when I troubleshoot I tried to remove all httpHandlers using . But the .vm not being blocked issue still exist.
Ignore this one. Page cache hurts.

Resources