Understanding and application of HttpHandler and HttpModule

  • 2020-06-01 09:23:06
  • OfStack

The mysterious HttpHandler and HttpModule

When I was in college, I started to learn asp.net from drag-and-drop controls, and I was not familiar with many library objects in.net. Therefore, when I see you write some unique asp.net nouns, I feel that asp.net is always shrouded in a veil of mystery, which makes me puzzled. HttpHandler and HttpModule used to be mysterious. Haha, today I will show you my understanding of him and his application.

Maybe you don't understand HttpHandler and HttpModule. Maybe you don't know what HttpHandler and HttpModule are for. Maybe you don't understand. Today,, please let me lead you to appreciate 1 HttpHandler and HttpModule elegant demeanor, today I want to let him become So Easy!!

Understand the asp.net pipeline incident

What is asp? net pipeline? Simply put, it's the life cycle of the page, which is the series of events that asp.net does from the moment you request the page to the moment it is displayed in your browser. These events are shown below (see Fish Li).

1. Verify the request by checking the information sent by the browser to see if it contains potentially malicious markup. For more information, see ValidateRequest and script intrusion overview.

2. If any URL has been configured in the UrlMappingsSection section of the Web.config file, the URL mapping is performed.

3. Trigger BeginRequest incident.

4. AuthenticateRequest incident was triggered.

5. PostAuthenticateRequest incident was triggered.

6. AuthorizeRequest incident was triggered.

7. Trigger PostAuthorizeRequest incident.

8. ResolveRequestCache incident was triggered.

9. Raises the PostResolveRequestCache event.

10. The request is processed by selecting the class that implements IHttpHandler based on the file extension of the requested resource (mapped in the application's configuration file). If the request is for an object derived from the Page class

If you need to compile the page, ASP.NET compiles the page before creating an instance of it.

11. PostMapRequestHandler incident was triggered.

12. Trigger AcquireRequestState incident.

13. PostAcquireRequestState incident was triggered.

14. PreRequestHandlerExecute incident was triggered.

15. Call the ProcessRequest method of the appropriate IHttpHandler class (or the asynchronous version of IHttpAsyncHandler.BeginProcessRequest) for this request. For example, if the request is for a page, then

The current page instance will process the request.

16. Raises the PostRequestHandlerExecute event.

17. ReleaseRequestState incident is triggered.

18. PostReleaseRequestState incident is triggered.

19. If the Filter property is defined, a response filter is performed.

20. UpdateRequestCache incident was triggered.

21. PostUpdateRequestCache incident is triggered.

22. Trigger EndRequest incident.

23. PreSendRequestHeaders incident is triggered.

24. PreSendRequestContent incident was triggered.

Note:

1. Remember the above events, not to write, their order is not to write. They are triggered from 1 to 2104, from top to bottom, from the beginning of the page request to the end of the page presentation.

2. Not every event that starts with BeginRequest will be triggered, because Response.End () can be called at any time during the whole process, or the whole process can be terminated early due to the occurrence of an unhandled exception. Of all the events, only the EndRequest event is certain to be triggered, and the BeginRequest (partial Module) may not be triggered either.

3. If it is IIS7, the 10th event is MapRequestHandler event, and two other events, LogRequest and PostLogRequest, have been added before EndRequest. MapRequestHandler, LogRequest, and PostLogRequest events are supported only when the application is running in IIS 7.0 integration mode and is running with.NET Framework 3.0 or later 1.

Summary: these events are free to add methods, classes, properties, etc. To the events you need. That means we used to program at the page level, but now we can process projects at the request level, handle requests. How to do this depends on the magic of HttpMoudle and HttpHandler below.

Understand HttpHandler and HttpModule

Said HttpHandler first.

First of all you should understand what asp.net does with our request file, not to mention asp.net's trivial and seemingly lower level mystery, so what does net do with our request file? Let me show you something.


Open C:\WINDOWS\ Microsoft.NET \Framework\ v2.0.50727 \CONFIG\ CONFIG/config Find the httpHandlers node and see what it says below. If you don't want to open it, look at me.


View Code 
<httpHandlers>
      <add verb="*" path="*.rules" type="System.Web.HttpForbiddenHandler" validate="true"/>
      <add verb="*" path="*.xoml" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>
            <add path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="false"/>
            <add path="trace.axd" verb="*" type="System.Web.Handlers.TraceHandler" validate="True"/>
            <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True"/>
            <add path="*.axd" verb="*" type="System.Web.HttpNotFoundHandler" validate="True"/>
            <add path="*.aspx" verb="*" type="System.Web.UI.PageHandlerFactory" validate="True"/>
            <add path="*.ashx" verb="*" type="System.Web.UI.SimpleHandlerFactory" validate="True"/>
            <add path="*.asmx" verb="*" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" validate="False"/>
            <add path="*.rem" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False"/>
            <add path="*.soap" verb="*" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" validate="False"/>
            <add path="*.asax" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.ascx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.master" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.skin" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.browser" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.sitemap" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.dll.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="True"/>
            <add path="*.exe.config" verb="GET,HEAD" type="System.Web.StaticFileHandler" validate="True"/>
            <add path="*.config" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.cs" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.csproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.vb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.vbproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.webinfo" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.licx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.resx" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.resources" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.mdb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.vjsproj" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.java" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.jsl" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.ldb" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.ad" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.dd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.ldd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.sd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.cd" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.adprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.lddprototype" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.sdm" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.sdmDocument" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.mdf" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.ldf" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.exclude" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*.refresh" verb="*" type="System.Web.HttpForbiddenHandler" validate="True"/>
            <add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True"/>
            <add path="*" verb="*" type="System.Web.HttpMethodNotAllowedHandler" validate="True"/>
        </httpHandlers>

The above code is interpreted as: in < httpHandlers > Node in a different file type mapping to different Handler to deal with, for. aspx, is by System Web. UI. PageHandlerFactory to deal with. And for.cs, it's handled by System.Web.HttpForbiddenHandler...

The above is the default Handler processing, of course, after knowing HttpHandler, we can also register our own HttpHandler, write our own HttpHandler handler, handle different types of files, I'll implement this later, I'll show you.

Question: since the purpose of HttpHandler is to map files with suffixes of different types in the request to different handlers for processing, what about the time in the page's life cycle that the handler maps to process the request?

Answer: according to the 24 events above, the mapping in the HttpHandler node was triggered in step 10. It maps to different handlers whose implementations of methods and classes are triggered at step 15.

Besides HttpModule.

HttpHandler is a file of type 1 that maps requests to the specified handler. And the mapping, as well as the processing, occurs in the event that asp.net has specified.

HttpModule maps all request files to the specified handler to process the request, which can occur in any one event in the request pipeline. In other words, if you subscribe to an event, the write processing will take place in that event, and then execute it after processing, the next event of the event that you subscribed to, and of course you can terminate all the events and run the last event directly, which means that he can deny HttpHandler the opportunity, which is awesome HttpModule.

The use of HttpHandler

The use of HttpHandler is demonstrated with an anti-hotlinking technique

1. Register HttpHandler first: register in Web.config


<httpHandlers>
                <!-- mapping jpg Format the file to ProcessHandler_test.CustomHandler To deal with. -->
                <!--type Inside before the comma   Namespace plus class name ( ProcessHandler_test.CustomHandler ), followed by the assembly name -->
                <add path="*.jpg" verb="*" type="httphander_test.CustomHandler, ProcessHandler_test" />
            </httpHandlers>

The above registration maps requests for jpg files in the web site to the ProcessHandler_test assembly named CustomHandler with the namespace httphander_test to process the requests.

2. If you want to process requests through HttpHandler, you must implement the interface IHttpHandler in the mapped handler

3. The program code mapped to is as follows


View Code 
namespace httphander_test
{
    public class CustomHandler :IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            //  Gets the physical path to the file server side 
            string FileName = context.Server.MapPath(context.Request.FilePath);
            //  if UrlReferrer Is empty, then displays 1 An image that by default disables hotlinking 
            if (context.Request.UrlReferrer.Host == null)
            {
                context.Response.ContentType = "image/gif";
                context.Response.WriteFile("/error.gif");
            }
            else
            {
                //  if  UrlReferrer Does not contain its own site host domain name, then display 1 An image that by default disables hotlinking 
                if (context.Request.UrlReferrer.Host.IndexOf("yourdomain.com") > 0)
                {
                    context.Response.ContentType = "image/gif";
                    context.Response.WriteFile(FileName);
                }
                else
                {
                    context.Response.ContentType = "image/gif";
                    context.Response.WriteFile("/error.gif");
                }
            }
        }
 
        public bool IsReusable
        {
            get { throw new NotImplementedException(); }
        }
    }
}

Copy the above simple example of the code by clicking Ctrl+C. If a request is made for an Jpg file instead of the domain name of this website, a specified error image will be printed to replace the original connection image.

Conclusion: httpHandler has more functions than these. I hope you can understand that it handles the request for 1 type of file, and I also hope you can understand its event location in the request pipeline, which will be more helpful for you to understand.

The use of HttpModule

Because of the powerful function of HttpModule, that is to say, any request must go through the registered HttpModule handler. Therefore, when using HttpModule, we must make a good judgment on all kinds of requests. In other words, when handling any request, let the request go through the handler, and don't let it execute every method. If you don't let the program load, it's not worth the cost.

The steps for using HttpModule are similar to HttpHandler, while HttpModule implements the IHttpModule interface.

I'm not going to write a specific case here, but I wrote a case where Url was rewritten using it, and you can look at it. The link is: url rewrite


Related articles: