How can I capture and handle static file requests with asp.net?
I've tried the "IModule" and "Global.asax" with BeginRequest but
the request is not captured.
Is there some setting in IIS to direct some Component (IModule / Handler / Global.asax / DLL) in asp.net?
Or some way to direct requests to some DLL made with C #?
For example:
"get http://localhost/myapp/report/report1.html"
How can I capture this request?
I could not do, get in asp.net.
I want to be able to check the permission, and can handle the file, and handle the response.
The simplest way if you are running the Application Pool in Integrated mode is to tell IIS to send all requests to the "Managed Handlers".
In your web.config you should have a <system.webServer> element which may have a modules element - update that to:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
[...]
With that in place you'll be able to use all the standard features of ASP.NET including authentication control on paths.
Note that this will send all requests through your application, so you'll see requests for .css and .js files in there as well so if you do try locking everything down you'll need to leave those open.
Yes, IIS has such setting, Handler Mapping.
The setting determines with handlers would be called for different file extensions. Set the ASP.NET handler to desired extensions, and the you can use ASP.NET features (IHttpModel and other) to capture.
Related
I have a website running on IIS 7.5 which I can only access using FTP. (So I won't be able to use IIS Manager.)
I want to reorganise the URL structure, so I've modified the Global.asax code to look for the old URLs and Response.Redirect them to their new location. This works great for some of the URLs but not all.
With some experimentation, I found that when the old URL has a dot (eg, http://example.com/hello.html) then my global.asax code doesn't run. If I remove the file extension part of the URL, the global.asax code runs fine.
Those URLs with .html etc on the end are already out there and I can't change them now.
What do I need to do please?
What's happening is that IIS thinks your request for "/hello.html" is a static file and tries to serve it up directly without handing it off to your ASP.ENT application (before it gets to the routing in your Globals.asax file).
To change this behavior, you need to tell IIS to send these requests to your ASP.NET app instead of handling them itself. You can do this in your web.config file:
<system.webServer>
<handlers>
<add name = "LetMeHandleMyOwnStaticContent" path ="/*" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersion4.0"/>
</handlers>
</system.webServer>
Note, this will make you handle ALL of the static files (be prepared to handle the .js files, .css files, .html files, .png files, etc.) through your app. You can manipulate the path and verb to narrow down what you want to serve through your app. You can add multiple filters by repeating the "add" element (just use a unique name for each path).
I have a gridview in which one column contains images. I have used lightbox to zoom the clicked image. But when I right click on the image and select an option "Open link in new tab" then the image gets opened in a new tab. that's not a problem.
After that I press log out button. Now I copy that image link and I paste it on the address bar, the same picture get's opened. I want that first it should be checked whether the user has logged in or not and then open the image if he has logged in otherwise not.
All the images of the gridview are stored in a folder named "product images".
I am already checking login status on the page where gridview is used.
Tell me what to do.
Your problem is that security trimming is not applied on your images.
Static resources do not follow the same route as an asp.net page so security trimming is not applied on images.
As long as you have a web.config file that do not allow unauthorized users in that images folder, you could handle the problem by setting at web.config => system.webServer => modules
<modules runAllManagedModulesForAllRequests="true">
... but this would mean that all resources would be routed through the asp.net pipeline which would could generate performance issues.
In response to you question (my solution):
I would actually go through another way, which would be a little more difficult, which would be:
Make the folder product images invisible to any user by using iis Request Filtering (=>Hidden Segments=> Disallow access to that folder)
Then create a custom http handled (.ashx file) in which I would have the image name as a parameter. That handler at ProcessRequest would get the image parameter, open the specific file and stream the data from the image to response.)
That handled could be easy under security trimming, as long as it goes through ASP.NET pipeline so users not logged in would not have access to the handler. Performance would be some slower but only for those specific images. Also note that you should change any direct calls to the images. For example, if you had src='/product images/imageA.png', this should change as src='/ImagesHandler.ashx?image=imageA.png'.
After your comment on difficulty and Abhishek Punj answer I would like to mention:
My solution wouldn't need to register handlers for each file type (what if you add a .jpg file type afterward and haven't registered it?).
Also, even with Abhishek Punj answer you would still need to stream
image data from the image file to response.
In addition, with my solution, you won't need to custom check for
user permissions at ProcessRequest but ASP.NET security trimming
would handle it.
Also, my solutions tries to "protect the folder"
where Abhishek Punj tries to "protect the file type globally".
But most important, Abhishek Punj answer means that ALL IMAGES would go through the ASP.NET pipeline which means that if you had any
images at log on form for example, they wont be shown to the user
too! After all, if you would hanlde all image file types, then why wouldn't you go with runAllManagedModulesForAllRequests="true", without any coding ?
You can create a new handler and register it in IIS for the type of extension that your image file has. In that handler on begin request you can check if the user is authenticated in using the Principle set by the forms authentication. This would not fire for all the static files and hence would perform better than the solution mentioned by George.
However there is one more problem that you will face.. all the static resources are cached by the browser and hence it might not send in a request to the server at all and just display the image to the user without authentication.
To deal with this problem you will need to set the no-cache header in the response from the custom handler you wrote in the first step so that the browser dosent cache the response and always hits the server to serve the response.
Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.
Hope this gives you the desired direction.
EDIT: Based on points raised by George
runAllManagedModulesForAllRequests="true" will not only be triggered for all images it will also be triggerd for all CSS files, and javascript files as well.. hence increasing the overhead.
If you want to specifically restrict files just in a specific directory a very simple way would be to mention the directory as a key in the config and do a regex comparison to check if the request is required to be authenticated or not.. this can also be extended to cater to various files or directories to be included or restricted with a custom configuration section as per need.
As far as registering the handler for requests with other file extensions is considered its a matter of seconds.. not a painful task.
My app is a very simple "one page" type app-
It has Default.aspx
I'm basically trying to get, for example:
www.myappurl.com/this is my text
I want to get hold of "this is my text" from the above example.
This will be displayed on the page (for now)
I didn't really want to have to use any complext url rewriting things for this...
(My hosting provider uses IIS6)
I tried using a 404 handler, but this is a bit long winded, and i'm using shared hosting, that can't set the "execute url" on custom 404 pages.
Any other ideas?
You can add a mapping for all requests with the * extension to the ASP.NET isapi dll (GET/POST) verbs. You will need to uncheck the "verify file is on disk" checkbox when mapping the extension in IIS. (In IIS7 integrated mode, you map the extension in the web.config as well). Note that this will caause everything to be served by asp.net, even images and script files, which can slow things down.
Then create a handler mapping in your web.config to a http handler you create.
From there, in the ProcessRequest() method of the handler, you have access to the HttpContext that spawned the request and can manipulate the URL from there.
That is the easiest option, you could also create a HttpModule, or have the default page at root redirect to http://www.domain.com/default.aspx/this is my text, in the code-behind of default.aspx, you will be able to get the text following the page and slash.
My question is simple (although the answer will most likely not be): I'm trying to decide how to implement a server side upload handler in C# / ASP.NET.
I've used both HttpModules (IHttpModule interface) and HttpHandlers (IHttpHandler interface) and it occurs to me that I could implement this using either mechanism. It also occurs to me that I don't understand the differences between the two.
So my question is this: In what cases would I choose to use IHttpHandler instead of IHttpModule (and vice/versa)?
Is one executed much higher in the pipeline? Is one much easier to configure in certain situations? Does one not work well with medium security?
An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. You can create your own HTTP handlers that render custom output to the browser.
Typical uses for custom HTTP handlers include the following:
RSS feeds To create an RSS feed for a Web site, you can create a handler that emits RSS-formatted XML. You can then bind a file name extension such as .rss to the custom handler. When users send a request to your site that ends in .rss, ASP.NET calls your handler to process the request.
Image server If you want a Web application to serve images in a variety of sizes, you can write a custom handler to resize images and then send them to the user as the handler's response.
An HTTP module is an assembly that is called on every request that is made to your application. HTTP modules are called as part of the ASP.NET request pipeline and have access to life-cycle events throughout the request. HTTP modules let you examine incoming and outgoing requests and take action based on the request.
Typical uses for HTTP modules include the following:
Security Because you can examine incoming requests, an HTTP module can perform custom authentication or other security checks before the requested page, XML Web service, or handler is called. In Internet Information Services (IIS) 7.0 running in Integrated mode, you can extend forms authentication to all content types in an application.
Statistics and logging Because HTTP modules are called on every request, you can gather request statistics and log information in a centralized module, instead of in individual pages.
Custom headers or footers Because you can modify the outgoing response, you can insert content such as custom header information into every page or XML Web service response.
From: http://msdn.microsoft.com/en-us/library/bb398986.aspx
As stated here, HttpModules are simple classes that can plug themselves into the request processing pipeline, whereas HttpHandlers differ from HttpModules not only because of their positions in the request processing pipeline, but also because they must be mapped to a specific file extensions.
IHttpModule gives you much more control, you can basically control all of the traffic directed to your Web application. IHttpHandler gives you less control (the traffic is filtered before it reaches your handler), but if this is sufficient for your needs, then I see no reason to use the IHttpModule.
Anyway, it's probably best to have your custom logic in a separate class, and then just use this class from either IHttpModule or IHttpHandler. This way you don't really have to worry about choosing one or the other. In fact, you could create an extra class which implements both IHttpHandler and IHttpModule and then decide what to use by setting it in Web.config.
15 seconds has a nice small tutorial giving practical example
Modules are intended to handle events raised by the application before and after the request is actually processed by the handler. Handlers, on the other hand, aren't given the opportunity to subscribe to any application events and, instead, simply get their ProcessRequest method invoked in order to the "main" work of processing a specific request.
Take a look at this documentation from Microsoft (about half way down the page in the "The request is processed by the HttpApplication pipeline" section):
http://msdn.microsoft.com/en-us/library/bb470252.aspx
You can see in step 15 where the handler gets its chance to execute. All of the events before and after that step are available for interception by modules, but not handlers.
Depending on what specific features you're trying to achieve, you could use either a handler or a module to implement an upload handler. You might even end up using both.
Something to consider might to use an upload handler that's already written.
Here's a free and open source one:
http://www.brettle.com/neatupload
Here's a commercial one:
http://krystalware.com/Products/SlickUpload/
If you look at the documentation for NeatUpload, you'll see that it requires you to configure a module.
I have a custom site I'm building with automatic url rewriting using a custom engine. The rewriting works fine as long as the page url doesn't end in somehting like .htm or .html. For these pages it goes directly to the iis 404 page instead of hitting my rewriting engine first.
I have the * wildcard handler in the "Home Directory" section of the IIS6 configuration of that website but these urls seem to be ignored by it (altho things like css, jpg, js, etc to get sent to the url handler in my web project). How do i set up IIS6 to force these urls to get sent to the handler, while still serving the page if it exists normally?
The handler basically does this
if (!File.Exists(Request.Path))
{
doMyRewriting();
}
I have to assume that using a block like this (just and example, the real one does some other stuff to format the Request.Path to be proper with everything) should run the "doMyRewriting()" if the requested file does not exist otherwise it will serve the page normally. Am I mistaken?
If I tell IIS specifically to send .htm and .html pages thru to the .NET handler the rewriting works but if the page is actually there it will not serve it.
Any help would be greatly appreciated.
Thanks in advance!
Don't know if you can or would want to do this, but there is the Ionics Isapi url rewriter you can use.
http://www.codeplex.com/IIRF
Basically install that then set a rule to remove the .html that way it hits your rewrite engine. I use it on IIS 6 with several of my blogs.
I think if you are having IIS send all requests to .NET and your handler, then your handler will need to detect if the page exists and serve it instead of rewriting.
UrlRewriting.NET has an option to do this - you might want to look at their code to see how they're handling this case.
In my opinion, rewriting URLs with IIS 6 is best handled with an ISAPI filter written as unmanaged native code. Otherwise, you run into the issues you've mentioned - having to map all extensions to ASP.Net and losing the ability for simple file handling. With an ISAPI filter, you can choose to not rewrite some URLs and let IIS handle them as normal.
To get started, I suggest reading the ISAPI Filter Overview on MSDN.
If your filter absolutely needs the .Net framework runtime, it is possible to write a small ISAPI filter shell that hosts the CLR and forwards the requests to some managed code. The Filter.Net Framework takes this approach and may be suitable for your needs. There is the small drawback to this approach in that you will have to use the same .Net version as any ASP.Net applications that are run in the main IIS process.