Un petit bug IE un peu pénible à trouver : lors de la création d’un DIV vide (par exemple pour créer une ligne de couleur en travers d’une page, IE ajoute une sorte de marge ou de padding et ne respecte donc pas vraiment les contraintes height et width mises dans le css.
La solution est simple : trsnaformer ce DIV vide en un div non vide en ajoutant un commentaire vide au milieu…
<DIV> <!– –></DIV>
Author Archives: Paul
Mise à jour de Windows avec authentification
Un grand éclat de rire aujoud’hui, Microsoft vient de lancer l’authentification des utilisateurs lors des mises à jours et téléchargements de logiciels sur son site. Ce système doit empécher que des utilisateurs n’ayant pas obtenus légalement leur licence téléchargent les dits programmes. En soit, cette mesure très légitime est une bonne chose, outre le prix exorbitant des logiciels ainsi protégés et, à mon avis, inadapté à une cible grand puplique.
Bref, là n’est pas l’objet de cette brève puisque la blague du jour est l’arrivée du programme de contournement deja diffusé. Rien d’etonnant me direz vous, je ne suis d’ailleurs aucunement surpris ; ce qui me fait rire par contre c’est la simplicité du contournement ou plutot l’extrème minimalisme de la protection : une blague !! En effet l’analyse du script est simple : il s’agit bêtement de l’ajout d’un cookie sur le poste indiquant que l’authentification est réussie !!! autant dire qu’un gamin bricolo de 14 ans pouvait à la fois inventer cette protection et la casser !
Tout ça pour en venir à l’idée suivante : quand on est le numéro 1 de l’informatique mondiale, que l’on compte parmi ses employés sans doute ce qu’il y a de meilleur et que l’on met en place une blague pareille, ca ne peut s’appeler que du marketing !! Au fait, Microsoft ne propose-t-il pas en même temps une offre “très aléchante” pour se mettre en règle et payer sa licence ? Ou comment investir un minimum pour juste doper ses ventes !
Pour ma part, si je voulai luter contre le piratage et ainsi récupérer des millions de dolards de licences qui m’échappent j’investirai un peu plus qu’une centaine d’euro dans mon système de sécurité … mais bon !
Synchronisation Palm et PC sous Windows XP
La synchro entre le palm et le PC sous win XP au travers de l’infrarouge n’est malheureusement pas toujours surper aisée à mettre en oeuvre… pour ma part j’ai du chercher un moment avant de trouver la bonne solution.
Une fois l’IR installé sur le portable et HotSync configuré pour accepter la synchro IR, il faut encore vérifier quelques points dans la config de la “liaison sans fil” avant de faire fonctionner la synchro… Dans le panneau de configuration, dans le gestionnaire des Liaison sans fil, il faut vérifier que :
1- Le Transfert d’image ne soit pas activé
2- Dans les propriété du Matériel, puis dans Avancé le paramètre Speed Limit soit bien à 57.6kbps
Une fois celà vérifié, la synchronisation devrait bien se passer et le message “port utilisé par une autre application” devrait disparaitre..
Le non au traité constitutionnel
Ca y est, le résultat est tombé, NON au traité constitutionnel … en soit, c’est un choix comme un autre même si ce n’est pas forcement le mien, mais ce petit mot d’humeur vient surtout suite aux discours médiocres venant de nos politiques, malheureusement quels qu’ils soient
Le français auraient donc voté contre la politique de Chirac ! Quelle honte ! La question que posait ce vote etait une question sur l’avenir, savoir ce que nous allions faire de cette Europe que nous construisons depuis des décenies. Comment-est il possible que la réponse portent sur la politique passée des trois dernières années. Les français sont il trop idiots pour répondre à une question aussi simple que celle posée ? ou la question était elle si compliquée qu’ils ont préféré répondre à une autre ?
Pour ma part, je pense que la faute revient à nos politiques du non qui ont mené une campagne mélangeant politique interne et démagogie, loin de l’idéologie Européenne ; une campagne en contre sans la moindre proposition objective pour l’Europe de demain.
Aujourd’hui, nous avons choisi le non et donc … rien ne change ! nous restons sur l’Europe d’hier, celle qu’ont décrié les camps du non ! bravo, c’est sans doute ça une victoire !
Une constitution Européenne et un compromis entre tous les pays de l’Europe et non une question de politique intérieure. La constitution parfaite pour les français ne peut exister, alors jouer en contre est facile.
Maintenant le débat ne porte plus sur l’Europe et les solutions possibles mais uniquement sur la politique intérieure et les appels à démission ! depuis quand une question de politique extérieure dont le gouvernement doit elle entraîner une alternance ? Le même triste débat a eu lieu aux régionnales ! Si nous voulons faire avancer notre sociétée et conserver la démocratie il va être impératif que les électeurs répondent aux questions qu’on leur pose et uniquement à celle-ci. Pour que ca fonctionne, nos politiques et nos journalistes doivent impérativement cesser les analyses post-scrutin basées uniquement sur l’analyse statistique du pour ou contre la politique gouvernementale qui a l’effet d’un lourd parasite sur les référendums.
Mais tout ceci sera bien vite oublié et nous seront vite figé dans l’immobilisme…
Ré-écriture d’URL en Java (URL Rewriting)
I. Objet & principe :
La ré-écriture d’URL permet, en gros, d’afficher une page dont le nom n’est pas celui saisit par l’internaute ; quel interet à celà : utiliser par exemple 1 seule page jsp existant physiquement avec de multiples nom. Ceci peut avoir deux objetifs : donner un nom plus parlant à une page ou et c’est plus généralement le cas… aider fortement au référencement de son site web. Beaucoup de moteurs recherchent avant tout des mots clefs dans le titre et dans le nom de votre page. Ainsi, insérer des mots clefs dans l’URL est une bonne façon d’améliorer son référencement.
En général, l’URL rewriting se configure sur le serveur web (Apache) au travers de règles assez simple ; ce qui est une bonne solution, mais tout de même beaucoup moins drôle que de ré-écrire soit-même le mécanisme qui est globalement assez simple. Avantage d’utiliser une solution coté application : elle ne nécessite aucune config coté serveur en cas de crash/redeploiement, contexte dans lequel on retrouve toujours les sources mais jamais les fichiers de conf… croyez en mon expérience sur le sujet.
Sur le principe, c’est assez simple : les serveurs d’application on une page vers laquelle sont renvoyées les requêtes qui ne trouvent pas de destinataire (un catchAll en quelque sorte). C’est ici que nous allons agir, partant du principe que nos URL virtuelles n’existeront pas mais renverront sur des URL physiques différentes. Nous allons donc rediriger toutes les requêtes en erreur 404 (not found) vers une servlet ce qui permettra un déploiement assez transparant.
II. Configuration du serveur d’application :
Le serveur d’application est paramétrer au travers du fichier web.xml. Avantage, ce fichier est spécifique à la webapp, il n’y a donc pas de paramétrage coté serveur mais seulement coté webapp. Le fichier va ressembler à cela :
<!– Partie 1 –>
<servlet>
<servlet-name>UrlRewritingServlet</servlet-name>
<display-name>UrlRewritingServlet</display-name>
<description>Servlet de redirection et rewriting</description>
<servlet-class>disk.tools.appServer.UrlRewritingServlet</servlet-class>
<init-param>
<param-name>configFile</param-name>
<param-value>urlRewritingServlet.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>UrlRewritingServlet</servlet-name>
<url-pattern>/error.jsp</url-pattern>
</servlet-mapping><!– Partie 2 –>
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>La partie 2 paramètre l’interception de la requête normalement en erreur et la redirige vers la page /error.jsp ce comportement est utiliser dans le cadre des redirection standard. Seulement, ici, nous avons une partie 1 qui redirige les requetes allant vers cette page d’erreur vers une servlet dont le nom est UrlRewritingServlet celle-ci étant implémenté par la classe disk.tools.appServer.UrlRewritingServlet dans l’exemple. Nous spécifions un paramètre configFile qui permettra d’indiquer à la Servlet le nom du fichier de configuration.
III. Le fichier de configuration des redirections :
Nous allons utilisé un fichier de configuration qui permettra d’indiquer les règles de redirection. Ce fichier va inclure des expressions régulières sous forme d’une liste de properties, ce mécanisme étant simple à gérer en java. Ne plus des règles de redirection, nous ajouterons une règle renvoyant vers une page spécifique les requetes à destinatination d’URL non reconnu par la servlet reproduisant ainsi le mécanisme normal d’erreur 404.
Le fichier est enregistré sous le nom UrlRewritingServlet.properties, ce nom a précédemment été indiqué dans la configuration serveur.
Son format est le suivant :# ########################################################
# DEFINITIONS DE LA REGLE PAR DEFAUT
# ########################################################
404.error = /error404.jsp# ########################################################
# REGLES SPECIFIQUES
# Format : Regex, destination
# ########################################################
rule.0 = .*MonMotif.*, /foo.jsp
rule.1 = .*TonMotif.*, /foo1.jspCette configuration renvoie toutes les requetes dont l’adresse contient le mon clef MonMotif vers la page foo.jsp et celles contenant TonMotif vers foo1.jsp. Toutes les autres requetes sont transmises à la page /error404.jsp. foo.jsp, foo1.jsp et error404.jsp sont des pages existant physiquement dans l’application ; elles serviront à présenter le résultat.
IV. La Servlet de redirection :
Pour commencer, c’est une servlet, elle hérite donc de cette classe :
public class UrlRewritingServlet extends HttpServlet {
public UrlRewritingServlet() {
super();
}
La fonction init() est appelée au chargement de la Servlet, à ce moment, celle-ci va aller lire le fichier de configuration utilisé pour les redirections. Ce fichier sera placé dans le répertoire WEB-INF de la webapp ; le chemin est donc indiqué de façon relative par rapport au chemin de la Servlet. Cette méthode n’est peut être pas optimale mais je n’ai pas mieux à proposer 🙁 . Il se peut que le chemin soit à adapter au package que vous utiliserez.
private boolean initialized; private Properties prop; public void init() {
this.initialized = false;
String file = getInitParameter(“configFile”);
if (file != null) {
String t[] = UrlRewritingServlet.class.getName().split(“\\.”);
String className = t[t.length-1];
String fileName = “Filename not found”;
try {
fileName = UrlRewritingServlet.class.getResource(className+”.class”).getPath();
fileName = fileName.substring(0,fileName.length()-className.length()-6)+”../../../../”+file;
FileInputStream is = new FileInputStream(fileName);
prop = new Properties();
prop.load(is);
} catch (Exception e) {
System.err.println(“Imposible d’acceder aux (“+fileName+”): \n”+e);
}
this.initialized = true;
}
}Reste maintenant à voir le coeur du système, la méthode doGet (ou doPost ) qui reçoit la requête à traiter :
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(“text/html”);if ( !this.initialized ) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
PrintWriter out = response.getWriter();
out.println(“<HTML><BODY>Error : UrlRewritingServlet not initialized </BODY></HTML>”);
return;
}URL requestedURL = new URL(request.getRequestURL().toString());
String requestedHost = requestedURL.getProtocol()+”://”+requestedURL.getHost()+((requestedURL.getPort() != 80 )?”:”+requestedURL.getPort():””)+request.getContextPath();
String requestedPage = requestedURL.getPath();String destUrl = null, pValue;
int index = 0;
boolean redirectFound = false;
while (!redirectFound && (pValue = prop.getProperty(“rule.”+index)) != null ) {
StringTokenizer st = new StringTokenizer(pValue,”,”);
if ( st.countTokens() == 2) {
String regEx = st.nextToken();
if ( requestedPage.matches(regEx) ) {
redirectFound = true;
destUrl = st.nextToken().trim();
}
} else System.err.println(“Bad data : “+pValue);
index++;
}
if ( redirectFound ) {
response.setStatus(HttpServletResponse.SC_OK);
RequestDispatcher dispatcher = request.getRequestDispatcher(destUrl);
dispatcher.forward(request, response);
} else {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
destUrl = prop.getProperty(“404.error”);
if (destUrl != null) {
destUrl = response.encodeRedirectURL(requestedHost+destUrl);
response.sendRedirect(destUrl);
}
}
}Le traitement se déroule suivant les étapes suivantes :
- Si le chargement du fichier de configuration a échoué, la servlet retourne un message d’erreur standard et une réponse 404
- Sinon, elle parcours les règles définie dans le fichier et configuration jusqu’à trouver une règle correspondante ou terminer sa recherche
- Si une règle est trouvée, alors la requete est forwardée vers la page de redirection
- Sinon, une requete de redirection est soumise au navigateur vers la page d’erreur
Dans le cas d’une ré-écriture d’URL on ne souhaite pas que le navigateur soit informé que l’adresse qu’il a soumis est fausse, c’est pourquoi on utilisera une requete de forward et que la réponse sera forcé à SC_OK sans quoi il recevrait un message 404, ce qui peut être transparant pour un humain mais bienexplicite pour un robot d’indexation.
Dans le cas d’une requête en erreur dans la ré-écriture, le fait d’utiliser un sendRedirect va informé le navigateur que la page qu’il a demandé n’existe pas et le demander de charger à la place notre page d’erreur. Ainsi l’URL sera mise à jour dans le browser et la réponse en statut SC_NOT_FOUND sera explicite.
V. Pour terminer :
La source complet de la Servlet est téléchargeable dans les liens. Ceci est sans doute perfectible mais vite écrit et fonctionne parfaitement sur les site que sur lesquels je l’utilise.
Hauteur d’un élément d’une page web
La problématique est la suivante : comment connaitre la hauteur d’un élément d’une page web alors que son contenu est dynamique et sa mise en page variable d’un navigateur/système à l’autre ?
Voici une solution pour calculer la hauteur d’un élément dans une page web au travers d’un Javascript :
La fonction suivante permet de calculer la hauteur de ou des élément situés entre deux balises div identifiées par les id debut et fin
<script type=”text/javascript”>
<!–
function getHeight() {
var d = document.getElementById(“debut”).offsetTop;
var f = document.getElementById(“fin”).offsetTop;
return f-d;
} //–>
</script>
L’élément est ensuite intégré entre deux balises :
<DIV id=”debut”></DIV>
<!– On met les éléments ici –>
<DIV id=”fin”><DIV>
Il suffira ensuite d’appeler la fonction getHeight() pour récupérer la hauteur de l’élément dans le navigateur…
Ce système à l’avantage de fonctionner sur IE 6.0, Mozilla 1.7.3, Firefox 1.0 et Firefox 1.0.2
Configuration HTTPS sur Apache2
Il s’agit de configurer un acces par https sur un serveur Apache2 tel que distribué par Suse.
Tout d’abord, il faut activer le module ssl dans la configuration. pour celà, éditer le fichier de paramétrage général /etc/sysconfig/apache2 et ajouter à la variable APACHE_MODULES le mot clef ssl. Il faut ensuite ajouter SSL à la variable APACHE_SERVER_FLAGS. Dès lors au prochain démarrage le module SSL sera activé. La configuration par défaut des modules doit suffire.
Il faut ensuite créer les clefs nécessaires à l’établissement de la session crypté. Pour un usage de test ou privé, il est possible de créer soit même ses clef :
- La première est la clef serveur : elle doit être enregistrée dans le répertoire /etc/apache2/ssl.key sous le nom server.key. Sa création se fait à l’aide de la commande suivantes :
openssl genrsa -des3 -rand file1:file2:file3 -out /etc/apache2/ssl.key/server.key 1024 pour une clef de 1024bit RSA cryptée par triple DES utilisant pour la génération de nombre aléatoire les fichier file1 à file3 (ou plus) passés en paramètre. Il est conseillé d’utiliser des fichiers gzip comme source aléatore. Un mot de passe sera demandé pour protéger la clef.
Créé de cette façon là, le serveur demandera de lui fournir le mot de passe à chaque démarrage pour décrypter le certificat. il est donc possible de stocker une version non cryptée de la clef à l’aide de la commande suivante : openssl rsa -in server.key -out server.pem. Bien sure cette solution plus simple est de moindre sécurité et l’accès à la clef doit être restraint.
- La seconde clef est le certificat X509 à proprement parlé. Il est stocké dans le fichier /etc/apache2/ssl.csr et sa création se fait à partir de la clef RSA précédemment calculée. Sa génération est obtenu à l’aide de la commande suivante :
openssl req -new -key /etc/apache2/ssl.key/server.key -out /etc/apache2/ssl.csr/server.csr : la commande vous demandera quelques informations permettant de remplir le certificat.
- Le certificat doit ensuite être signé ; normalement c’est un organisme spécialisé (et payant) qui peut réaliser celà. Pour un usage de test, cette signature peut être faite soit même par la commande suivante :
openssl x509 -req -days 365 -in /etc/apache2/ssl.csr/server.csr -signkey /etc/apache2/ssl.key/server.key -out /etc/apache2/ssl.crt/server.crt
La configuration de l’hôte ou de l’hôte virtuel se fait de la façon suivante en ajoutant les lignes :
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:-eNULL
SSLCertificateFile /etc/apache2/ssl.crt/server.crt
SSLCertificateKeyFile /etc/apache2/ssl.key/server.pem
SetEnvIf User-Agent “.*MSIE.*” nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
Les logs doivent être du type suivant : ssl_combined
Au passage, pour que cela fonctionne, il faut, selon votre config initiale avoir :
- NameVirtualHost *:80
- NameVirtualHost *:443
Ainsi apache va scanner les virtuals hosts à la fois pour le port 80 et le port 443. Sans celà le même (le premier) vhost avec un port 443 sera pris à chaque fois.
A la fin il reste à redemmarrer le serveur apache et tester …
Utilisation de AWT sur un serveur sans Xwindows
Lorsque l’on manipule de images, des fontes ou autre objets basés sur AWT, java utilisa par défaut des informations venant de votre serveur X ou de l’environnement graphique de Windows. (Sans doute hérité d’un passé Applet toujours présent). Lors de calculs coté serveur, ce fonctionnement peut poser problème : en effet pourquoi installer et démarrer X, et consommer de la mémoire inutilement pour une application web ?!?
Si vous êtes dans ce cas, voici l’option de la mort à passer à la JVM … cette variable est à initialiser avant de lancer le serveur d’application :
export JAVA_OPTS=”-DJava.awt.headless=true”
Voilà, c’est tout simple, j’espere que ceci vous aura éviter les 3heures passées à chercher le pourquoi du comment.