Makale Özeti

HttpModule nedir? Nasıl uygulanır.

Makale

HttpModule

Web sunucusuna (IIS) bir istek geldiğinde sunucu gelen istekde talep edilen dosya uzantısına göre isteğe nasıl cevap verileceğini belirler. Talep edilen dosyanın uzantısı ISAPI Extensions mapping listesinde yer alan bir uzantı ise istek ISS tarafından ilgili ISAPI Extension'a aktarılır. ASP.NET uygulamalarında kullanılan uzantılar olan .aspx,.asmx,.ascx ve diğer uzantılar ISS üzerinde ISAPI Mapping tablosunda aspnet_isapi.dll dosyasına map edilmişlerdir. aspnet_isapi.dll ISS üzerinde ISAPI extension olarak çalışan ve istekleri ASP.NET Worker Process'e (aspne_wp.exe) aktarmaktır. 

Mapping işlemi .NET Framework kurulduğunda otomatik yapılmaktadır. Ancak önce .NET Framework'ün daha sonra ISS'in kurulması gibi durumlarda .NET Framework ile beraber gelen aspnet_regiis uygulaması -i parametresi ile çalıştırılarak bu mapping işleminin yapılması sağlanabilir. (aspnet_regiis -i)

 

IIS, aspnet_isapi.dll, aspnet_wp.exe, tüm bu katmanların dahil olduğu işlemler dizesine HTTP Pipeline denir.

Yukarıdaki ilk paragrafta anlatığımız HTTP Pipeline'ın işleyişini özetlemektedir.

Şema da verilen OutputCache ve BenimModulum adındaki iki Http Module örnek olarak gösterilmiştir. Http module'ler belirlenmiş bir arayüzü (IHttpModule) implemente eden sınıflardır. Http Module ler bir istek yapılmadan önce ve yapıldıktan sonra işlemler gerçekleştirebilir.

.NET Framework'de önceden tanımlı Http Module'ler vardır. Bunlar nerede tanımlıdır? Bildiniz Machine.config. Machine.Config içeriğine göz atacak olursak bize hiç de yabancı gelmeyecek bazı isimlerde Htpp Module tanımlamaları yapıldığını görebiliriz.

Burada görüldüğü gibi ASP.NET bazı işlevlerini yerine getirebilmek için sistem bazında Http Module'ler tanımlar. Örneğin OutputCache ile caching işlemlerini yönetir. Session ile session yönetimini sağlar. WindowsAuthentication,FormsAuthentication gibi moduleler ile güvenlik ile ilgili işlemleri gerçekleştirebilir. FileAuthorization disk üzerinde erişeceğimiz dosyalar üzerinde yetki kontrolü yapan bir module'dür.

Pipeline'a kendi HttpModule'ümüzü eklemek

HttpModule yazmak için uyulması gereken iki kural vardır. IHttpModule sınıfından miras alan bir sınıf oluşturmak ve bu sınıfı bir assembly'e derlendikten (Web uygulamasının assembly'si de olabilir.) sonra web.config dosyası ile Http Pipeline'a httpmodulun kayıt edilmesi gerekir.

Şimdi bir ASP.NET Web Application projesi açıp içerisine bir class dosyası ekleyip içeriğini aşağdaki şekilde düzenleyin.

Public Class BenimModule1

    Implements IHttpModule

    Public Sub Init(ByVal context As System.Web.HttpApplication) _

    Implements System.Web.IHttpModule.Init

 

    End Sub

    Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

 

    End Sub

End Class

IHttpModule interface'i implemente edildiği zaman Init ve Dispose adında iki metod implementasyonunu sağlar. Init HttpModule http pipeline'a dahil olurken çalıştırılır. Dispose ise HttpModule Http Pipeline'da işini bitirip sonlandıracağı zaman çağrılır. Dispose metoduna eğer CLR tarafından yönetilmeyen bir kod kullanmadıysak genellikle bir şey yazmayız. Eğer var ise kullandığınız kaynakların tüketimi için kullanırız. (Bilindiği gibi dispose metodu bu duruma özgü değil, IDisposable arayüzü implemente edilerek herhangi bir proje türündeki sınıflarda kullanabileceğimiz bir metottur.)

    1 Public Class BenimModule1

    2     Implements IHttpModule

    3 

    4     Public Sub Init(ByVal context As System.Web.HttpApplication) _

    5     Implements System.Web.IHttpModule.Init

    6         AddHandler context.BeginRequest, AddressOf beginrequest

    7         AddHandler context.EndRequest, AddressOf endrequest

    8     End Sub

    9     Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

   10         'var ise resourcelar serbest birakilir,yok edilir.

   11     End Sub

   12 

   13     Private Sub beginrequest(ByVal s As Object, ByVal e As EventArgs)

   14         Dim app As HttpApplication = CType(s, HttpApplication)

   15         app.Response.Write("request baslangici.<br>")

   16     End Sub

   17     Private Sub endrequest(ByVal s As Object, ByVal e As EventArgs)

   18         Dim app As HttpApplication = CType(s, HttpApplication)

   19         app.Response.Write("request sonu.")

   20     End Sub

   21 End Class

Yukarıdaki kod bloğu ile HttpModule ile HttpApplication nesnesine erişiyor ve örnek amacıyla iki olayı tetiklendiğinde çalışacak metodlar belirliyoruz.

Init metodunun aldığı HttpApplication türündeki parametre HttpModule'ün dahil olduğu HttpApplication nesnesini gösterir.

Bu noktada aklınıza Global.asax ile zaten HttpApplication nesnesinin olaylarını yakalayabildiğimiz gelmiş olabilir. Evet! Global.asax ile bunu yapabiliyoruz. Zaten Global.asax.vb (yada .cs) dosyasında tanımlanan sınıflar HttpApplication'dan miras almaktadır.

Niye HttpModule'ü tercih edeyim?

HttpModule kullanarak HttpApplication nesnesinin olaylarına erişmek daha moduler bir yapıya sahiptir. Web.config'e yapılacak bir satırlık ekleme ile HttpModule pipeline'a dahil edilir. İstendiği takdirde Pipeline'dan çıkarmak için web.config'de yapılacak bir düzenleme yeterlidir.

Global.asax dosyasına ihtiyacınız yoktur. Yukarıda da bahsettiğim gibi Web.config'de yapılacak bir eklenti ile devreye alınır.

Global.asax'de yazdığımız VB6 benzeri Session_Start, Application_BeginRequest gibi metodlar yerine daha object oriented bir yapı ile çalışabilirsiniz.

Örnek: "Role Based Security" için HttpModule kullanılması

Örneğin önceki makalelerimden Forms Authentication - Rol tabanlı güvenlik sistemi başlıklı makalede kullanıcılara rol atama işlemi HttpApplication nesnesinin AuthenticateRequest olayını yakalayan bir metod içerisinde gerçekleştiriliyordu. Aynı işlemi global.asax dosyasında yapmak yerine bir HttpModule ile daha kaliteli bir çözüm üretilebilir.

Örneğin önceki makalede ki işlevi aşağıda ki kod bloğu ile de sağlayabiliriz.

Imports System.Security.Principal

Imports System.Data.SqlClient

Public Class BenimModule1

    Implements IHttpModule

    Public Sub Init(ByVal context As System.Web.HttpApplication) _

    Implements System.Web.IHttpModule.Init

        AddHandler context.AuthenticateRequest, AddressOf authRequest

    End Sub

    Public Sub Dispose() Implements System.Web.IHttpModule.Dispose

        'var ise resourcelar serbest birakilir,yok edilir.

    End Sub

    Private Sub authRequest(ByVal sender As Object, ByVal e As EventArgs)

        Dim app As HttpApplication = CType(sender, HttpApplication)

        If Not app.User Is Nothing AndAlso app.User.Identity.IsAuthenticated = True Then

            Dim roller() As String = UyeRoller.GetRoles(app.User.Identity.Name)

            HttpContext.Current.User = New GenericPrincipal(app.User.Identity, roller)

        End If

    End Sub

End Class

Public Class UyeRoller

    Public Shared Function GetRoles(ByVal uyeid As Integer) As String()

        Dim liste As New ArrayList

        Dim con As New SqlConnection("server=.;database=Uyelik;user id=sa;password=;")

        Dim cmd As New SqlCommand("", con)

        cmd.CommandText = "SELECT RoleName from roles where roleID IN (select roleID from uyerole where uyeID=@UyeID)"

        cmd.Parameters.Add("@UyeID", uyeid)

        con.Open()

        Dim rdr As SqlDataReader

        rdr = cmd.ExecuteReader

        While rdr.Read

            liste.Add(rdr("RoleName"))

        End While

        con.Close()

        Return liste.ToArray(GetType(System.String))

    End Function

End Class

HttpModule ile neler yapabilirim?

HttpModule kullanarak gerçek hayatta işinize yarayabilecek bir kaç senaryodan bahsedelim.

  • Url yönlendirme yapabilirsiniz. HttpModule'lerin (ve HttpHandler) en çok kullanıldığı senaryolardan birisi url yönlendirmedir. Örneğin konumu değişken dosyalarınıza gelen istekleri dosyanın yeni konumuna yönlendirebilirsiniz. Yada adres çubuğunda gözüken dosya ismi başka iken sayfayı üreten dosya adı baska olabilir. Kullanıcı gerçek dosya adı yerine sizin istediğiniz dosyayı görebilir.
  • Sayfalarınızda belirlediğiniz standart bölümlerin görüntülenmesini sağlayabilirsiniz. Örneğin istediğini bölümde görüntülenecek bir html kod parçası veya banner. (Bir sonraki makalemizde bu senaryo üzerine bir uygulama geliştireceğiz.)
  • Siteniz ile ilgili istatistiki bilgileri kayıt tutabilirsiniz. Hangi sitelerden tıklanıp gelinmiş, tarayıcısı vb. bilgileri elde edip kaydedip istatistik amaçlı kullanmak için en uygun yöntem bir HttpModule geliştirmek olacaktır.
  • Sitenizde barındırdığınız dosyaların (resim vb.) başka sitelerden kullanılmamasını sağlayabilirsiniz.

HttpModule çalışma prensibini öğrendikten sonra yukarıda bahsettiğim yada senaryonuz için uygun olan çözümler üretmek sizin elinizde. Yukarıda da bahsettiğim gibi HttpModule ile güzel bir uygulama örneği gerçekleştireceğimiz sonraki makaleye kadar, konu hakkında danışmak için iletişime geçebilirsiniz.