5

Aug

Cache delle risorse con l’ ETAG HTTP

Ciao a tutti,

l' Etag fa parte del protocollo HTTP ed è uno dei meccanismi che HTTP utilizza per la convalida della cache. Ogni risorsa web contiene questo parametro e ogni qual volta questa risorsa cambia anche il suo ETag cambia!

Vediamo subito come fare.

N.B. nel codice che segue viene utilizzata una libreria chiamata RestSharp per fare le chiamate web.

Ecco il codice d’esempio scritto in una app per Windows Phone.

Attenzione: il codice è stato fatto “on the fly” solo per farvi vedere come funziona, prima di utilizzarlo in qualche progetto bisogna rivederlo e modificarlo opportunamente!

using System;
      using System.Linq;
      using System.Net;
      using Microsoft.Phone.Controls;
      using RestSharp;

      namespace TestApp
      {     public partial class MainPage : PhoneApplicationPage     
	{        
		 private string _etag;        
		 public MainPage()         {            
			 InitializeComponent();            
			 GetResource();      
		   }       
		  public void GetResource()         {            
			 RestClient restClient = new RestClient(@"http://2.bp.blogspot.com");            
			 RestRequest restRequest = new RestRequest("/_6qIOL7apb7g/S-yQpVSeiyI/AAAAAAAAAGM/TqsrAeLXb98/s1600/ner%20framework.png");            
			 if (!string.IsNullOrEmpty(_etag))                
				 restRequest.AddHeader("If-None-Match", _etag);            
			  restClient.ExecuteAsync(restRequest, Callback);        
		 }        
		 private void Callback(IRestResponse restResponse)         {        
 	           switch (restResponse.StatusCode)            
		 {          
	          case HttpStatusCode.NotModified:             
	          	//Entra qui se la risorsa non è cambiata        
	        	   this.Dispatcher.BeginInvoke(() => lblseconda.Text = "La seconda richiesta è stata effettuata ma la risorsa non è stata cambiata!");            
       		 break;        
         case HttpStatusCode.OK:               
     		   //entra qui se la risorsa viene scaricata                      
		  _etag = restResponse.Headers.Single(c => c.Name.ToLower() == "etag").Value.ToString();                        
		 this.Dispatcher.BeginInvoke(() => lblprima.Text = "Scaricata la risorsa con etag: " + _etag);                        
 		//Tento di riscaricare la risorsa..al termine mi aspetto di entrare nel primo Switch                        
		 GetResource();  
      		   break; 
            }     
    }  
   }
      }
Il codice è molto semplice, appena avviata l’app viene fatta la chiamata al metodo GetResource che scaricata la risorsa. Appena finito il download viene richiamata la callback e, se tutto è andato a buon fine, l’HttpStatusCode è OK e quindi il codice entra nel secondo switch. Qui ci memorizziamo l’etag della risorsa appena scaricata e facciamo ripartire il download della stessa risorsa. 
Se notate bene il codice di questa seconda richiesta è leggermente diversa dalla prima perchè viene aggiunto un Header chiamato If-None-Match dove come parametro gli viene passato il nostro etag appena memorizzato:
if (!string.IsNullOrEmpty(_etag)) 
restRequest.AddHeader("If-None-Match", _etag); 
è proprio grazie a questo che il server confronta i due etag e ci risponde come stato 304 NotModified nel caso la risorsa non è cambiata (da notare che la risposta in questo caso pesa solo alcuni byte, quindi risparmiamo tantissimo a livello di performance) oppure OK inviandoci la nuova risorsa. 
Ecco il risultato ottenuto eseguendo il codice:
post

 Conclusioni

Per fare una applicazione di qualità bisogna gestire correttamente la cache delle risorse. Grazie a questo procedimento possiamo gestire ottimamente questo aspetto aumentando di molto le performance della nostra applicazione! E poi la cosa bella è che il tutto avviene quasi gratuitamente Sorriso

 

Ciao e alla prossima

 

Carmine

by Carmine Punella on 8/5/2012
Post archive