Flow Group SASFlow Group
L'erp des Processus Relationnels
Systeme d'Information – Audit Industriel
> Accueil > Expertises & Savoirs > Articles techniques
<div class="infotip"><b>Espace client&#160;:</b> <a href="login.aspx">suivez ce lien</a> pour entrer dans l'espace qui vous est réservé.</div>

Articles technique


Utilisation de la compression HTTP/1.1 avec les Services Web depuis un PocketPC

read the English version English version

Principe général
Implémenter ZHttpWebRequest
Implémenter ZHttpWebResponse
Enregistrer le protocole
Changer l'Url du WebService
Configurer IIS 5.0 pour compresser les fichiers aspx et asmx
Quelques liens utiles...
Historique de révisions...

Dans son tutorial Retrieving Data from Web Services using Standard HTTP 1.1 Compression, Jacek Chmiel explique comment, en .NET, surcharger les méthodes GetWebRequest et GetWebResponse de la classe proxy du Web Service pour demander au serveur la compression des données et les décompresser avant l'interprétation de l'enveloppe SOAP.

Cette approche, très intéressante, ne s'applique malheureusement pas au PocketPC car le Compact Framework ne permet pas la surcharge de ces méthodes. En revanche, nous nous sommes rendus compte qu'il est possible de définir un nouveau protocole, zhttp par exemple, qui utilise des objets WebRequest et WebResponse adaptés pour la compression.

Et cette approche marche sur PocketPC !

Attention !Cet article a été rédigé avec la version Beta du Compact Framework.
  • Pour obtenir les binaires de la version de zhttp compatible avec la Final Beta, cliquez ici.
  • Pour obtenir les fichiers sources qui utilisent le dernière version de SharpZipLib, au lieu de l'ancienne version NZipLib, cliquez ici.
    Dans cette version, l'implémentation de ZHttpWebRequest surcharge la propriété WebRequest.Timeout en déléguant son appel à l'objet HttpWebRequest sous-jacent. Ne pas le faire entraine l'envoi d'une NotSupportedException en cas d'utilisation de la propriété Timeout.

Principe général

A priori, la phase de transport HTTP d'un appel SOAP est la suivante :

  • création d'une requête HTTP via Webrequest.Create sur le protocole http ;
  • préparation de la requête pour envoyer l'enveloppe SOAP ;
  • demande de la réponse ;
  • lecture du flux de la réponse pour interpréter l'enveloppe SOAP de résultat.

Sans rien changer au fonctionnement des WebServices et des objets SOAP coté client et coté serveur, le code que nous allons mettre en place nous permettra d'obtenir la phase de transport suivante :

  • enregistrement du protocole zhttp ;
  • création d'une requête HTTP via WebRequest.Create sur le protocole zhttp ;
  • création de la requête HTTP sous-jacente via WebRequest.Create, sans le "z" ;
  • ajout de l'en-tête "Accept-Encoding: gzip, deflate";
  • préparation de la requête pour envoyer l'enveloppe SOAP ;
  • demande de la réponse ;
  • demande de la réponse de la requête sous-jacente ;
  • décompression du flux de la réponse sous-jacente ;
  • lecture du flux de la réponse pour interpréter l'enveloppe SOAP de résulat.

Implémenter ZHttpWebRequest

Diagramme de classe de WebRequestNous commençons par implémenter la classe qui permet de créer une requête HTTP en précisant dans les en-têtes que le client sait traiter les réponses compressées, soit en gzip, soit en deflate. Si le serveur ne connaît aucune des deux méthodes, il renvoie les données non-compressées.

public class ZHttpWebRequest : System.Net.WebRequest { private HttpWebRequest request; private System.Uri uri; internal ZHttpWebRequest(System.Uri uri) { string s = uri.AbsoluteUri.Substring(1); // remove the leading z this.uri = uri; request = (HttpWebRequest)WebRequest.Create(s); // tell the HTTP server that the client accept compressed data request.Headers.Add("Accept-Encoding", "gzip, deflate"); }

Ensuite, il suffit que la méthode GetResponse renvoie notre objet qui se charge de décompresser les informations renvoyées par le serveur HTTP.

public override System.Net.WebResponse GetResponse() { ZHttpWebResponse response = null; // create the appropriate response object response = new ZHttpWebResponse(request, uri); return response; }

Enfin, pour toutes les autres méthodes pouvant être surchargées, nous appelons directement l'objet de requête HTTP sous-jacent.

// for all the other overridable functions, redirect the call // to the private HttpRequest object, as shown above public override void Abort() { request.Abort(); // redirect the call } ... }

Implémenter ZHttpWebResponse

Diagramme de classe de WebResponsePour traiter la réponse, nous devons développer un nouvel objet qui dérive de WebResponse et qui encapsule l'objet réponse HTTP classique.

public class ZHttpWebResponse : WebResponse { private HttpWebResponse response; private System.Uri uri; internal ZHttpWebResponse(WebRequest request, System.Uri uri) { this.uri = uri; response = (HttpWebResponse)request.GetResponse(); }

C'est dans la méthode GetResponseStream que nous devons faire le travail de décompression, en tenant compte de la réponse du serveur : soit la réponse est encodée en "gzip", soit en "deflate" ou sinon elle n'est encodée pas du tout.

public override Stream GetResponseStream() { // select the right decompression stream if(response.ContentEncoding=="gzip") { return new GZipInputStream(response.GetResponseStream()); } else if(response.ContentEncoding=="deflate") { return new InflaterInputStream(response.GetResponseStream()); } else { return response.GetResponseStream(); } }

Puis, nous surchargeons la méthode ResponseUri pour utiliser l'Uri initiale. Et finalement, pour toutes les autres méthodes pouvant être surchargées, nous appelons directement l'objet de réponse HTTP sous-jacent.

public override System.Uri ResponseUri { get { return uri; } } // for all the other overridable functions, redirect the call // to the private HttpRequest object, as shown above public override void Close() { response.Close(); } ... }

Enregistrer le protocole

Les requêtes Web sont gérés via une fabrique de classes qui instancie les objets WebRequest en fonction du préfixe de l'uri. Ainsi, http:// est traité par HttpWebRequest, file:// par FileWebRequest, etc.

Pour enregistrer notre protocole, nous devons d'abord créer une classe implémentant l'interface IWebRequestCreate, qui permettra à la fabrique d' instancier nos objets ZHttpWebRequest.

class ZHttpWebRequestCreate : IWebRequestCreate { /// <summary> /// Create the WebRequest object able to handle the Uri /// </summary> /// <param name="uri">the requested Uri</param> /// <returns>The WebRequest object</returns> public System.Net.WebRequest Create(System.Uri uri) { System.Net.WebRequest request = new ZHttpWebRequest(uri); return request; } }

Ensuite, pour être plus propre, nous encapsulons dans une méthode l'appel à l'enregistrement du préfixe et l'objet de création dans la fabrique.

public class ZHttpProtocol { /// <summary> /// Register the protocol /// </summary> /// <returns></returns> static public bool Register() { return WebRequest.RegisterPrefix("zhttp", new ZHttpWebRequestCreate()); } }

Il ne nous reste plus qu'à appeler la méthode ZHttpProtocol.Register dans notre programme, avant d'appeler les WebServices, dans la méthode Main par exemple.

// register the protocol ZHttpProtocol.Register();

Changer l'Url du WebService

Lors du référencement des WebService via le Web, les Uri des fichiers WSDL sont en http://. Donc, pour utiliser notre protocole, il nous suffit d'ajouter le z devant l'Uri normal.

// initiliaze the WebService MyWebService ws = new MyWebService(); ws.Url = "z" + ws.Url; // call the methods ...

Et voilà !

Configurer IIS 5.0 pour compresser les fichiers aspx et asmx

Pour compresser les fichiers aspx et asmx sur un serveur IIS, nous devons activer la compression HTTP sur le serveur puis exécuter les commandes suivantes :

CSCRIPT.EXE ADSUTIL.VBS 
  SET W3Svc/Filters/Compression/GZIP/HcScriptFileExtensions 
  "dll" "asp" "aspx" "asmx"¶
¶
CSCRIPT.EXE ADSUTIL.VBS¶
  SET W3Svc/Filters/Compression/DEFLATE/HcScriptFileExtensions 
  "dll" "asp" "aspx" "asmx"¶
¶
IISRESET.EXE¶

Quelques liens utiles...

Historique de révisions...

daterévision
18/01/2006 00:00Mise à jour des binaires
Les binaires sont désormais en nom fort pour permettre leur utilisation avec des assemblies signés.
26/01/2004 00:00Mise à jour du fichier source
Ajout à la ligne 374 de l'implémentation de la propriété Headers pour éviter une exception NotSupportedException. (Merci à Jeff Evans pour avoir remonté et corrigé le bug).

les informations fournies ici le sont en tant que telles, sans aucune garantie d'aucune sorte.
© 2021 Flow Group SAS - Flow Group est une marque déposée de GL Conseil SA.