![]() Luis Colorado A propos de l'Auteur: Luis Colorado travaille comme administrateur de systèmes Unix et d'accès Internet pour Telefónica Sistemas S.A. en Espagne. Il est diplômé de Physique de Universidad Complutense à Madrid et a developpé plusieurs utilitaires libres pour Unix.
|
Résumé:
Cet article décrit un programme qui permet d'accéder à une base de données depuis une page HTML. L'objectif de ce programme est le contrôle de l'accès aux données, la flexibilité de la configuration et l'indépendance vis à vis de la mise en page. Ce programme est le résultat d'une série d'idées provenant de la lecture de plusieurs articles sur M4 qui sont sortis récemment dans les magazines Linux Journal et LinuxFocus (www.linuxfocus.org) pendant ces 12 derniers mois.
De plus, la disponibilité de nombreux serveurs web et moteurs de base de données contraste avec le manque d'utilitaires qui permettent d'interfacer les 2 environnements (La majorité de ces applications sont commerciales ou ont de sérieuses insuffisances dans les formats qu'elles peuvent prendre en compte).
Le programme tente d'unifier les 2 mondes grâce à une application qui satisfait les points suivants:
Permettre le contrôle de la sécurité du site. L'application supporte une méthode assez générale pour sélectionner une configuration et peut être facilement configurable pour contrôler l'accès au site web
C'est un fait bien connu que HTML est un langage de formatage pour formater des documents qui pourront être affichés avec un navigateur Internet. Une caractéristique de base d'un bon générateur de texte est un langage convenable pour formater le texte offrant suffisamment de possiblités de contrôle pour l'arrangement des paragraphes et parties de texte dans la composition finale de la page. Cependant, dans la plupart des langages de formatage, il y a toujours une série de macros qui permettent de manipuler les éléments flottants du document (tables, images, etc, qui s'ajustent dynamiquement sur la page au chargement).
La plupart des utilitaires que je connais pour interfacer HTML et des bases de données, génèrent l'information sur le texte affiché en étendant le jeu de balises HTML (NdT: en anglais, tag). Ces nouvelles balises prennent le rôle de 'macros'. Cependant, cette approche à un serieux inconvénient: La plupart du temps, nous devons modifier les éléments dans les balises du code HTML natif et c'est une limitation importante. Souvent, ces utilitatires doivent créer des balises dans le but d'obtenir un effet déterminé sur une balise HTML existante. Mon programme utilise M4 dans le but de remplacer les macros partout où cela est nécessaire. Le programme ne génère aucun texte formaté, et c'est pourquoi il est indépendant du format de sortie du langage utilisé. Le programme génère une série de macros comme résultat d'une requête puis M4 génère un document HTML en utilisant ces macros et un modèle HTML donné.
|
M4 fut originellement développé pour lier la CGI (Common Gateway Interface) avec la base de données PostgreSQL. Rapidement, des gens ont réalisé qu'il était suffisamment général pour supporter d'autres interfaces (par exemple une passerelle entre une serveur LDAP et d'autres bases de données comme Informix ou Oracle).
Plus tard, l'interface fut standardisée incorporant toutes les fonctionnalités nécessaires et les modules PostgreSQL furent réécris en fonction de la nouvelle interface. Maintenant, il est possible d'écrire de nouveaux pilotes qui permettent au programme de supporter d'autres gestionnaires de base de données. |
|
|
Prenons un exemple: Supposons que le client doive nous transmettre des informations dans la QUERY_STRING, au format suivant:
CHAMP=ValeurNotez que la query_string doit satisfaire ce format et aucune information ne doit être ajoutée à la chaîne de caractères.
La mise en oeuvre de cette syntaxe se fait facilement en écrivant les termes suivants dans la règle de sélection:
QUERY_STRING: "^CHAMP=[^&]*$";La ligne ci-dessus garantit que la règle sera invoquée seulement si la QUERY_STRING est au bon format... Mais, de plus, si nous plaçons des parenthèses autour de la valeur, alors le programme pourra analyser la valeur correspondante:
QUERY_STRING: "^CHAMP=([^&]*)$";Dans le processus, le programme transforme les séquences d'échappement de la forme %xx introduite pour le navigateur.
QUERY_STRING: "^CHAMP=([^&]*)$";
! HTTP_ADDRESS: "^194\.142\.12\.";(Cet exemple invalidera la règle si la requête vient de 194.142.12.xxx)
[ QUERY_STRING: "UTILISATEUR=([^&]*)" ];Ces définitions nous permettent de transmettre la valeur de l'utilisateur si le client la fournit mais n'invalide pas la règle si le client ne la spécifie pas.
La partie gauche et la partie droite d'une règle sont délimitées par des accolades "{ }" et sont séparées par le symbole`->'.
La partie droite contient les termes avec une même syntaxe: un nom de variable, le caractère ':', une chaîne de caractères et le caractère fin de chaîne ';'. Tous les termes du coté droit sont des assignations de valeurs à des variables effectuées par M4.
et la règle déclarée dans le site web est :
QUERY_STRING: "NAME=([^&]*)"; QUERY_STRING: "FAMNAME1=([^&]*)"; QUERY_STRING: "FAMNAME2=([^&]*)";Le résultat serait:
term_0_match_0 <- "NAME=JOSE"; term_0_match_1 <- "JOSE"; term_1_match_0 <- "FAMNAME1=DE LA FUENTE" ; (noté le remplacement du caractère + par ` ') term_1_match_1 <- "DE LA FUENTE"; term_2_match_0 <- "FAMNAME2=LOPEZ"; term_2_match_1 <- "LOPEZ";Pilotes:
Nous ne décrirons pas, dans cet article, l'utilisation des pilotes. Tout est déjà expliqué dans la documentation fournie avec la distribution de PG2CGI. Le lecteur intéressé est encouragé à lire le manuel de référence
Pour le moment, il n'existe qu'un seul pilote pour la connexion à la base de données PostgreSQL. Cependant, l'auteur a prévu d'écrire un autre pilote pour les bases de type LDAP.
Un exemple:
Examinons maintenant le source d'un exemple complet.
Considérons la table de déclarations provenant de la base de données de déclarations à slug.cvt.es (Suivez le lien "AVISO A LOS NAVEGANTES"). C'est un exemple très simple qui utilise 2 modèles pour voir des enregistrements individuellement ou une liste complète.
{
PATH_INFO: "^/avisos/?$"; # Selectionne by PATH_INFO
[SERVER_ADMIN: ".*"];
# Obtient des informations de SERVER_ADMIN. Optionnel
} -> {
DRIVER: "POSTGRESQL";
PGTTY: "/dev/console"; # Envoie les log à la console
PGDATABASE: "postgres";
# Nous faisons une requête (Toujours écrire l'oid qui
# l'utilisera en interne dans le fichier modèle
# pour lier les enregistrements individuels).
PGQUERY: "select oid,ct,titulo,texto,mt"
" from avisos"
" where (dt is NULL or dt > 'now')"
" order by mt desc";
# Fichier contenant le modèle
M4FILE: "/usr/local/etc/httpd/plantillas_m4/avisos.m4";
WEBMASTER: "term_1_match_0";
#TESTMODE: "TRUE";
}
# La règle de sélection suivante permet de sélectionner une déclaration (aviso)
# avec un OID connu (clé primaire ou primary key). L'information est incluse dans
# la variable PATH_INFO de la CGI.
{
PATH_INFO: "^/avisos/([0-9]+)/?$";
SERVER_ADMIN: ".*";
} -> {
DRIVER: "POSTGRESQL";
PGTTY: "/dev/console"; # Comme précédemment, permet
d'écrire les "logs" sur la console
PGDATABASE: "postgres";
OID: "term_0_match_1"; # assigne un OID
# Encore une fois la sélection est importante. Nous incluons l'OID
# au début du champ pour le cas où nous souhaitons écrire
# un hyperlien pour effacer cet enregistrement.
PGQUERY: "select oid,ct,titulo,texto,mt,dt,autor"
" from avisos"
" where
(dt is NULL or dt > 'now') and oid=OID";
# Le modèle est différent maintenant
M4FILE: "/usr/local/etc/httpd/plantillas_m4/avisos_oid.m4";
WEBMASTER: "term_1_match_0";
#TESTMODE: "TRUE";
}
|
|
define(<<<for>>>, <<<dnl ifelse(eval((<<<$2>>>) <= (<<<$3>>>)), 1, <<<define(<<<$1>>>,<<<$2>>>)$4<<<>>>dnl for(<<<$1>>>,eval(<<<$2>>>+1),<<<$3>>>, <<<$4>>>)dnl >>>)dnl >>>)dnl divert(0)dnl Mime-Version: 1.0 Content-type: text/html <HTML> <!-- la tabla est\xe1 vac\xeda --> >>>,<<<dnl /* PGRES_NTUPLES != 0 )( */ for(<<<i>>>,0,eval(PGRES_NTUPLES-1),<<<dnl </table> >>>)dnl /* PGRES_NTUPLES */ >>>,<<<dnl /* ifelse PGRES_RESULTSTATUS )(*/ Error en el resultado: <B>PGRES_RESULTSTATUS</b><BR> >>>)dnl <CENTER><HR WIDTH=100></center> |
|
divert(-1) $Id: generic_list.m4,v 1.1 1998/07/06 17:13:33 luis Exp $ define(<<<cell>>>, <<<PGRES_CELL_$1_$2>>>) define(<<<field>>>, <<<PGRES_FNAME_$1>>>) define(<<<for>>>, <<<dnl ifelse(eval((<<<$2>>>) <= (<<<$3>>>)), 1, <<<define(<<<$1>>>,<<<$2>>>)$4<<<>>>dnl for(<<<$1>>>,eval(<<<$2>>>+1),<<<$3>>>, <<<$4>>>)dnl >>>)dnl >>>)dnl divert(0)dnl Mime-Version: 1.0 Content-type: text/html <HTML> ifelse(PGRES_RESULTSTATUS, <<<PGRES_TUPLES_OK>>>,<<<dnl <!-- la tabla est\xe1 vac\xeda --> >>>,<<<dnl /* PGRES_NTUPLES != 0 )( */ >>>)dnl /* PGRES_NTUPLES */ >>>,<<<dnl /* ifelse PGRES_RESULTSTATUS )(*/ Error en el resultado: <B>PGRES_RESULTSTATUS</b><BR> >>>)dnl <CENTER><HR WIDTH=100></center> |
Le résultat peut-être vu à ces adresses:
http://slug.ctv.es/cgi-bin/pg2cgi/avisos/
ou
http://slug.ctv.es/cgi-bin/pg2cgi/avisos/20384
Traduit, de l'anglais, par , texte original en espagnol
| © Luis Colorado 1998 LinuxFocus 1999 Contacter le . |