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
21/11/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
|
|
|