Pour les besoins d'un projet d'application AIR, je suis tombé sur une restriction plutôt gênante dans la fonction launchApplication du fichier airSWF d'adobe, permettant de démarrer une application AIR installée sur la machine à partir d'un navigateur.
Cette restriction empêche l'utilisation d'un grand nombre de caractères au sein du tableau du paramètre argument: airSWF.launchApplication(appID, pubID, argument);. Ainsi, les caractères admis dans ce tableau sont les suivants: A-Za-z0-9:-= .
Mon projet m'imposait d'envoyer des liens, ou plutôt mon application devait recevoir des liens sous la forme http://www.lesite.fr/plop_plop.php?plop=1 par exemple. Ces liens présentent donc les caractères interdits suivants: /._?. J'ai donc décidé d'utiliser les expressions régulières afin d'encoder les caractères interdits en caractères autorisés.
Extrait du fichier appelAir.swf à placer sur son serveur:
var pattern:RegExp = /(_|\?|.|\/)/g; var str1:String="http://www.lesite.fr/plop_plop.php?plop=1"; var str2:String = str1.replace(pattern,strFunction); var argument:Array=[str2]; function strFunction( matchedSubstring:String,capturedMatch1:String,index:int, str:String):String { var cm:String = capturedMatch1; switch(cm) { case ".": cm = cm.replace(cm, ":-:"); break; case "/": cm = cm.replace(cm, ":-=:"); break; case "_": cm = cm.replace(cm, ":--:"); break; case "?": cm =cm.replace(cm, ":==:"); break; } return cm; } airSWF.launchApplication(appID, pubID, argument);
L'expression régulière est simple puisqu'elle ne fait que 'capturer' les caractères interdits. Soit le souligné, soit le point d'interrogation, soit le point, soit la barre oblique inversée. L'ajout de g à la fin de l'expression permet de la rendre globale, ce qui a pour effet de capturer tous les caractères et non seulement le premier trouvé. Pour modifier ces caractères, je fais appel à une fonction (strFunction) renvoyant une chaîne de caractères (String) au sein de la méthode replace. J'utilise ensuite un switch afin de les remplacer par une suite de caractères autorisés: :-:, :--:, :-=:, :==:
Pour terminer, il suffit d'utiliser le procédé inverse dans son application AIR:
NativeApplication.nativeApplication.addEventListener( BrowserInvokeEvent.BROWSER_INVOKE,onInvokeEvent); public function onInvokeEvent(e:BrowserInvokeEvent):void{ var str1:String=e.arguments[0]; var pattern:RegExp = /(:-=:|:-:|:==:|:--:)/g; var str2:String = str1.replace(pattern,strFunction); } function strFunction(matchedSubstring:String, capturedMatch1:String,index:int,str:String):String{ var cm:String = capturedMatch1; switch(cm) { case ":-:": cm = cm.replace(cm, "."); break; case ":-=:": cm = cm.replace(cm, "/"); break; case ":--:": cm = cm.replace(cm, "_"); break; case ":==:": cm = cm.replace(cm, "?"); break; } return cm; }
A noter que depuis la réalisation de ce petit script, j'ai trouvé une autre méthode qui consiste à utiliser un encodage à l'aide de la librairie as3crypto.
import com.hurlant.crypto.rsa.RSAKey; import com.hurlant.crypto.rsa.RSAKey; import com.hurlant.util.Base64; import com.hurlant.util.Hex; private var currentInput:String; private var currentResult:String; private var currentModulus:String; private var currentExponent:String; private var currentPrivate:String; private var currentP:String; private var currentQ:String; private var currentDMP1:String; private var currentDMQ1:String; private var currentCoeff:String; var start:Boolean; var exp:String = "10001"; var rsa:RSAKey = RSAKey.generate(512, exp); currentModulus = rsa.n.toString(); currentPrivate = rsa.d.toString(); currentP = rsa.p.toString(); currentQ = rsa.q.toString(); currentDMP1 = rsa.dmp1.toString(); currentDMQ1 = rsa.dmq1.toString(); currentCoeff = rsa.coeff.toString(); var rsa:RSAKey = RSAKey.parsePublicKey(currentModulus, exp); var data:ByteArray = Hex.toArray(Hex.fromString("http://www.lesite.fr/pl_op.php?p=1")); var dst:ByteArray = new ByteArray; rsa.encrypt(data, dst, data.length); currentResult = Hex.fromArray(dst); var txt:String; txt = currentResult; var rsa:RSAKey = RSAKey.parsePrivateKey(currentModulus, exp, currentPrivate, currentP, currentQ, currentDMP1, currentDMQ1, currentCoeff); var data:ByteArray = Hex.toArray(txt); var dst:ByteArray = new ByteArray; rsa.decrypt(data, dst, data.length); currentInput = Hex.fromArray(dst); txt = Hex.toString(currentInput);