Ce court RFC spécifie comment utiliser le protocole d'avitaillement
Le RFC est court car il n'y a pas grand'chose à dire, juste
l'utilisation des primitives de TCP (ouverture et fermeture de
connexion, section 2 du RFC), l'ordre des messages (section 3), le
L'entier en question est fixé à 32 bits. Si on programme un client
EPP en
struct.pack("I", length)
force un entier (
# Machine 32 bits :
Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import struct
>>> print struct.calcsize("l")
4
>>> print struct.calcsize(">l")
4
# Machine 64 bits :
Python 2.4.5 (#2, Mar 11 2008, 23:38:15)
[GCC 4.2.3 (Debian 4.2.3-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import struct
>>> print struct.calcsize("l")
8
>>> print struct.calcsize(">l")
4
Si on a quand même un doute, on peut tester la taille obtenue mais ce
code est probablement inutile (merci à
David Douard pour son aide ici) :
I"
if struct.calcsize(format_32) < 4:
format_32 = ">L"
if struct.calcsize(format_32) != 4:
raise Exception("Cannot find a 32 bits integer")
elif struct.calcsize(format_32) > 4:
format_32 = ">H"
if struct.calcsize(format_32) != 4:
raise Exception("Cannot find a 32 bits integer")
else:
pass
...
def int_from_net(data):
return struct.unpack(format_32, data)[0]
def int_to_net(value):
return struct.pack(format_32, value)
]]>
L'algorithme complet d'envoi est :
epp_as_string = ElementTree.tostring(epp, encoding="UTF-8")
# +4 for the length field itself (section 4 mandates that)
# +2 for the CRLF at the end
length = int_to_net(len(epp_as_string) + 4 + 2)
self._socket.send(length)
self._socket.send(epp_as_string + "\r\n")
et la lecture :
data = self._socket.recv(4) # RFC 5734, section 4, the length
# field is 4 bytes long
length = int_from_net(data)
data = self._socket.recv(length-4)
epp = ElementTree.fromstring(data)
if epp.tag != "{%s}epp" % EPP.NS:
raise EPP_Exception("Not an EPP instance: %s" % epp.tag)
xml = epp[0]
Le code Python complet (qui ne met en œuvre qu'une petite
partie de EPP, le but était juste de tester ce
def safe_recv(s, n):
data = ''
while (n > 0):
tmp = s.recv(n)
data += tmp
n -= len(tmp)
return data
(Merci à Kim-Minh Kaplan pour son
aide sur ce point.)
Pour
print pack('N', length($out) + 4).$out;
et pour lire un élément EPP :
my $length = unpack "N", $buf;
...
$rc = read STDIN, $buf, $length;
Puisque le format
À noter que cette lecture du champ longueur présente un risque de
sécurité : si le serveur
La section 8, consacrée à la sécurité, et surtout la nouvelle
section 9, consacrée à
La liste des changements par rapport au