Le XML-RPC en Shell UNIX

Pourquoi et comment réaliser un service XML-RPC en Shell UNIX

 «Pourquoi faire simple quand on peut faire compliqué ?» Telle est la devise des Shadocks qui pourrait s'appliquer à ma situation actuelle. En effet, j'ai pris quelques heures de mon temps -- 5 heures en tout et pour tout -- pour développer un service XML-RPC entièrement en Shell UNIX.

Tout est parti d'une amélioration de mon EntropyCMS. Je comparais le résultat avec une autre page, d'un autre site, afin de comprendre pourquoi Google trouvait des erreurs dans la sémentique; une page de référence dont le code était joli, propre, même s'il contenait un nombre incalculable de références à des réseaux sociaux dont la plupart faisaient redondance. Comme je regardais si les métadonnées et la sémantique de mon résultat produit avaient les mêmes propriétés que la référence choisie, je suis tombé sur une balise faisant du pingback en faisant appel à un obscur xmlrpc.php.

Ce n'était pas la première fois que je voyais cette référence. Mais, cette fois-ci, j'ai décidé de me pencher sur le sujet et d'en savoir plus sur ce XML-RPC car mes serveurs LAPSUS utilisent des services P2P et je vois régulièrement passer des requêtes XML-RPC sur mon réseau sans savoir ce que c'est exactement. D'autre part, étant un grand utilisateur de XML, j'étais très intrigué par un service utilisant un protocole utilisant ce langage.

Déjà, j'ai dû faire quelques recherches pour comprendre ce qu'est le pingback et quel peut être son intérêt. Et puis, de fil en aiguille, j'ai étudié le XML-RPC dans ce contexte et rapidement compris son intérêt, notamment dans le cadre de mon autre projet FINT, qui fontionne de façon a-centrée et nécessite un moyen de communication entre différentes instances.

J'ai développé mes propres API fondées sur des requêtes classiques GET/POST, qu'on découpe ensuite avec :

echo ${QUERY_STRING} | tr '&' '\n' | grep ^xxx= | cut -d"=" -f2 | …

C'est simple, rapide, efficace. Ça ne nécessite aucun composant supplémentaire. C'est facile à intégrer mais c'est moins structuré que du XML et donc plus rigide et moins puissant, notamment lorsqu'il faut gérer des informations structurées. Et puis c'est un format personnel -- un de plus. Autant utiliser un format ouvert.

En développant mon propre service, j'avais l'occasion d'apprendre quelque chose et surtout de le faire à ma façon, lui permettant alors de s'intéger parfaitement dans mes environnements, en comprenant ce que je fais et sans ajouter de composants exotiques qui auraient nécessité de nouveaux paquets à installer, de nouvelles configurations à effectuer, …

Bon, il faut avouer que l'usage du XML m'oblige alors à utiliser un composant exotique : un processeur XSLT. Personnellement, j'ai opté pour xsltproc qui est léger, ne nécessite aucune dépendance, rapide et affiche le résultat sur la console de sortie standard, ce qui permet de le relier aisément à d'autres commandes.

 Qu'est-ce que le XML-RPC ?

Le XML-RPC est un protocole simple de communication client/serveur fondé sur des messages XML et utilisant les mécanismes classique du web. Grosso modo, la même façon de procéder que ma méthode personnelle, mais avec des messages mieux structurés et quelques contraintes supplémentaires pour que tout le monde parle la même langue.

Le message envoyé est assez simple : il s'agit d'un appel à une méthode nommée et des paramètres associés. Par exemple :

<?xml version="1.0" encoding="utf-8"?> <methodCall>
<methodName>demo.sayHello</methodName>
<params/>
</methodCall>

Le serveur reçoit le message, exécute la méthode demandée et renvoie un résultat, en XML egalement :

<?xml version="1.0" encoding="utf-8"?>
<methodResponse>
<params>
<param><value>
<string>Hello!</string>
</value></param>
</params>
</methodResponse>

 Ce qui donne de façon schématique :

Schéma de fonctionnement XML-RPC
Schéma de fonctionnement du XML-RPC

Contrairement à SOAP qui est beaucoup plus complexe parce qu'il autorise l'usage de plusieurs espaces de noms simultanément, le XML-RPC se veut simple. Pas d'espaces de nom, juste du XML bio, sans sucre ajouté.

Il permet aussi le passage de paramètres selon une notation assez simple également, mais qui permet de couvrir un grand nombre de problématiques -- c'est en cela d'ailleurs que le XML est supérieur à la méthode classique : il faut se donner un peu plus de mal à penser la structure des données au départ, mais le résultat final est beaucoup plus facile à interpréter et valider.

 Comment ça marche ?

Bon, sur le papier, c'était simple. C'est toujours simple et beau sur le papier. Mais ce n'était que de la théorie et des exemples abstraits ou sans intérêt dans mon contexte  -- addition de deux nombres. Mais je ne vis pas en théorie. Pour faire du pingback, je devais récupérer une méthode, et deux paramètres -- la source et la cible.

Pour résumer simplement, le service fonctionne sur deux niveaux.

Le premier niveau technique qui vérifie que le message est envoyé selon les contraintes protocolaires précises. À ce niveau, le service peut renvoyer une erreur.

Passé le premier niveau, le second niveau ne s'occupe que de traiter le message et de renvoyer un résultat. Le serveur ne peut pas renvoyer d'erreur. Juste un retour normal (code 200) disant que l'opération demandée s'est mal passée.

J'ai décrit dans cet article comme la mécanique fonctionne :

Réaliser de A à Z un webservice XML-RPC en Shell UNIX

 Pour aller plus loin

Au-delà du XML-RPC, c'est la simplicité de la mise en place d'un tel protocole qui reste intéressant. Rien que le fait de faire des recherches afin de voir et comprendre comme ça fonctionne génère un certain nombre d'idées.

À partir de là, il est aisé de développer un service SOAP, c'est juste du XML un peu plus complexe, mais la mécanique de base est la même.

Comme j'ai réalisé des tests en ligne de commande avec wget, il est aisé de développer un petit client qui permettrait d'effectuer des opérations à distance sans utiliser de navigateur. Déposer un fichier sur une machine distante est simplement envisageable et on peut réaliser aisément un service de stockage à distance chiffré :

Schéma XML-RPC avec transfert chiffré
Schéma XML-RPC avec transfert chiffré

C'est assez facile à réaliser, il suffit d'intercaler un chiffrement avec openssl à l'entrée et d'envoyer le tout au format base64. On peut même interfacer le tout avec un bout de code Shell appelant Zenity ou bien depuis un clic droit sur un fichier. Ou même réaliser un service de prise de notes chiffré…

Dans le même genre, on peut transférer les images d'un timelapse depuis un Raspberry Pi vers un serveur web, ou n'importe quel autre fichier, à partir du même bout de code. Ou même de mettre à jour un blog; faire communiquer mon réseau de Raspberry pi qui serveillent mon infrastucture -- disponibilité des serveurs, débits réseaux, niveau de charge des onduleurs, etc. -- et de transmettre les informations par XML-RPC à un serveur centralisé chargé d'analyser le tout et de me prévenir en cas de problème -- oui parce que j'ai aussi un Raspberry Pi qui parle --, etc.

Mon idée de départ était d'implémenter un service de pingback. En travaillant sur XML-RPC, je suis tombé sur les webmentions. Et ça, j'adore. Simple, joli et efficace. Il faut que j'implémente ce truc… en Shell UNIX bien entendu.