Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
di Fabio Yeon
Questo è un esempio di come scrivere un modulo nativo (C++) che inserirà in modo dinamico una filigrana configurata dall'utente in un'immagine gestita, nonché come estendere la configurazione e lo strumento dell'interfaccia utente inetmgr per fornire un'amministrazione semplice del nuovo modulo.
Il modulo watermark offre le funzionalità seguenti:
- Può essere abilitata/disabilitata a qualsiasi livello di configurazione (ad esempio sito, applicazione, directory virtuale e così via).
- Può filigrana i formati di immagine JPG, GIF e PNG.
- L'immagine della filigrana può essere in formato JPG, GIF o PNG. L'immagine filigrana non deve essere lo stesso tipo dell'immagine da filigrana(ad esempio, un'immagine di filigrana GIF può essere usata per filigrana una richiesta di immagine PNG).
- È possibile configurare la posizione dell'immagine della filigrana ("in alto a sinistra", "in alto a destra", "in basso a sinistra", "in basso a destra", "centrato", nonché le opzioni di "piastrellare" e "allungare"). Solo l'opzione "stretch" modificherà l'immagine della filigrana, se necessario.
- È anche possibile selezionare il livello di trasparenza dell'immagine della filigrana, da 0 a 100%.
Per compilare l'esempio, è necessario installare Platform SDK per Windows Vista o Windows Server 2008. Il file di progetto incluso nell'esempio può essere caricato in Visual Studio 2005 o 2008.
Il codice sorgente per questi esempi è disponibile qui.
Il modulo filigrana
Il primo componente di questo esempio è il modulo watermark stesso. Si tratta di un modulo C++ nativo che controlla come vengono gestite le richieste e se il tipo MIME della richiesta indica che è un'immagine, applicherà dinamicamente una filigrana configurata dall'utente all'immagine e sostituirà l'immagine in uscita. Questa operazione viene eseguita in modo trasparente in un modulo eseguito dopo il gestore della richiesta. Per illustrarlo:
- La logica del codice è piuttosto semplice:
- Quando il modulo viene caricato per la prima volta, viene registrato per l'evento post-RQ_EXECUTE_REQUEST_HANDLER, che indica al sistema che vuole ricevere una notifica subito dopo l'esecuzione del gestore della richiesta.
- Ora, quando viene generato l'evento post-RQ_EXECUTE_REQUEST_HANDLER, recupera la configurazione per il relativo percorso. Se non è abilitata, non farà altro per la richiesta e la cauzione.
- Se è abilitato, controlla l'intestazione della risposta "Content-Type" e verifica se si tratta di un tipo di immagine. In caso contrario, si interromperà.
- Se si tratta di un'immagine, verrà quindi visualizzato se la risposta è un buffer o un handle di file. Se è successivamente, caricherà l'immagine in memoria, applicherà la filigrana in base alle impostazioni configurate dall'utente (ad esempio file di immagine, posizione, trasparenza), salvare l'immagine risultante in un buffer in memoria, sostituire i dati di risposta con il buffer in memoria e restituire.
- Il buffer in memoria verrà rilasciato nel metodo "Dispose" del modulo.
L'uso delle classi CImage di ATL rende molto semplice il caricamento e l'elaborazione dell'immagine, soprattutto perché può modificare facilmente vari formati di immagine.
In questo esempio sono ora presenti alcune avvertenze e devono essere considerate, soprattutto se si vuole usarlo in un ambiente di produzione "reale":
- Il codice funziona solo per i tipi di immagine in cui la risposta si trova in un handle di file. L'oggetto HTTP_RESPONSE può invece contenere l'immagine in una serie di buffer. Un esercizio interessante consiste nel creare un'implementazione di IStream in memoria che avvolge i buffer nell'oggetto di risposta (prestare attenzione alle risposte con più buffer).
- Il modulo non tenta di modificare o aggiornare l'intestazione della risposta "ETag". Ciò significa che l'immagine con filigrana risultante verrà considerata l'immagine "reale" per quanto riguarda il client (come dovrebbe), ma può anche confondere la logica di memorizzazione nella cache del client. Un'implementazione corretta di questa operazione deve modificare "ETag" in modo da tenere conto della configurazione dell'immagine con filigrana. Ad esempio, nell'implementazione corrente, se è stata filigranata un'immagine con "WatermarkFileA" nella posizione "UpperLeft" con una trasparenza di "50%", e quindi è stata effettuata una richiesta con un browser (ad esempio Internet Explorer), Internet Explorer memorizza tale immagine nella cache in base alle varie intestazioni di risposta. Se si dovesse modificare la configurazione del modulo filigrana (ad esempio, è stata modificata l'immagine, la posizione o la trasparenza) e richiesto di nuovo il file (tramite "F5"), perché l'immagine è stata memorizzata nella cache da Internet Explorer, invece di richiedere l'immagine, si farebbe semplicemente una richiesta "HEAD", inviando le informazioni sull'immagine. Il gestore della richiesta, non sapendo che l'immagine è stata modificata, risponderà che la risposta inviata in precedenza è ancora valida e terminerà l'elaborazione della richiesta. Sfortunatamente, in questo caso, il modulo filigrana non avrà la possibilità di eseguire e ri-filigranare l'immagine con la nuova configurazione, quindi il client continuerà a mostrare felicemente l'immagine filigrana precedente. Una correzione adeguata per questo problema sarebbe che il modulo della filigrana incorpori in qualche modo la sua configurazione nell'"ETag" della risposta, in modo che qualsiasi modifica all'immagine o al modulo della filigrana causi l'invalidazione di qualsiasi immagine memorizzata nella cache del client e la sua rielaborazione.
Configurazione
La configurazione del modulo watermark viene eseguita tramite una nuova sezione nello spazio dei nomi "system.webServer". Il file di schema è il seguente:
<configSchema>
<sectionSchema name="system.webServer/watermark">
<attribute name="enabled" type="bool" defaultValue="false" />
<attribute name="watermarkImage" type="string" />
<attribute name="transparency" type="uint" defaultValue="50" validationType="integerRange" validationParameter="0,100" />
<attribute name="position" type="enum" defaultValue="LowerRight" >
<enum name="UpperLeft" value="0" />
<enum name="UpperRight" value="1" />
<enum name="LowerLeft" value="2" />
<enum name="LowerRight" value="3" />
<enum name="Center" value="4" />
<enum name="Stretch" value="5" />
<enum name="Tile" value="6" />
</attribute>
</sectionSchema>
</configSchema>
Il file "watermark.xml" deve essere eliminato nella %windir%\system32\inetsrv\config\schema directory per renderlo effettivo, oltre ad aggiungere la definizione di sezione nel file "applicationhost.config" , nello spazio dei nomi "system.webServer":
<section name="Watermark" overrideModeDefault="Allow" />
Per usare il modulo, è quindi necessario installare il modulo nell'elenco dei moduli globali "system.webServer\globalModules":
<add name="WatermarkModule" image="c:\Watermark\Watermark.dll" />
E all'elenco dei moduli per l'applicazione, "system.webServer\modules":
<add name="WatermarkModule" />
Inetmgr
Insieme al modulo di esempio, c'è un set di classi gestite che funzionano come plug-in gestionali per il nuovo strumento di amministrazione dell'interfaccia utente "Inetmgr". Sono disponibili varie altre documentazioni su come scrivere ed estendere il nuovo "Inetmgr", disponibile qui. In breve, per usarli, è necessario compilare, aggiungere le DLL alla GAC (Global Assembly Cache) e aggiungere la configurazione seguente al %windir%\system32\inetsrv\config\administration.config file:
Nell'insieme <moduleProviders> aggiungere la voce seguente:
<add name="Watermark" type="WatermarkServer.WatermarkModuleProvider, Watermarkserver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5f6f8f3f74d67fe4" />
Aggiungere la seguente riga alla raccolta <modules>.
<add name="Watermark" />
Riavviare lo strumento e nel sito dovrebbe essere disponibile una nuova icona.