Imports System
Imports System.Web
Imports System.Text.RegularExpressions
Imports System.Configuration
Imports System.Xml.Linq
Imports System.Web.UI

Namespace URLRewriter
    Public Class RewriterModule
        Implements IHttpModule
        Sub Dispose() Implements System.Web.IHttpModule.Dispose

        End Sub

        Public Sub Init(ByVal app As HttpApplication) Implements System.Web.IHttpModule.Init
            AddHandler app.AuthorizeRequest, AddressOf Me.URLRewriter
        End Sub

        Protected Sub URLRewriter(ByVal sender As Object, ByVal e As EventArgs)
            Dim mReUrl() As String = BaseFunction.PublicMethod.GetApplication("URLRewrite").ToLower.Split(",")
            Dim app As HttpApplication = DirectCast(sender, HttpApplication)
            Dim requestedPath As String = app.Request.Path
            If Not mReUrl.Contains(IO.Path.GetExtension(requestedPath).ToLower) Then Exit Sub
            Dim requestFile As String = IO.Path.GetFileName(requestedPath)
            If requestFile IsNot Nothing AndAlso requestFile.Length > 0 Then
                Dim RealFilePath As String = app.Context.Server.MapPath(requestedPath)
                If IO.File.Exists(RealFilePath) Then Exit Sub
            End If
            Dim db As New DB_Template.DB_TemplateDataContext
            Dim mSiteID As Integer = CType(BaseFunction.PublicMethod.GetApplication("SiteID"), Integer)
            Dim mRules = DB_Template.clsTemplateURL.GetLinq(mSiteID)
            Dim RulesList As List(Of DB_Template.TemplateURL) = XrenCache.XrCache.GetList(db, "Rules" & mSiteID.ToString, mRules, XrenCache.XrCache.CacheLifeType.Relative, "1440", , , , True)
            If Not IsNothing(RulesList) AndAlso RulesList.Count > 0 Then
                Dim RuleValue = (From v In RulesList _
                                 Let lookFor = "^" & RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, v.LookFor) & "$" _
                                 Let re = New Regex(lookFor, RegexOptions.IgnoreCase) _
                                 Where re.IsMatch(requestedPath) = True _
                                 Select v).FirstOrDefault
                If Not IsNothing(RuleValue) Then
                    Dim lookFor As String = "^" & RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, RuleValue.LookFor) & "$"
                    Dim re As New Regex(lookFor, RegexOptions.IgnoreCase)
                    Dim sendToUrl As String = RewriterUtils.ResolveUrl(app.Context.Request.ApplicationPath, re.Replace(requestedPath, RuleValue.SendTo))
                    Dim FilePath As String = app.Server.MapPath(IO.Path.GetDirectoryName(sendToUrl) & "\" & IO.Path.GetFileName(sendToUrl).Split("?")(0))
                    If IO.File.Exists(FilePath) Then
                        Dim mCheckFile As Boolean = CType(BaseFunction.PublicMethod.GetApplication("CheckFile"), Boolean)
                        If mCheckFile Then
                            Dim mFileInfo As New IO.FileInfo(FilePath)
                            Dim mFileTime As Date = mFileInfo.LastWriteTime
                            Dim mSpan As TimeSpan = RuleValue.LastWriteTime - mFileTime
                            If mSpan.Seconds = 0 Then
                                RewriterUtils.RewriteUrl(app.Context, sendToUrl)
                            Else
                                Dim mFileName As String = IO.Path.GetFileName(FilePath).Replace(IO.Path.GetExtension(FilePath), "")
                                Dim mTmpList As New DB_Template.clsTemplateList
                                Dim mTmp As DB_Template.TemplateList = mTmpList.GetSingle(mFileName)
                                Dim clsTMP As New DB_Template.FormatTmplate
                                If clsTMP.FormatSaveFile(BaseFunction.PublicMethod.Base64DecryptData(mTmp.TmpContent), mFileName, mTmp.ClassID, mTmp.TmpName, mTmp.ID) Then
                                    RewriterUtils.RewriteUrl(app.Context, sendToUrl)
                                Else
                                    RewriterUtils.RewriteUrl(app.Context, "/ErrorPage.aspx")
                                End If
                            End If
                        Else
                            RewriterUtils.RewriteUrl(app.Context, sendToUrl)
                        End If
                    Else
                        RewriterUtils.RewriteUrl(app.Context, "/ErrorPage.aspx?path=" & FilePath)
                    End If
                End If
            End If
        End Sub
       
    End Class

    Friend Class RewriterUtils
        Friend Shared Sub RewriteUrl(ByVal context As HttpContext, ByVal sendToUrl As String)
            Dim sendToUrlLessQString As String
            If context.Request.QueryString.Count > 0 Then
                If sendToUrl.IndexOf("?"c) <> -1 Then
                    sendToUrl += "&" & context.Request.QueryString.ToString()
                Else
                    sendToUrl += "?" & context.Request.QueryString.ToString()
                End If
            End If

            Dim queryString As String = [String].Empty
            sendToUrlLessQString = sendToUrl
            If sendToUrl.IndexOf("?"c) > 0 Then
                sendToUrlLessQString = sendToUrl.Substring(0, sendToUrl.IndexOf("?"c))
                queryString = sendToUrl.Substring(sendToUrl.IndexOf("?"c) + 1)
            End If
            context.RewritePath(sendToUrlLessQString, [String].Empty, queryString)
        End Sub

        Friend Shared Function ResolveUrl(ByVal appPath As String, ByVal url As String) As String
            If IsNothing(url) Then url = ""
            If url.Length = 0 OrElse url(0) <> "~"c Then
                Return url
            Else
                If url.Length = 1 Then
                    Return appPath
                End If
                If url(1) = "/"c OrElse url(1) = "\"c Then
                    If appPath.Length > 1 Then
                        Return (appPath & "/") + url.Substring(2)
                    Else
                        Return "/" & url.Substring(2)
                    End If
                Else
                    If appPath.Length > 1 Then
                        Return (appPath & "/") + url.Substring(1)
                    Else
                        Return appPath + url.Substring(1)
                    End If
                End If
            End If
        End Function
    End Class

End Namespace