G.r.a. Capitolo 4: Lady Ceramica

Oggi prendo il raccordo dall’entrata de “La Rustica”, un posto semi abbandonato dagli dei che presto diventerà la prossima zona popolata di Roma; ogni percorso è valido pur di arrivare qualche entrata piu avanti su questa infernale pista Polistil a 3 corsie. Telecomando alla mano, pigio il pulsante, le spazzole scintillano e mi monodireziono sull’entrata..

Una melodia suonata con un flauto Shakuhachi, nella mente, mi sveglia dal torpore quotidiano e capisco subito il tema della giornata.. Tra i fiori di ciliegio, il vento, e questo fantastico giardino zen di 50km costruito intorno a veicoli in disuso da diverse ore, nella monotonia di questa monorotaia lenta e precisa,come in un film di Miyazaki entro in una dimensione onirica (perche sto ancora dormendo) , magica e fantastica, in cui strane e improbabili creature si avvicendano alla guida di mezzi immobili..

E tra un porco rosso che sorvola Anagnina, e un gatto taxi che saltella sui cartelli stradali, scrivendo Acab con la sua urina, arrivo cosi, chiacchierando con l’invisibile Totoro, con la mia macchina sul Raccordo Anulare e mi imbatto subito in Lady Ceramica, una strana sessantenne che incontro spesso. E’ talmente truccata che la sua faccia sembra fatta di porcellana. Ricorda molto le maschere del teatro Kabuki, solo che qui non siamo a Tokio, e quello non è un palco ma una Volvo 240 color panna del ’78 con interni rivestiti di peli di cane..

Lady Ceramica sarà alta un metro e tanti dubbi su quel metro, e già penso a Giacobbo che indaga sulla sua provenienza … sicuramente Atlantide transitando per l’egitto..

Dal finestrino di dietro un Carlino salta compulsivamente cercando di attirare l’attenzione, alitando e sbavando su tutto..

Lei impassibile, con gli occhi a binocolo, l’immancabile sigaretta lunga 20 cm in bocca, cerca di scrutare l’orizzonte e guida il suo Nautilus color panna come un freddo e calcolatore Capitano Nemo… Potete suonargli, lampeggiargli, lei è immobile..per alcuni l’unico elemento vivo in macchina è il Carlino che salta..

Sembra una nave fantasma nel mare di Bering.. I sedili strappati come vele divelte dal tempo e dalle intemperie..quest’aria di stato avanzato di decomposizione (dato anche dal colore sbiadito della macchina).. ci si aspetta da un momento all’altro di essere catturati da questo strano essere dall’innocuo aspetto di nonnetta dei cartoni giapponesi.. una sorta di Sakurambo al femminile,una Banshee nana, che sembra avere il doppio dei suoi anni..

Immobile come l’ambiente che la circonda e un cane epilettico in braccio, sembra la madre di Norman Bates, eppure è viva, e te ne accorgi quando prima di collidere con la macchina davanti a te a causa di un suo improvviso cambio di corsia, il suo collo si muove di mezzo grado, quanto basta per guardare con la coda della coda dell’occhio lo specchietto di destra, e con una calma che sfiora livelli da natura morta, mette la freccia a indicare che “si è spostata”.. un gesto faticoso e ritardato probabilmente dal sottile rigor mortis in arrivo…

Dietro di lei uno stormo impazzito di “Zero” giapponesi , gli scooteroni Mistubishi A6M, strombazzano sparando tutti i loro decibel in segno di protesta per la micidiale quanto kamikaze manovra che nemmeno a Pearl Harbor si era vista (ma questa è un altra storia).. La macchina davanti a me si ferma, io inchiodo, le passa, impassibile, il suo Carlino salta quasi sfottendo l’automobilista dietro di lui, il mega ingranaggio GRA ruota di qualche secondo, scatta il reset, ed il resto e’ la solita attesa..

Comprimere il contenuto di una risposta web, e analisi dell’Accept-Encoding

Il seguente articolo, è inerente c# e in particolare all’integrazione di un CompressionFilter nel  workflow di una chiamata web mediante il framework MVC2 di Microsoft, ma è applicabile in linea di massima a tutti i linguaggi. Si tratta fondamentalmente di applicare un algoritmo di compressione ai dati in output da una chiamata http, in modo da far viaggiare meno dati sulla rete, e accertarsi di quale metodi di compressione il client chiamante supporti.

Ci sono diversi tutorial sulla rete riguardo a questa problematica, ma è difficile trovare una risposta assoluta in quanto il vero problema non è la creazione di una funzione per la compressione (già implementate nei vari framework), ma nella decodifica corretta dell’Header Accept-Encoding che ci aiuta a dedurre che cosa supporti il chiamante, evitando così di applicare meccanismi di compressione non graditi o non supportati.

Banalmente basterebbe controllare se nell’header in questione sia presente la stringa gzip o deflate ,ad indicare che il client supporta i due algoritmi di compressione standard, ma in realtà le specifiche W3C sull’encoding, prevedono un funzionamento molto piu complesso.

 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Questo tipo di Headers si basano su un concetto di preferenza e pesi..

Alcuni esempi di valori possibili:

  • il più banale “gzip” oppure solo “deflate” ad indicare l’algoritmo desiderato.
  • “gzip,deflate” ad indicare la sequenza delle preferenze,
  • “gzip;q=0,deflate” ad indicare che gzip non dovrebbe minimamente essere usato (ha un peso Q pari a zero)
  • “gzip;q=0.4,deflate;q=0.4,identity;q=0.2″ ad indicare la ripartizione tra le preferenze..
  • identity sta a indicare che non va assolutamente usato un content-encoding.. se espresso senza q, il default sui parametri e’ q=1 e quindi avrebbe sempre la precedenda come in questo esempio: “gzip;q=0.5,deflate;q=0.5,identity”..
  • “*” sta invece a indicare qualsiasi encoding

Da quello che si evince e’ impossibile andare a cercare semplicemente se nella stringa sia presente gzip o deflate.. perche si rischia di incappare in errori (come da esempio con lo “*” o con identity dove q=1)

Sulla rete si trovano gia delle List per valori pesati oppure realizziamo noi direttamente una semplice classe che tokenizza la stringa usando la virgola come separatore e poi tokenizza ogni token utlizzando il “;” . Ovviamente in caso di “*” la scelta di default possiamo attribuirla noi ad esempio gzip. Il sort dei token e’ eseguito sulla base del valore di q, andando a mettere q=1 a tutti gli elementi con q non specificato.

Poi passiamo alla parte MVC e realizziamo un ActionAttributeFilter che utilizzeremo per annotare le Action nel nostro Controller , che saranno sottoposte a compressione.

using System;

using System.Collections.Generic;

using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Collections.Specialized;
using System.IO.Compression;
using System.IO;

public class CompressionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{

HttpRequestBase request = filterContext.HttpContext.Request;
string acceptEncodingHeader = request.Headers["Accept-Encoding"];
if (acceptEncodingHeader == null) return;

HttpResponseBase response = filterContext.HttpContext.Response;

MyFantasticQList encodingPreference = new MyFantasticQList(acceptEncodingHeader);

encodingPreference.setDefaultPreference("gzip");

string preferred = encodingPreference.findPreferred();

switch(preferred.Name){

case "gzip":

Response.AppendHeader("Content-Encoding""gzip");

Response.Filter = new GZipStream(Response.Filter, CompressionMode.Compress);

break;

case "deflate":

Response.AppendHeader("Content-Encoding""deflate");

Response.Filter = new DeflateStream(Response.Filter,CompressionMode.Compress);

break;

default:

break;

}

}

Realizzato il nostro CompressFilterAttribute, nel nostro controller basta annotare le action che devono restituire contenuto compresso:

 

[HttpPost()]

[CompressionFilter]

public ActionResult ListaElementi(string key){

//codice dell'action

}

In automatico prima della response, verrà applicato il content encoding corretto .

Ciao.

 

Ottenere il Soap Message in WCF

A volte cose molto semplici richiedono delle operazioni aggiuntive per essere espletate, e quindi cio che ci aspettiamo essere una semplice Get, prevede invece l’utilizzo di diversi pattern.

Il nostro caso:

stiamo utilizzando un client WCF per chiamare un webservice e vorremmo ottenere programmaticamente, quindi da codice, la busta Soap per memorizzarla ad esempio in sistemi di monitoring o debug particolari.

La soluzione:

Realizziamo una classe che implementi due interfacce, IClientMessageInspector e IEndpointBehavior.

Implementiamo le interfacce e otteniamo:

public class MessageInspector : IClientMessageInspector, IEndpointBehavior

{
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
//throw new NotImplementedException();
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
{
Console.WriteLine("Soap Message:"+request.toString());
return null;
}

public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
//;
}

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.MessageInspectors.Add(this);
}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
//;
}

public void Validate(ServiceEndpoint endpoint)
{
//;
}

}

Nel metodo BeforeSendRequest otteniamo il messaggio prima dell’invio e ad esempio lo stampiamo sulla console..

Per poter poi aggiungere questo Inspector alle caratteristiche del nostro client, basta passarlo in questo modo:

//serviceClient e' l'istanza del nostro client WCF
serviceClient.ChannelFactory.Endpoint.Behaviors.Add(new MessageInspector());

Importante l’implementazione del metodo ApplyClientBehavior , dall’interfaccia IEndpointBehavior, che ci permette di aggiungere il nostro Inspector agli Inspector del client WCF. Come tutto in WCF, anche gli inspector sono completamente configurabili nell’app.config (o web.config), nella parte di serviceModel e tramite delle extensions.

Spero di avervi (e in particolare a chi me lo ha chiesto) aiutato.