TuttoPC.Info
  Home  |  Hardware  |  Tips & Tricks  |  Reti & Sicurezza  |  E-Commerce  |  Tecnologie Web  |  Connessioni Internet/EMail  |  Glossario  |  Marketing e Web Marketing  |  Script e moduli per ASP.NET
   Sei in:  
Home \ Knowledge Base \ 
Sommario
Hardware
Tips & Tricks
Reti & Sicurezza
E-Commerce
Tecnologie Web
Connessioni Internet/EMail
Glossario
Marketing e Web Marketing
Script e moduli per ASP.NET
Registrazione File Hosting BETA
Login File Hosting BETA
Verifica configurazione DNS
Utility varie
Nuovo Blog
Ricerca nel sito
Segnala il sito a un amico
Se hai trovato questa pagina interessante, scrivilo ad un amico, clicca qui
NEW!! GiDiNet Web Directory
GiDiNet Directory è una Web Directory divisa in più aree tematiche in cui potrete trovare comodamente siti che trattano argomenti di vostro interesse, continua...
Statistiche
Oggi 29/03/2024
sei il visitatore n.
per un totale di visitatori dal 23/04/2007
Hai un problema particolare? Non trovi quello che stai cercando? clicca qui!
Script anti-hotlinking - ASP.NET 1.X
In questa pagina è presente una variante dello Script anti-hotlinking - ASP.NET 2.0 che può essere utilizzata sul .NET framework v1.*
Questa versione ha due limitazioni rispetto alla versione originale:
  • Dovendo utilizzare Response.WriteFile invece di Response.TransmitFile per l'invio del file al browser, il sistema può essere meno perfomante sui file di grandi dimensioni.
  • ASP.NET 1.X di default non blocca i file .exclude e la limitazione avviene quindi tramite IIS, in alcuni casi potrebbe essere permesso il download diretto dei file .exclude, questo anche se abbastanza raro è possibile e dipende dalla configurazione di IIS.

1. Installazione dello script

Per l'installazione dello script è necessario copiare il file "GiDiNet.AntiLeechHandler.dll" nella directory /bin e il file /Web.config.
Se il file /Web.config fosse già presente sullo spazio web, basterà modificarlo inserendo quanto riportato in grassetto nelle sezioni indicate.
Scarica i sorgenti completi, compreso il file dll

Codice del file AntiLeechHandler.vb:
'Copyright (C) 2007 Daniele Iunco

'This program is free software; you can redistribute it and/or modify
'it under the terms of the GNU General Public License as published by
'the Free Software Foundation; either version 2 of the License, or
'(at your option) any later version.

'This program is distributed in the hope that it will be useful,
'but WITHOUT ANY WARRANTY; without even the implied warranty of
'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
'GNU General Public License for more details.

'You should have received a copy of the GNU General Public License along
'with this program; if not, write to the Free Software Foundation, Inc.,
'51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

Imports System
Imports System.Configuration
Imports System.Web
Imports System.IO

Namespace GiDiNet

    'AntiLeechHandler v1.0 for .NET Framework v1.X
    'Author: Daniele Iunco
    'Date: 6th May 2007
    Public Class AntiLeechHandler
        Implements IHttpHandler

        Private Shared _Settings As AntiLeechSettings
        Private Shared ReadOnly Property Settings() As AntiLeechSettings
            Get
                If _Settings Is Nothing Then _Settings = New AntiLeechSettings()
                Return _Settings
            End Get
        End Property

        Private Enum ReturnType
            PageMissing = 0
            ImageMissing = 1
            PageNoLeech = 2
            ImageNoLeech = 3
        End Enum

        Private Sub ProcessInvalidRequest(ByRef Context As HttpContext, ByVal myType As ReturnType)
            'TODO: Qui si potrebbe sviluppare un sistema per registrare le richieste respinte

            Select Case myType
                Case ReturnType.PageMissing
                    Context.Response.Redirect(Settings.AntiLeechModule_MissingPageURL)
                Case ReturnType.ImageMissing
                    Context.Response.Redirect(Settings.AntiLeechModule_MissingImageURL)
                Case ReturnType.PageNoLeech
                    Context.Response.Redirect(Settings.AntiLeechModule_NoLeechPageURL)
                Case ReturnType.ImageNoLeech
                    Context.Response.Redirect(Settings.AntiLeechModule_NoLeechImageURL)
            End Select

        End Sub

        Public Sub ProcessRequest(ByVal Context As HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
            Dim myRequestPath As String = Context.Request.Path.ToLower()

            'Prelevo la configurazione della directory richiesta, se non la trovo restituisco la pagina di errore
            Dim myDirectory As ProtectedDirectory = Settings.GetProtectedDirectory(myRequestPath)
            If myDirectory Is Nothing Then
                'Se non ho trovato una directory restituisco la pagina di errore
                ProcessInvalidRequest(Context, ReturnType.PageMissing)
                Exit Sub
            End If

            'Questo primo controllo serve per evitare di eseguire troppe verifiche inutili: 
            'Se l'estensione più corta è di 3 caratteri e aggiungo 7 caratteri, la lunghezza del percorso richiesto deve essere per forza maggiore di 10 caratteri (la richiesta è nella forma "/percorso/a.ext.aspx")
            If myRequestPath.Length < myDirectory.PublicPath.Length + 10 Then
                ProcessInvalidRequest(Context, ReturnType.PageMissing)
                Exit Sub
            End If

            'Queste tre righe fanno una verifica davvero semplice sul referer, si potrebbero anche usare le espressioni regolari, fare attenzione a gestire i referer nulli
            'Volendo posso verificare in modo più approfondito se il file "localPath" può essere davvero scaricato (es. verificando estensione, percorso, autorizzazioni, etc)
            Dim myReferer As String = Context.Request.ServerVariables("HTTP_REFERER")
            If myReferer Is Nothing Then myReferer = ""
            Dim bIsValidReferer As Boolean = Settings.IsValidReferer(myReferer)

            'Preparo la stringa col percorso reale
            Dim newPath As String = myDirectory.PrivatePath & myRequestPath.Substring(myDirectory.PublicPath.Length)
            newPath = newPath.Substring(0, newPath.LastIndexOf("."))

            'Qui avviene l'impostazione del content type, se necessario aggiungere gli altri tipi di file
            If newPath.Substring(newPath.LastIndexOf(".") + 1).ToLower = "gif" Then
                If Not bIsValidReferer Then ProcessInvalidRequest(Context, ReturnType.ImageNoLeech) : Exit Sub
                Context.Response.ContentType = "image/gif"
            ElseIf newPath.Substring(newPath.LastIndexOf(".") + 1).ToLower = "zip" Then
                If Not bIsValidReferer Then ProcessInvalidRequest(Context, ReturnType.PageNoLeech) : Exit Sub
                Context.Response.ContentType = "application/x-zip-compressed"
            ElseIf newPath.Substring(newPath.LastIndexOf(".") + 1).ToLower = "jpg" Then
                If Not bIsValidReferer Then ProcessInvalidRequest(Context, ReturnType.ImageNoLeech) : Exit Sub
                Context.Response.ContentType = "image/jpeg"
            ElseIf newPath.Substring(newPath.LastIndexOf(".") + 1).ToLower = "png" Then
                If Not bIsValidReferer Then ProcessInvalidRequest(Context, ReturnType.ImageNoLeech) : Exit Sub
                Context.Response.ContentType = "image/png"
            Else
                If Not bIsValidReferer Then ProcessInvalidRequest(Context, ReturnType.PageNoLeech) : Exit Sub
            End If

            Dim localPath As String = Context.Server.MapPath(newPath) & ".exclude"

            If Not File.Exists(localPath) Then ProcessInvalidRequest(Context, ReturnType.PageMissing) : Exit Sub

            'Imposto il nome del file
            Context.Response.AddHeader("Content-Disposition", "attachment; filename=" & newPath.Substring(newPath.LastIndexOf("/") + 1))

            'Invio il file al browser, su ASP.NET 2.0 posso usare Response.TransmitFile per ridurre il carico di lavoro sul server, su ASP.NET 1.x dovrò usare Response.WriteFile
            Context.Response.WriteFile(localPath)
        End Sub

        Public ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable
            Get
                Return True
            End Get
        End Property

    End Class

    Public Class ProtectedDirectory
        Private _PublicPath As String
        Public ReadOnly Property PublicPath() As String
            Get
                Return _PublicPath
            End Get
        End Property

        Private _PrivatePath As String
        Public ReadOnly Property PrivatePath() As String
            Get
                Return _PrivatePath
            End Get
        End Property

        Public Sub New(ByVal PublicPath As String, ByVal PrivatePath As String)
            _PublicPath = PublicPath
            _PrivatePath = PrivatePath
        End Sub
    End Class

    Public Class AntiLeechSettings
        Public ReadOnly Property AllowedDomains() As String()
            Get
                Return _AllowedDomains
            End Get
        End Property

        Public ReadOnly Property ProtectedDirectories() As ProtectedDirectory()
            Get
                Return _ProtectedDirectories
            End Get
        End Property

        Public ReadOnly Property AntiLeechModule_NoLeechImageURL() As String
            Get
                Return _AntiLeechModule_NoLeechImageURL
            End Get
        End Property

        Public ReadOnly Property AntiLeechModule_NoLeechPageURL() As String
            Get
                Return _AntiLeechModule_NoLeechPageURL
            End Get
        End Property

        Public ReadOnly Property AntiLeechModule_MissingImageURL() As String
            Get
                Return _AntiLeechModule_MissingImageURL
            End Get
        End Property

        Public ReadOnly Property AntiLeechModule_MissingPageURL() As String
            Get
                Return _AntiLeechModule_MissingPageURL
            End Get
        End Property

        Private _AllowedDomains As String()
        Private _ProtectedDirectories As ProtectedDirectory()

        Private _AntiLeechModule_NoLeechImageURL As String
        Private _AntiLeechModule_NoLeechPageURL As String

        Private _AntiLeechModule_MissingImageURL As String
        Private _AntiLeechModule_MissingPageURL As String

        Public Sub New()
            'Caricamento delle varie impostazioni dal file di configurazione
            Dim myDomainNumberString As String = ConfigurationSettings.AppSettings("AntiLeechModule_DomainNumber")
            If IsNumeric(myDomainNumberString) Then
                ReDim _AllowedDomains(myDomainNumberString - 1)
            Else
                ReDim _AllowedDomains(0)
            End If
            Dim i As Integer
            For i = 1 To _AllowedDomains.Length
                Dim tmpItem As String
                tmpItem = ConfigurationSettings.AppSettings("AntiLeechModule_AllowedDomain_" & i)
                If Not tmpItem Is Nothing AndAlso tmpItem.Length > 0 Then
                    _AllowedDomains(i - 1) = tmpItem.Trim.ToLower
                Else
                    _AllowedDomains(i - 1) = ""
                End If
            Next

            _AntiLeechModule_NoLeechImageURL = ConfigurationSettings.AppSettings("AntiLeechModule_NoLeechImageURL")
            If _AntiLeechModule_NoLeechImageURL Is Nothing Then _AntiLeechModule_NoLeechImageURL = "/"
            _AntiLeechModule_NoLeechPageURL = ConfigurationSettings.AppSettings("AntiLeechModule_NoLeechPageURL")
            If _AntiLeechModule_NoLeechPageURL Is Nothing Then _AntiLeechModule_NoLeechPageURL = "/"

            _AntiLeechModule_MissingImageURL = ConfigurationSettings.AppSettings("AntiLeechModule_MissingImageURL")
            If _AntiLeechModule_MissingImageURL Is Nothing Then _AntiLeechModule_MissingImageURL = "/"
            _AntiLeechModule_MissingPageURL = ConfigurationSettings.AppSettings("AntiLeechModule_MissingPageURL")
            If _AntiLeechModule_MissingPageURL Is Nothing Then _AntiLeechModule_MissingPageURL = "/"

            Dim myProtectedDirectoryNumberString As String = ConfigurationSettings.AppSettings("AntiLeechModule_DirectoryNumber")
            If IsNumeric(myProtectedDirectoryNumberString) Then
                ReDim _ProtectedDirectories(myProtectedDirectoryNumberString - 1)
            Else
                ReDim _ProtectedDirectories(0)
            End If
            For i = 1 To _ProtectedDirectories.Length
                Dim tmpItem1, tmpItem2 As String
                tmpItem1 = ConfigurationSettings.AppSettings("AntiLeechModule_DirectoryPublic_" & i)
                tmpItem2 = ConfigurationSettings.AppSettings("AntiLeechModule_DirectoryPrivate_" & i)
                If Not tmpItem1 Is Nothing AndAlso tmpItem1.Length > 0 AndAlso Not tmpItem2 Is Nothing AndAlso tmpItem2.Length > 0 Then
                    _ProtectedDirectories(i - 1) = New ProtectedDirectory(tmpItem1, tmpItem2)
                Else
                    _ProtectedDirectories(i - 1) = New ProtectedDirectory("/", "/")
                End If
            Next

        End Sub

        Public Function GetProtectedDirectory(ByVal RequestPath As String) As ProtectedDirectory
            If RequestPath Is Nothing Then Return Nothing

            'Verifico se la directory della richiesta è una sottodirectory di un percorso protetto, e in questo caso restituisco i parametri di configurazione 
            Dim i As Integer
            For i = 0 To ProtectedDirectories.Length - 1
                If RequestPath.Substring(0, ProtectedDirectories(i).PublicPath.Length) = ProtectedDirectories(i).PublicPath Then Return ProtectedDirectories(i)
            Next

            Return Nothing
        End Function

        Public Function IsValidReferer(ByVal RefererString As String) As Boolean
            If RefererString Is Nothing Then Return False

            Dim i As Integer
            For i = 0 To AllowedDomains.Length - 1
                RefererString = RefererString.ToLower
                If RefererString.IndexOf(AllowedDomains(i)) >= 0 Then Return True
            Next

            Return False
        End Function

    End Class

End Namespace

Codice del file /Web.config:
Nota: Se sul server web è già presente un file web.config, modificare il file esistente inserendo le righe indicate in grassetto nelle rispettive sezioni (appSettings e httpHandlers)
<?xml version="1.0"?>
<configuration>
    <appSettings>
        <add key="AntiLeechModule_DomainNumber" value="3"></add>
        <add key="AntiLeechModule_AllowedDomain_1" value="http://www.primodominio.com"></add>
        <add key="AntiLeechModule_AllowedDomain_2" value="http://www.secondodominio.com"></add>
        <add key="AntiLeechModule_AllowedDomain_3" value="http://www.terzodominio.com"></add>
        <add key="AntiLeechModule_NoLeechImageURL" value="http://hostname.com/AlertImage.gif"></add>
        <add key="AntiLeechModule_NoLeechPageURL" value="http://hostname.com/AlertPage.htm"></add>
        <add key="AntiLeechModule_MissingImageURL" value="http://hostname.com/404.gif"></add>
        <add key="AntiLeechModule_MissingPageURL" value="http://hostname.com/404.htm"></add>
        <add key="AntiLeechModule_DirectoryNumber" value="2"></add>
        <add key="AntiLeechModule_DirectoryPublic_1" value="/directory1/"></add>
        <add key="AntiLeechModule_DirectoryPrivate_1" value="/directory1/secure/"></add>
        <add key="AntiLeechModule_DirectoryPublic_2" value="/directory2/"></add>
        <add key="AntiLeechModule_DirectoryPrivate_2" value="/directory2/secure/"></add>
    </appSettings>

    <system.web>
        <httpHandlers>
              <add verb="GET" path="*.zip.aspx" type="GiDiNet.AntiLeechHandler,GiDiNet.AntiLeechHandler"></add>
              <add verb="GET" path="*.jpg.aspx" type="GiDiNet.AntiLeechHandler,GiDiNet.AntiLeechHandler"></add>
              <add verb="GET" path="*.png.aspx" type="GiDiNet.AntiLeechHandler,GiDiNet.AntiLeechHandler"></add>
              <add verb="GET" path="*.gif.aspx" type="GiDiNet.AntiLeechHandler,GiDiNet.AntiLeechHandler"></add>
        </httpHandlers>
    </system.web>
</configuration>

2. Configurazione e uso dello script

Per la configurazione seguire le istruzioni della versione per ASP.NET 2.0 a questa pagina

4. File supportati

Il sistema creato supporta i file .zip, .gif, .png, .jpg, è possibile inserire ulteriori estensioni seguendo le istruzioni riportate nei commenti del codice sorgente.

5. Problemi noti

Il sistema può funzionare in modo non corretto con il browser Internet Explorer 6, se viene attivata la compressione HTTP lato server per i file aspx.

Pubblicato da: Daniele Iunco il 06/04/2007


Sei interessato a ulteriori informazioni su un particolare argomento? Potete contattaci attraverso l'apposito modulo.

ATTENZIONE: Le operazioni elencate nel sito possono avere esiti negativi o diversi da quanto indicato. Si consiglia di procedere con cautela.
Decliniamo ogni responsabilità per eventuali danni e/o malfunzionamenti derivanti dall'applicazione di ciò che è riportato in queste pagine.
Realizzazione a cura di GiDiNet