Planet Collab

🔒
❌ About FreshRSS
There are new available articles, click to refresh the page.
Before yesterdayYour RSS feeds

RFC 8792: Handling Long Lines in Content of Internet-Drafts and RFCs

By Stéphane Bortzmeyer

Le sujet peut sembler un point de détail sans importance mais, dans un RFC, tout compte. Que serait une norme si les exemples de code et les descriptions en langage formel avaient la moindre ambiguïté ? C'est le cas par exemple des lignes trop longues : comment les couper pour qu'on comprenne bien ce qui s'est passé ? Ce RFC propose deux méthodes.

Le cas principal est celui des modules YANG (RFC 7950) et c'est pour cela que ce RFC sort du groupe de travail netmod. Mais le problème concerne en fait tous les cas où on veut mettre dans un RFC du texte dans un langage formel et que les lignes dépassent ce qui est généralement considéré comme acceptable. Notre RFC formalise deux solutions, toutes les deux traditionnelles et déjà souvent utilisées, mettre une barre inverse après les lignes coupées, ou bien mettre cette barre inverse et une autre au début de la ligne suivante. Donc, dans le premier cas, le texte :

Il n'est pas vraiment très long, mais c'est un exemple.
  
Ce texte, coupé à quarante-cinq caractères, donnerait :
Il n'est pas vraiment très long, mais c'est \
un exemple.
  
Ou bien :
Il n'est pas vraiment très long, mais c'est \
       un exemple.
  
Et, avec la seconde solution :
Il n'est pas vraiment très long, mais c'est \
\un exemple.
  

Si la forme officielle des RFC n'est plus le texte brut depuis le RFC 7990, il y a toujours une version en texte brut produite, suivant le format décrit dans le RFC 7994. Il impose notamment des lignes de moins de 72 caractères. Or, les exemples de code, ou les textes décrits en un langage formel (modules YANG, ABNF, ou ASN.1, par exemple), dépassent facilement cette limite. Les outils actuels comme xml2rfc ne gèrent pas vraiment ce cas, se contentant d'afficher un avertissement, et laissant l'auteur corriger lui-même, d'une manière non officiellement standardisée.

Désormais, c'est fait, il existe un tel standard, ce nouveau RFC, standard qui permettra notamment de bien traiter les textes contenus dans l'élement <sourcecode> (RFC 7991, section 2.48) du source du RFC. Naturellement, rien n'interdit d'utiliser cette norme pour autre chose que des RFC (section 2 du RFC).

Les deux stratégies possibles, très proches, sont « une seule barre inverse » et « deux barres inverses ». Dans les deux cas, un en-tête spécial est mis au début, indiquant quelle stratégie a été utilisée, pour qu'il soit possible de reconstituer le fichier original.

Dans le premier cas, la stratégie à une seule barre inverse (section 7 du RFC), une ligne est considérée pliée si elle se termine par une barre inverse. La ligne suivante (moins les éventuels espaces en début de ligne) est sa suite. Dans le deuxième cas, la stratégie à deux barres inverses (section 8), une autre barre inverse apparait au début des lignes de continuation.

Différence pratique entre les deux stratégies ? Avec la première (une seule barre inverse), le résultat est plus lisible, moins encombré de caractères supplémentaires. Par contre, comme les espaces au début de la ligne de continuation sont ignorés, cette stratégie va échouer pour des textes comportant beaucoup d'espaces consécutifs. La deuxième est plus robuste. La recommandation du RFC est donc d'essayer d'abord la première stratégie, qui produit des résultats plus jolis, puis, si elle échoue, la deuxième. L'outil rfcfold, présenté plus loin, fait exactement cela par défaut.

La section 4 rappellait le cahier des charges des solutions adoptées :

  • Repli des lignes automatisable (cf. le script rfcfold présenté à la fin), notamment pour le cas où un RFC ou autre document est automatiquement produit à partir de sources extérieures,
  • Reconstruction automatisable du fichier original, pour qu'on puisse réutiliser ce qu'on a trouvé dans un RFC en texte brut, ce qui est déjà utilisé par les outils de soumission d'Internet-Drafts, qui extraient le YANG automatiquement et le valident, pratique qui pourrait être étendu à XML et JSON, et qui assure une meilleure qualité des documents, dès la soumission.

En revanche, la section 5 liste les « non-buts » : il n'est pas prévu que les solutions fonctionnent pour l'art ASCII. Et il n'est pas prévu de gérer les coupures spécifiques à un format de fichier. Les stratégies décrites dans ce RFC sont génériques. Au contraire, des outils comme pyang ou yanglint connaissent la syntaxe de YANG et peuvent plier les lignes d'un module YANG plus intelligemment (cf. aussi RFC 8340).

L'annexe A du RFC contient un script bash qui met en œuvre les deux stratégies (le script rfcfold.bash). Ici, je pars d'un fichier JSON compact (au format du RFC 8785). D'abord, première stratégie (notez la ligne de documentation ajoutée au début) :

% ./rfcfold.bash -s 1 -i /tmp/i.txt -o /tmp/t.txt && cat /tmp/t.txt
========== NOTE: '\' line wrapping per RFC 8792 ===========

[{"af":6,"avg":23.4686283333,"dst_addr":"2001:67c:2218:e::51:41","ds\
t_name":"2001:67c:2218:e::51:41","dup":0,"from":"2a01:4240:5f52:bbc4\
::ba3","fw":5020,"group_id":26102101,"lts":30,"max":23.639063,"min":\
23.285885,"msm_id":26102101,"msm_name":"Ping","mver":"2.2.1","prb_id\
":1000276,"proto":"ICMP","rcvd":3,"result":[{"rtt":23.480937},{"rtt"\
:23.639063},{"rtt":23.285885}],"sent":3,"size":64,"src_addr":"2a01:4\
240:5f52:bbc4::ba3","step":null,"stored_timestamp":1593694541,"times\
tamp":1593694538,"ttl":52,"type":"ping"},{"af":6,"avg":65.9926666667\
...
Et avec la deuxième stratégie :
% ./rfcfold.bash -s 2 -i /tmp/i.txt -o /tmp/t.txt && cat /tmp/t.txt|more 
========== NOTE: '\\' line wrapping per RFC 8792 ==========

[{"af":6,"avg":23.4686283333,"dst_addr":"2001:67c:2218:e::51:41","ds\
\t_name":"2001:67c:2218:e::51:41","dup":0,"from":"2a01:4240:5f52:bbc\
\4::ba3","fw":5020,"group_id":26102101,"lts":30,"max":23.639063,"min\
\":23.285885,"msm_id":26102101,"msm_name":"Ping","mver":"2.2.1","prb\
\_id":1000276,"proto":"ICMP","rcvd":3,"result":[{"rtt":23.480937},{"\
\rtt":23.639063},{"rtt":23.285885}],"sent":3,"size":64,"src_addr":"2\
\a01:4240:5f52:bbc4::ba3","step":null,"stored_timestamp":1593694541,\
\"timestamp":1593694538,"ttl":52,"type":"ping"},{"af":6,"avg":65.992\
L'option -r du script permet d'inverser, c'està-dire de reconstituer le fichier original à partir du fichier aux lignes pliées.

L'outil rfcfold n'a pas de connaissance des formats de fichiers et coupe donc brutalement, y compris au milieu d'un nom de variable. Un outil plus intelligent (section 9.3) pourrait couper au bon endroit, par exemple, pour XML, juste avant le début d'un élément XML.

  • July 3rd 2020 at 02:00

Python re – match month only

By italchemy

 

import re
expr = “I was born on the 4th of July, 1974.”
p =  re.compile(r”(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)”)
m = p.search(expr)
print(m)
print(m.group())
pynetauto@CMW-PC18HB4A:~/HelloWorld$ /usr/bin/python3 /home/pynetauto/HelloWorld/script1.py
<re.Match object; span=(25, 29), match=’July‘>
pynetauto@CMW-PC18HB4A:~/HelloWorld$
July

RFC 8820: URI Design and Ownership

By Stéphane Bortzmeyer

Ah, les URI... Comme ces identificateurs sont très souvent vus et manipulés par un grand nombre d'utilisateurs, ils suscitent forcément des passions et des discussions sans fin. Ce RFC de bonne pratique s'attaque à un problème fréquent : les applications ou extensions qui imposent des contraintes sur l'URI, sans que cela soit justifié par le format de ces URI. Par exemple, on voit des CMS imposer, au moment de l'installation, que le CMS soit accessible par un URI commençant par le nom du logiciel. S'il s'appelle Foobar, on voit parfois des logiciels qui ne marchent que si l'URI commence par http://www.example.org/Foobar/. Pourquoi est-ce une mauvaise idée et que faudrait-il faire à la place ? (Ce document remplace le RFC 7320, dans le sens d'un plus grand libéralisme : moins de directives et davantage de suggestions.)

Ce RFC est destiné aux concepteurs d'application (par exemple les API REST) et aux auteurs de protocoles qui étendent les protocoles existants.

D'abord, l'argument d'autorité qui tue : la norme des URI, le RFC 3986, dit clairement que la structure d'un URI est déterminé par son plan (scheme en anglais) et que donc l'application n'a pas le droit d'imposer des règles supplémentaires. Les deux seuls « propriétaires » sont la norme décrivant le plan (qui impose une syntaxe, et certains éléments, par exemple le nom du serveur avec le plan http://) et l'organisation qui contrôle cet URI particulier (par exemple, toujours pour http://, l'organisation qui contrôle le domaine dans l'URI). Imposer des règles, pour une application ou une extension, c'est violer ce principe de propriété. (Il est formalisé dans une recommandation du W3C, section 2.2.2.1.)

Un exemple de structure dans les URI est l'interprétation du chemin (path en anglais) comme étant un endroit du système de fichiers. Ainsi, bien des serveurs HTTP, en voyant l'URI http://www.example.org/foo/bar/toto.html, chercheront le fichier en $DOCUMENT_ROOT/foo/bar/toto.html. C'est une particularité de la mise en œuvre de ce serveur, pas une obligation du plan d'URI http://. Un autre exemple est l'utilisation de l'extension du nom de fichier comme moyen de trouver le type de média de la ressource. (« Ça se termine en .png ? On envoie le type image/png. ») Ces deux cas ne violent pas forcément le principe de propriété des URI car l'utilisateur, après tout, choisit son serveur.

Mais, dans certains cas, l'imposition d'une structure (autre que celle déjà imposée par la norme du plan d'URI) a des conséquences néfastes :

  • Risque de collisions entre deux conventions différentes.
  • Risque d'instabilité si on met trop d'informations dans l'URI (voir la section 3.5.1 du document « Architecture of the World Wide Web, Volume One », cité plus haut). Pour reprendre l'exemple de l'extension du fichier, si on change le format de l'image de PNG en JPEG, l'URI changera, ce qui est néfaste.
  • Rigidité accrue. Si un logiciel impose d'être installé en /Foobar comme dans l'exemple au début, il contraint les choix pour l'administrateur système (et si je veux des URI avec un chemin vide, genre http://foobar.example.org/, je fais quoi ?)
  • Risque que le client fasse des suppositions injustifiées. Si une spécification décrit le paramètre sig comme étant forcément une signature cryptographique, il y a une possibilité qu'un logiciel client croit, dès qu'il voit un paramètre de ce nom, que c'est une signature.
Donc, pour toutes ces raisons, notre RFC déconseille fortement de rajouter des règles de structure dans les URI. Ces règles diminuent la liberté du propriétaire de l'URI.

Qui risque de violer ce principe ? Les auteurs d'applications, comme dans l'exemple Foobar plus haut, mais aussi des gens qui font des extensions aux URI, par le biais de nouvelles spécifications (par exemple pour mettre des signatures ou autres métadonnées dans l'URI). En revanche, ce principe ne s'applique pas au propriétaire lui-même, qui a évidemment le droit de définir ses règles pour la gestion de ses URI (exemple : le webmestre qui crée un schéma de nommage des URI de son site Web). Et cela ne s'applique pas non plus au cas où le propriétaire de l'URI reçoit lui-même une délégation pour gérer ce site (par exemple, un RFC qui crée un registre IANA et spécifie la structure des URI sous https://www.iana.org/ est dans son droit, l'IANA agissant sur délégation de l'IETF). Le principe ? On n'interdit pas de mettre de la structure dans les URI, on dit juste qui a le droit de le faire.

La partie normative de notre RFC est la section 2. Elle explicite le principe. D'abord, éviter de contraindre l'usage d'un plan particulier. Par exemple, imposer http:// peut être trop contraignant, certaines applications ou extensions pourraient marcher avec d'autres plans d'URI comme par exemple file:// (RFC 8089).

D'autre part, si on veut une structure dans les URI d'un plan particulier, cela doit être spécifié dans le document qui définit le plan (RFC 7230 pour http://, RFC 6920 pour ni:, etc) pas dans une extension faite par d'autres (« touche pas à mon plan »).

Les URI comprennent un champ « autorité » juste après le plan. Les extensions ou applications ne doivent pas imposer de contraintes particulières sur ce champ. Ainsi, pour http://, l'autorité est un nom de domaine et notre RFC ne permet pas qu'on lui mette des contraintes (du genre « le premier composant du nom de domaine doit commencer par foobar-, comme dans foobar-www.example.org »).

Même chose pour le champ « chemin », qui vient après l'autorité. Pas question de lui ajouter des contraintes (comme dans l'exemple du CMS qui imposerait /Foobar comme préfixe d'installation). La seule exception est la définition des URI bien connus du RFC 8615 (ceux dont le chemin commence par /.well-known). Le RFC 6415 donne un exemple d'URI bien connus, avec une structure imposée.

Autre conséquence du principe « bas les pattes » et qui est, il me semble, plus souvent violée en pratique, le champ « requête » (query). Optionnel, il se trouve après le point d'interrogation dans l'URI. Notre RFC interdit aux applications d'imposer l'usage des requêtes, car cela empêcherait le déploiement de l'application dans d'autres contextes où, par exemple, on veut utiliser des URI sans requête (je dois dire que mes propres applications Web violent souvent ce principe). Quant aux extensions, elles ne doivent pas contraindre le format des requêtes. L'exemple cité plus haut, d'une extension hypothétique, qui fonctionnerait par l'ajout d'un paramètre sig aux requêtes pour indiquer une signature est donc une mauvaise idée. Une telle extension causerait des collisions (applications ou autres extensions qui voudraient un paramètre de requête nommé sig) et des risques de suppositions injustifié (un logiciel qui se dirait « tiens, un paramètre sig, je vais vérifier la signature, ah, elle est invalide, cet URI est erroné »). Au passage, les préfixes n'aident pas. Supposons qu'une extension, voulant limiter le risque de collisions, décide que tous les paramètres qu'elle définit commencent par myapp_ (donc, la signature serait myapp_sig). Cela ne supprime pas le risque de collisions puisque le préfixe lui-même ne serait pas enregistré.

(Sauf erreur, Dotclear gère bien cela, en permettant, via les « méthodes de lecture » PATH_INFO ou QUERY_STRING d'avoir les deux types d'URI, sans requête ou bien avec.)

Pourtant, HTML lui-même fait cela, dans la norme 4.01, en restreignant la syntaxe lors de la soumission d'un formulaire. Mais c'était une mauvaise idée et les futures normes ne devraient pas l'imiter.

Comme précédemment, les URI bien connus ont, eux, droit à changer la syntaxe ou contraindre les paramètres puisque, d'une certaine façon, l'espace sous .well-known est délégué à l'IETF et n'est plus « propriété » de l'autorité.

Dernier champ de l'URI à étudier, l'identificateur de fragment (ce qui est après le croisillon). Les définitions d'un type de média (RFC 6838) ont le droit de spécifier la syntaxe d'un identificateur de fragment spécifique à ce type de média (comme ceux du texte brut, dans le RFC 5147). Les autres extensions doivent s'en abstenir sauf si elles normalisent une syntaxe pour de futurs types de médias (comme le fait le RFC 6901).

Bon, assez de négativité et d'interdiction. Après les « faites pas ci » et les « faites pas ça », la section 3 de notre RFC expose les alternatives, les bonnes pratiques pour remplacer celles qui sont interdites ici. D'abord, si le but est de faire des liens, il faut se rappeler qu'il existe un cadre complet pour cela, décrit dans le RFC 8288. Une application peut utiliser ce cadre pour donner la sémantique qu'elle veut à des liens. Autre technique rigolote et peu connue, les gabarits du RFC 6570, qui permettent de gérer facilement le cas de données spécifiques à l'application dans un URI.

Et, comme cité plusieurs fois, les URI bien connus du RFC 8615 sont un moyen de déclarer sa propre structure sur des URI. Par contre, ils sont censés avoir un usage limité (accéder à des métadonnées avant de récupérer une ressource) et ne sont pas un moyen générique d'échapper aux règles qui nous dérangent !

Les changements depuis le premier RFC qui avait décrit ces règles (RFC 7320) sont résumés dans l'annexe A. En gros, moins d'interdictions, et davantage de conseils. Par exemple, la règle comme quoi une application ne devrait pas empêcher l'utilisation de futurs plans (comme file: en plus de http:) n'utilise maintenant plus le vocabulaire normatif du RFC 2119 et est donc désormais davantage un avis. De même, pour le composant « requête » de l'URI, l'interdiction de spécifier sa syntaxe dans les applications n'est désormais plus une règle absolue. Autre cas, le RFC 7320 parlait négativement, non seulement du préfixe de chemin d'URI fixe (le /Foobar dans mes exemples) mais même d'une partie fixe du chemin, y compris si elle n'était pas au début du chemin. Cela avait suscité des débats houleux dans la discussion du successeur du RFC 6962 et cette restriction a donc été supprimée.

  • July 1st 2020 at 02:00

Python re – match month only

By italchemy

 

import re
expr = “I was born on the 4th of July, 1974.”
p =  re.compile(r”(Jan(uary)?|Feb(ruary)?|Mar(ch)?|Apr(il)?|May|Jun(e)?|Jul(y)?|Aug(ust)?|Sep(tember)?|Oct(ober)?|Nov(ember)?|Dec(ember)?)”)
m = p.search(expr)
print(m)
print(m.group())
pynetauto@CMW-PC18HB4A:~/HelloWorld$ /usr/bin/python3 /home/pynetauto/HelloWorld/script1.py
<re.Match object; span=(25, 29), match=’July‘>
pynetauto@CMW-PC18HB4A:~/HelloWorld$
July

RFC 8785: JSON Canonicalization Scheme (JCS)

By Stéphane Bortzmeyer

Des opérations cryptographiques comme la signature sont nettement plus simples lorsqu'il existe une forme canonique des données, une représentation normalisée qui fait que toutes les données identiques auront la même représentation. Le format de données JSON n'a pas de forme canonique standard, ce RFC documente une des canonicalisations possibles, JCS (JSON Canonicalization Scheme).

Pourquoi canonicaliser ? Parce que deux documents JSON dont le contenu est identique peuvent avoir des représentations texte différentes. Par exemple :

{"foo": 1, "bar": 3}
  
et
{
  "foo": 1,
  "bar": 3
}
  
représentent exactement le même objet JSON. Mais la signature de ces deux formes textuelles ne donnera pas le même résultat. Pour les mécanismes de signature de JSON (comme JWS, décrit dans le RFC 7515), il serait préférable d'avoir un moyen de garantir qu'il existe une représentation canonique de l'objet JSON. Ce RFC en propose une. Je vous le dis tout de suite, la forme canonique de l'objet ci-dessus sera :
{"bar":3,"foo":1}
  

JSON est normalisé dans le RFC 8259. Il n'a pas de canonicalisation standard. Comme c'est une demande fréquente, plusieurs définitions d'une forme canonique de JSON ont été faites (cf. annexe H du RFC), comme Canonical JSON ou comme JSON Canonical Form. Mais aucune n'est encore la référence. (Vous noterez que ce RFC n'est pas une norme.) Cette situation est assez embêtante, alors que XML, lui, a une telle norme (cf. XML Signature).

Notez que la solution décrite dans ce RFC se nomme JCS, mais qu'il y a aussi un autre JCS, JSON Cleartext Signature.

Parmi les concepts importants de la proposition de ce RFC, JCS :

  • Réutiliser les règles de sérialisation de la norme ECMA, connues sous le nom de « ES6 »,
  • Le JSON doit suivre le sous-ensemble I-JSON du RFC 7493, ce qui implique l'absence de duplication des noms de membres dans un objet, l'utilisation de IEEE-754 pour les nombres, etc.

La section 3 du RFC décrit les opérations qui, ensemble, forment la canonicalisation JCS. À partir de données en mémoire (obtenues soit en lisant un fichier JSON, ce que je fais dans les exemples à la fin, soit en utilisant des données du programme), on émet du JSON avec :

  • Pas d'espaces entre les éléments lexicaux ("foo":1 et pas "foo": 1),
  • Représentation des nombres en suivant les règles de sérialisation « ES6 » citées plus haut (3000000 au lieu de 3E6, c'est la section 7.12.2.1 de ES6, si vous avez le courage, les puissances de 10 où l'exposant est inférieur à 21 sont développées),
  • Membres des objets (rappel : un objet JSON est un dictionnaire) triés ({"a":true,"b":false} et non pas {"b:"false,"a":true}),
  • Chaînes de caractères en UTF-8.
Concernant le tri, André Sintzoff me fait remarquer que les règles de tri de JSON sont parfois complexes. Évidentes pour les caractères ASCII, elles sont plus déroutantes en dehors du BMP.

Plusieurs annexes complètent ce RFC. Ainsi, l'annexe B fournit des exemples de canonicalisation des nombres.

Et pour les travaux pratiques, on utilise quoi ? L'annexe A du RFC contient une mise en œuvre en JavaScript, et l'annexe G une liste d'autres mises en œuvre (que vous pouvez aussi trouver en ligne). Ainsi, en npm, il y a https://www.npmjs.com/package/canonicalize et, en Java, il y a https://github.com/erdtman/java-json-canonicalization. (Si vous voulez programmer la canonicalisation de JSON vous-même, l'annexe F contient d'utiles conseils aux programmeurs. Mais, ici, on se contentera de logiciels déjà écrits.)

Commençons avec Python, et https://github.com/cyberphone/json-canonicalization/tree/master/python3. Avec cet exemple de départ :

{
       "numbers": [333333333.33333329, 1E30, 4.50,
                   2e-3, 0.000000000000000000000000001],
       "string": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
       "literals": [null, true, false]
 }
  
Et ce programme :
from org.webpki.json.Canonicalize import canonicalize

import json 
import sys

raw = open(sys.argv[1]).read()
data = canonicalize(json.loads(raw))
print(data.decode())
  
On obtient :
% git clone https://github.com/cyberphone/json-canonicalization.git
% export PYTHONPATH=json-canonicalization/python3/src
% ./canonicalize.py test.json
{"literals":[null,true,false],"numbers":[333333333.3333333,1e+30,4.5,0.002,1e-27],"string":"€$\u000f\nA'B\"\\\\\"/"}
  

Et en Go ? Avec le même fichier JSON de départ, et ce programme :

package main

import ("flag";
	"fmt";
	"os";)

import "webpki.org/jsoncanonicalizer"

func main() {
	flag.Parse()
	file, err := os.Open(flag.Arg(0))
	if err != nil {
		panic(err)
	}
	data := make([]byte, 1000000)
	count, err := file.Read(data)
	if err != nil {
		panic(err)
	}
	result, err := jsoncanonicalizer.Transform(data[0:count])
	if err != nil {
		panic(err);
	} else {
		fmt.Printf("%s", result);
	}
}
  
On arrive au même résultat (ce qui est bien le but de la canonicalisation) :
% export GOPATH=$(pwd)/json-canonicalization/go
% go build canonicalize.go
%  ./canonicalize.py test.json
{"literals":[null,true,false],"numbers":[333333333.3333333,1e+30,4.5,0.002,1e-27],"string":"€$\u000f\nA'B\"\\\\\"/"}
  
Comme notre RFC contraint le JSON à suivre le sous-ensemble I-JSON (RFC 7493), si le texte d'entrée ne l'est pas, il va y avoir un problème. Ici, avec un texte JSON qui n'est pas du I-JSON (deux membres de l'objet principal ont le même nom) :
% cat test3.json
{
  "foo": 1,
  "bar": 3,
  "foo": 42
}

% ./canonicalize test3.json
panic: Duplicate key: foo
  

L'excellent programme jq n'a pas d'option explicite pour canonicaliser, mais Sébastien Lecacheur me fait remarquer que les options -c et -S donnent apparemment le même résultat (y compris sur les nombres, ce qui ne semble pas documenté) :

% cat example.json 
{
  "foo":                               1,
  "bar": 3000000000000000000000000000000,
"baz": true
}

% jq -cS . example.json
{"bar":3e+30,"baz":true,"foo":1}
  
Par contre, je n'ai rien trouvé sur ce formateur en ligne.

Comme il y a un brevet pour tout, notez qu'apparemment VMware prétend avoir inventé la canonicalisation JSON (cf. ce signalement, et le commentaire « The patent is effectively a JSON based "remake" of XML's "enveloped" signature scheme which in the submitter's opinion makes it invalid. »).

  • June 29th 2020 at 02:00

Seven Steps to Improving Your Agent’s First Call Resolution

By Guest Author - William Balvanz

William Balvanz is the Training Specialist at Voyant, a US-based UCaaS provider. He has years of experience in the call center space, as well as cloud-based communications. We have once again called on William to provide some direction as to how to coach your agents toward First Call Resolution for your customers.

[Book] Regex basics 1 – metacharacters for repetition

By italchemy

Written on 24/11/2019 at 20:30

# Use of Python regex metacharacters
Search, extract, replace complicated texts
very powerful metacharacter based searching tool using various character pattern combinations.
Regular Expression function is provided by re module in Python.

#.1 metacharacters
Regular Expression has many built-in metacharacters to display characters or character patterns.
These metacharacters allow repetition possible.

#.1 Python metacharacters - repetition

metacharacters | Description | Example

1 * | repeats 0 or more times |  zo*m matches zm, zom, zoom, zooom, zoooom, zooooom
Note: repeats the character infront of the *, so in this case alphabet 'o'

import re

maz = re.findall("zo*m" , "zm, zom, zoom, zooom, zoooom, zooooom")
print(maz)
['zm', 'zom', 'zoom', 'zooom', 'zoooom', zooooom]

2 + | repeats once or more than once | zo+m matches zom, zoom, zooom, zoo..m etc.
Note: repeats the character infront of the +, so in this case alphabet 'o'

import re

maz = re.findall("zo+m" , "zm, zom, zoom, zooom, zoooom, zooooom")
print(maz)
['zom', 'zoom', 'zooom', 'zoooom', 'zooooom']

3 ? | repeats 0 times or once | zo?m matches zm and zom.
Note: repeats the character infront of the ?, so in this case alphabet 'o'

import re

maz = re.findall("zo?m" , "zm, zom, zoom, zooom, zoooom, zooooom")
print(maz)
['zm', 'zom']

4 {m} | repeats m number of times | zo{3}m matches zooom.
Note: repeats the character infront of the {m}, so in this case alphabet 'o'

import re

maz = re.findall("zo{3}m" , "zm, zom, zoom, zooom, zoooom, zooooom")
print(maz)
['zooom']


5 {m, n} | repeats m number of times | zo{2,4}m matches zoom - zoooom
Note: repeats the character infront of the {m}, so in this case alphabet 'o'

import re

maz = re.findall("zo{2,4}m" , "zm, zom, zoom, zooom, zoooom, zooooom")
print(maz)
['zoom', 'zooom', 'zoooom']

Catpure Gigabit interface only – GigabitEthernet\d[/]\d\d?

By italchemy

s= “””

Interface IP-Address OK? Method Status Protocol
Vlan1 unassigned YES NVRAM administratively down down
Vlan10 10.193.40.11 YES NVRAM up up
FastEthernet0 unassigned YES NVRAM administratively down down
GigabitEthernet0/1 unassigned YES unset up up
GigabitEthernet0/2 unassigned YES unset down down
GigabitEthernet0/3 unassigned YES unset up up
GigabitEthernet0/4 unassigned YES unset down down
GigabitEthernet0/5 unassigned YES unset down down
GigabitEthernet0/6 unassigned YES unset down down
GigabitEthernet0/7 unassigned YES unset up up
GigabitEthernet0/8 unassigned YES unset down down
GigabitEthernet0/9 unassigned YES unset down down
GigabitEthernet0/10 unassigned YES unset down down

“””

 

>>> m = re.findall(r”(GigabitEthernet\d[/]\d\d?)”, s)

>>> m

[‘GigabitEthernet0/1’, ‘GigabitEthernet0/2’, ‘GigabitEthernet0/3’, ‘GigabitEthernet0/4’, ‘GigabitEthernet0/5’, ‘GigabitEthernet0/6’, ‘GigabitEthernet0/7’, ‘GigabitEthernet0/8’, ‘GigabitEthernet0/9’, ‘GigabitEthernet0/10’]

VMware ovf to ova conversion using OVFTool

By italchemy

Sometime you have to change ovf files to ova or ova to ovf.

Step 1: OVFTool is installed in workstation by default. Start CLI Prompt line as admin and drill down to the folder with OVFTool.exe

cd C:\Program Files (x86)\VMware\VMware Workstation\OVFTool

 

Step 2a: To change ovf file to ova, run 

ovftool.exe C:\file_path2\vm..ovf C:\file_path1\vm.ova

Step 2b: To change ova file to ovf, run

ovftool.exe C:\file_path1\vm.ova C:\file_path2\vm.ovf

The following example is conversion from ovf file to ova file.  

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool>ovftool.exe C:\pams_v0\ubuntu20.ovf C:\pams_v1\ubuntu20.ova

Opening OVF source: C:\ubuntu20_v0\ubuntu20.ovf
The manifest validates
Opening OVA target: C:\ubuntu20_v0\ubuntu20.ova
Writing OVA package: C:\ubuntu20_v1\ubuntu20.ova
Transfer Completed
Completed successfully

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool> cd /ubuntu20_v1

C:\ubuntu20_v1>dir
Volume in drive C has no label.
Volume Serial Number is 54B2-806B

Directory of C:\pams_v1

23/06/2020 07:13 PM <DIR> .
23/06/2020 07:13 PM <DIR> ..
23/06/2020 07:16 PM 2,934,892,032 ubuntu20.ova
1 File(s) 2,934,892,032 bytes
2 Dir(s) 24,086,020,096 bytes free

 

How to use Contact Center Messaging to Your Advantage

By Dave Gilbert

Within a call center queue there exists the opportunity to tailor your messaging for best impact. Entrance messages, Messages on hold, and Comfort messages are the three main areas of concern. We will explore these three sections and offer advice on how to maximize the impact of these messages.

Catpure Gigabit interface only – GigabitEthernet\d[/]\d\d?

By italchemy

s= “””

Interface IP-Address OK? Method Status Protocol
Vlan1 unassigned YES NVRAM administratively down down
Vlan10 10.193.40.11 YES NVRAM up up
FastEthernet0 unassigned YES NVRAM administratively down down
GigabitEthernet0/1 unassigned YES unset up up
GigabitEthernet0/2 unassigned YES unset down down
GigabitEthernet0/3 unassigned YES unset up up
GigabitEthernet0/4 unassigned YES unset down down
GigabitEthernet0/5 unassigned YES unset down down
GigabitEthernet0/6 unassigned YES unset down down
GigabitEthernet0/7 unassigned YES unset up up
GigabitEthernet0/8 unassigned YES unset down down
GigabitEthernet0/9 unassigned YES unset down down
GigabitEthernet0/10 unassigned YES unset down down

“””

 

>>> m = re.findall(r”(GigabitEthernet\d[/]\d\d?)”, s)

>>> m

[‘GigabitEthernet0/1’, ‘GigabitEthernet0/2’, ‘GigabitEthernet0/3’, ‘GigabitEthernet0/4’, ‘GigabitEthernet0/5’, ‘GigabitEthernet0/6’, ‘GigabitEthernet0/7’, ‘GigabitEthernet0/8’, ‘GigabitEthernet0/9’, ‘GigabitEthernet0/10’]

VMware ovf to ova conversion using OVFTool

By italchemy

Sometime you have to change ovf files to ova or ova to ovf.

Step 1: OVFTool is installed in workstation by default. Start CLI Prompt line as admin and drill down to the folder with OVFTool.exe

cd C:\Program Files (x86)\VMware\VMware Workstation\OVFTool

 

Step 2a: To change ovf file to ova, run 

ovftool.exe C:\file_path2\vm..ovf C:\file_path1\vm.ova

Step 2b: To change ova file to ovf, run

ovftool.exe C:\file_path1\vm.ova C:\file_path2\vm.ovf

The following example is conversion from ovf file to ova file.  

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool>ovftool.exe C:\pams_v0\ubuntu20.ovf C:\pams_v1\ubuntu20.ova

Opening OVF source: C:\ubuntu20_v0\ubuntu20.ovf
The manifest validates
Opening OVA target: C:\ubuntu20_v0\ubuntu20.ova
Writing OVA package: C:\ubuntu20_v1\ubuntu20.ova
Transfer Completed
Completed successfully

C:\Program Files (x86)\VMware\VMware Workstation\OVFTool> cd /ubuntu20_v1

C:\ubuntu20_v1>dir
Volume in drive C has no label.
Volume Serial Number is 54B2-806B

Directory of C:\pams_v1

23/06/2020 07:13 PM <DIR> .
23/06/2020 07:13 PM <DIR> ..
23/06/2020 07:16 PM 2,934,892,032 ubuntu20.ova
1 File(s) 2,934,892,032 bytes
2 Dir(s) 24,086,020,096 bytes free

 

RFC 8765: DNS Push Notifications

By Stéphane Bortzmeyer

Lorsqu'une donnée DNS change dans les serveurs faisant autorité, les clients ne seront prévenus que lorsqu'ils reviendront demander, et cela peut être long s'ils ont mémorisé l'ancienne valeur. Ce RFC propose une autre approche, où les données DNS sont poussées vers les clients au lieu d'attendre qu'ils tirent.

Qu'est-ce qui fait que des données DNS changent ? Cela peut être l'administrateur système qui a changé la zone et rechargé le serveur faisant autorité. Ou bien il y a pu y avoir mise à jour dynamique (RFC 2136). Ou encore d'autres mécanismes. Dans tous les cas, certains clients DNS (par exemple pour la découverte de services du RFC 6763) aimeraient bien être prévenus tout de suite (et voir la nouvelle imprimante du réseau local apparaitre dans la liste). Le DNS est purement pull et ces clients voudraient un peu de push.

Cette idée de protocoles push, où on envoie les données vers les clients au lieu d'attendre qu'il les réclame, est nouvelle pour le DNS mais ancienne dans l'Internet (modèle publish/subscribe ou design pattern Observateur). Parmi les protocoles IETF, XMPP peut fonctionner ainsi (cf. XEP0060).

Il y a quand même un peu de push dans une variante du DNS, mDNS (RFC 6762, section 5.2), où les changements peuvent être poussés vers une adresse IP multicast. Mais des protocoles comme la découverte de services du RFC 6763 peuvent aussi fonctionner sans multicast et cette solution ne leur convient donc pas. Il existait une solution non-standard, LLQ (Long-Lived Queries), décrite dans le RFC 8764 et mise en œuvre dans les produits Apple (cf. RFC 6281). Utilisant UDP, elle ne convient guère au DNS moderne.

Il existe aujourd'hui un mécanisme plus pratique pour déployer des fonctions comme le push : DSO (DNS Stateful Operations, RFC 8490), qui repose sur des connexions de longue durée, sur TCP (et TLS pour la sécurité). La solution push est donc bâtie sur DSO, et il est donc bon d'avoir lu le RFC 8490 avant celui-ci.

La section 3 de notre RFC présente le protocole DNS push. Un client s'abonne à un service de notification et, une fois abonné, il reçoit les nouveautés. Quand il n'a plus besoin des données, le client se déconnecte. L'abonnement est valable pour un certain couple {nom de domaine, type de données}. Client et serveur utilisent le mécanisme DSO du RFC 8490. Comment le client trouve-t-il le serveur ? Ce n'est pas forcément un des serveurs listés comme faisant autorité pour la zone. Il peut être trouvé en demandant à son résolveur normal (s'il accepte DSO, le client peut tenter sa chance) dans le DNS, puis, si ça ne marche pas, via une requête SRV pour le nom _dns-push-tls._tcp.LA-ZONE (cf. section 6, et son enregistrement à l'IANA). Rappelez-vous que, si un serveur DNS accepte DSO mais pas DNS push, il répondra avec un code de retour DNS DSOTYPENI (RFC 8490, section 5.1.1).

Pour éviter de trop charger le serveur, le client ne doit s'abonner que s'il a une bonne raison, par exemple parce qu'une fenêtre de sélection d'une imprimante est ouverte, et qu'il veut la rafraichir en permanence. Lorsque le client va s'endormir ou estomper son écran pour économiser sa batterie, il devrait se désabonner d'abord. En tout cas, le mécanisme DNS push ne devrait pas être utilisé 24x7, ce n'est pas son but. (Et c'est inutile, le mécanisme est suffisamment rapide pour pouvoir être invoqué seulement quand on en a besoin.)

De toute façon, le serveur n'est pas obligé d'accepter tous les clients qui se présentent. Il peut rejeter les abonnements s'il manque de ressources (section 4 du RFC).

Comment est-ce que le client demande du DNS push ? En s'abonnant, une fois la session DSO établie. Il envoie une requête de type DSO SUBSCRIBE (la syntaxe des TLV DSO est dans le RFC 8490, section 5.4.4). Dans les données de la requête se trouvent le nom de domaine et le type de données qui intéressent le client. Le serveur répond alors NOERROR (ou bien un code DNS d'erreur s'il y a un problème, par exemple REFUSED si le serveur ne veut pas) et envoie une réponse de type SUBSCRIBE (même type que la requête, c'est le bit QR de l'en-tête DNS qui permet de différencier requête et réponse). Il est parfaitement légitime pour un client de s'abonner à un nom de domaine qui n'existe pas encore, et le serveur ne doit donc jamais répondre NXDOMAIN.

Une fois l'abonnement accepté, le client attend tranquillement et, lorsqu'un changement survient, le serveur envoie des messages de type DSO PUSH (code 0x0041). Les données contenues dans ce message sont formatées comme les messages DNS habituels, avec une exception : un TTL valant 0xFFFFFFFF signifie que l'ensemble d'enregistrements concerné a été supprimé.

À la fin, quand le client n'est plus intéressé, il envoie un message DSO UNSUBSCRIBE (code 0x0042). Encore plus radical, le client peut mettre fin à la session DSO, annulant ainsi tous ses abonnements.

Et la sécurité de ce DNS push (section 7 du RFC) ? DNS push impose l'utilisation de TLS (donc on a du DSO sur TLS sur TCP). Le client doit authentifier le serveur selon le profil strict du RFC 8310. Ensuite, DNSSEC est recommandé pour la découverte du serveur DNS push, lorsqu'on utilise les requêtes SRV, puis DANE pour vérifier le serveur auquel on se connecte (RFC 7673).

Ensuite, DNS push permet d'utiliser les données précoces du RFC 8446 (section 2.3), ce qui permet de diminuer la latence. Mais elles posent quelques problèmes de sécurité : plus de confidentialité persistante, et risque de duplication des messages. D'autre part, si on utilise la reprise de session du RFC 8446 (section 2.2), il faut noter que, si elle permet de ne pas recommencer toute la session TLS, en revanche, elle ne garde pas les abonnements DNS push, que le client devra donc renouveler.

Désolé, mais je ne connais pas encore de mise en œuvre de ce RFC, à part dans le monde Apple.

  • June 23rd 2020 at 02:00
❌