Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

send() et HTTP

19 réponses
Avatar
n
Bonjour =E0 tous, je fais un serveur de synchronisation SyncML pour
synchroniser des t=E9l=E9phones mobiles.

lorsque le mobile demande une synchronisation au serveur, le serveur
fait un accept() sur la socket qui correspond, lit la demande du
mobile et g=E9n=E8re une r=E9ponse (jusque l=E0, =E7a fonctionne imp=E9cabl=
e)
Le probl=E8me c'est pour envoyer la r=E9ponse, l=E0 je fait la chose
suivante :

length =3D len(response)
head =3D []
head.append("HTTP/1.1 200 OK\n")
head.append("Server: myPythonServer\n")
head.append("Cache-Control: no-store, no-cache, must-revalidate, post-
check=3D0, pre-check=3D0\n")
head.append("Pragma: no-cache\n")
head.append("Content-Length: "+str(length)+"\n")
head.append("Content-Type: application/vnd.syncml+wbxml\n\n")
head =3D ''.join(head)
client.send(head+response)

(je me suis inspir=E9 des trames sniff=E9es entre le t=E9l=E9phone et un si=
te
de synchronisation).

Sauf que =E7a ne doit pas =EAtre la bonne m=E9thode car quand je sniffe les
trames, ma trame (qui contient les flags PSH et ACK) est suivie d'une
trame provenant du t=E9l=E9phone et contenant les flags FIN et ACK et
aucune donn=E9e. La connection s'arr=EAte alors =E0 ce point.

et quand je compare mes donn=E9es avec celle sinff=E9es entre le mobile et
le site de synchronisation, le contenu de la r=E9ponse est identique, je
pense donc que le probl=E8me vient de la m=E9thode d'envoi.

Pouvez vous m'aider, j'ai un peut de mal =E0 r=E9soudre moi m=EAme...

Fabien

9 réponses

1 2
Avatar
Bruno Desthuilliers
head = "rn".join((
"HTTP/1.1 200 OK",
"Server: myPythonServer",
"Cache-Control: no-store, no-cache, must-revalidate," +
"post-check=0, pre-check=0",
"Pragma: no-cache",
"Content-Length: %s" % len(response),
"Content-Type: application/vnd.syncml+wbxml",
))


ok, et entre le head et la réponse, n'est il pas nécéssaire d'insérer
des 'rn' ?
Est ce que je dois envoyer en deux paquet différents : dabort le head
et ensuite la réponse (avec deux send donc) ou est ce que je dois tout
concaténer dans un même paquet ? (et dans ce cas, comment dois-je
séparer les données du head ?)


La réponse (sans jeu de mot) est dans la RFC:


Response = Status-Line ; Section 6.1
*(( general-header ; Section 4.5
| response-header ; Section 6.2
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 7.2

En bref : la réponse doit être composée
* du Status-Line (ici : "HTTP/1.1 200 OK"),
* suivi d'un nombre indéfini de headers séparés par de CRLF,
* suivis d'un CRLF
* suivis du corps s'il y en a un.

Donc théoriquement:

head = "rn".join((
"HTTP/1.1 200 OK",
"Server: myPythonServer",
"Cache-Control: no-store, no-cache, must-revalidate," +
"post-check=0, pre-check=0",
"Pragma: no-cache",
"Content-Length: %s" % len(response),
"Content-Type: application/vnd.syncml+wbxml",
))

message = "%srn%s" % (head, response)

client.send(message)

NB : sans garantie du gouvernement. Pour plus de précision, se référer
à: http://www.faqs.org/rfcs/rfc2616.html


Merci à tous pour votre aide.

Fabien




Avatar
n
j'écrivais mon message en même temps que toi, alors je le post quand
même.
J'ai effectivement trouvé ma réponse dans la RCF pour se qui est des
'rn', mais ça ne résoud pas mon problème :

apparement, faut une ligne vide entre le header et les data (donc un
'rn').
J'ai essayé, mais ça change pas grand chose, le mobile répond pas.
Quand je sniff avec wireshark, tout est dans la section data (header +
data) et il n'y a pas de section "Hyper Text Transfer Protocol" alors
que quand je sniff entre le mobile et le site de synchronisation, il y
a une section "Hyper Text Transfer Protocol" qui contient le header et
une section data qui contient les données. Pourtant, si on prend le
contenu des trames (header + data) c'est pour ainsi dire le même, je
ne comprend pas bien...
La seule raison qui pourrais expliquer, c'est que lors de la
synchronisation avec le site, le port utilisé par le serveur est le
port 80 alors que moi j'utilise le port 1234 (le port 80 est déjà
utilisé sur ma machine). Mais est ce pour cette raison qu'il n'y a pas
de découpage entre mon serveur et le mobile ???

Fabien
Avatar
Bruno Desthuilliers
j'écrivais mon message en même temps que toi, alors je le post quand
même.
J'ai effectivement trouvé ma réponse dans la RCF pour se qui est des
'rn', mais ça ne résoud pas mon problème :

apparement, faut une ligne vide entre le header et les data (donc un
'rn').


Après vérif, il faut *deux* sauts de lignes: un après le dernier header,
et un pour la ligne vide.

J'ai essayé, mais ça change pas grand chose, le mobile répond pas.
Quand je sniff avec wireshark, tout est dans la section data (header +
data) et il n'y a pas de section "Hyper Text Transfer Protocol" alors
que quand je sniff entre le mobile et le site de synchronisation, il y
a une section "Hyper Text Transfer Protocol" qui contient le header et
une section data qui contient les données. Pourtant, si on prend le
contenu des trames (header + data) c'est pour ainsi dire le même, je
ne comprend pas bien...
La seule raison qui pourrais expliquer, c'est que lors de la
synchronisation avec le site, le port utilisé par le serveur est le
port 80 alors que moi j'utilise le port 1234 (le port 80 est déjà
utilisé sur ma machine).


Ca ne devrait pas changer grand chose a priori. Du point de vue de HTTP,
ce n'est qu'une valeur par défaut, et apparament pareil pour SyncML/HTTP

Mais bon, là ça devient franchement HS ici. Je ne sais pas quel groupe
serait plus adapté, par contre.

Avatar
n
Après vérif, il faut *deux* sauts de lignes: un après le dernier he ader,
et un pour la ligne vide.


c'est exacte, après avoir apporté cette modif, wireshark détècte bi en
mon entête comme une entête http, tout est correcte.
Le téléphone ne répond toujours pas, (il envoi les flag FIN et ACK
maintenant) la connection est fermée, mais du coup, ce n'est plus le
header qui est en tort, ce doit être les data.

Déjà qu'avant ça ne rentrait pas trop dans le topic, mais du coup
maintenant ça en sort carrément. Étant donné que je ne trouve pas de
topic syncml avec suffisament d'activité, je vais arrêter ici, et
chercher de mon côté.

Merci à tous

Fabien

Avatar
Thomas Harding
Le 26-07-2007, a écrit:
Déjà qu'avant ça ne rentrait pas trop dans le topic, mais du coup
maintenant ça en sort carrément. Étant donné que je ne trouve pas de
topic syncml avec suffisament d'activité, je vais arrêter ici, et
chercher de mon côté.


Ca doit rentrer dans le sujet de fr.comp.reseaux.ip,
puisque ça sort de celui de fr.comp.infosystemes.www.serveurs

Mais à ta place, pour un truc aussi pointu, j'irais voir dans le gros 8.
--
Thomas Harding

Avatar
Paul Gaborit
À (at) Thu, 26 Jul 2007 04:06:03 -0700,
"" écrivait (wrote):
J'ai effectivement trouvé ma réponse dans la RCF pour se qui est des
'rn', mais ça ne résoud pas mon problème :


Ce n'est pas rn mais bien le caractère de code ASCII 015 (en octal)
suivi du caractère de code ASCII 012 (toujours en octal).

Le n change de valeur selon la plateforme (012 sur Unix, 015 sur Mac
et 015 suivi de 012 sur Windows). Il se trouve que sur Unix, ça
marche. Mais ce n'est pas propre.

apparement, faut une ligne vide entre le header et les data (donc un
'rn').


Il faut effectivement une ligne vide entre les en-têtes et le
contenu. Ce qui fait dont deux fins de ligne (1512) successifs :
la première pour terminer la dernière ligne des en-têtes et la seconde
pour la ligne vide.

On peut envoyer tout d'un seul coup (après contaténation) ou par
morceaux successifs. Tant qu'on ne ferme pas la connexion, il n'y a
pas de problème.

N'existe-t-il pas des bouts de code Python tout prêt pour gérer tout
cela *proprement* sans se prendre la tête ? ;-)

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>

Avatar
Paul Gaborit
À (at) Thu, 26 Jul 2007 17:26:55 +0200,
Bruno Desthuilliers écrivait (wrote):
(snip)
N'existe-t-il pas des bouts de code Python tout prêt pour gérer tout
cela *proprement* sans se prendre la tête ? ;-)

Il ne manque pas de bibliothèques et frameworks Python permettant de

générer simplement et proprement des réponse HTTP correctement
formatées.


Oui ! Tu le sais et moi aussi... Mais qu'en est-il du PO ?

A priori, à peu près tous les framework web Python (qui
sont plus nombreux que les mots réservés du langage...)


;-)

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>


Avatar
n
Le n change de valeur selon la plateforme (012 sur Unix, 015 sur Mac
et 015 suivi de 012 sur Windows). Il se trouve que sur Unix, ça
marche. Mais ce n'est pas propre.


merci pour tes conseil, je remplace donc les rn par des 1512.
J'y gagne un peut en portabilité comme ça.
Pour gérer ça proprement, j'ai pas trouvé sur le coup, mais bon
maitenant que ça marche, ça m'a permis de mieux comprendre le
fonctionnement de tous ça :)

En tout cas, merci à tous, j'ai réussi ce soir ma première synchro
avec le téléphonne mobile, preuve que mon serveur de synchronisation
fonctionne !

Fabien

Avatar
Paul Gaborit
À (at) Mon, 30 Jul 2007 18:36:01 +0200,
jean-michel bain-cornu écrivait (wrote):
À (at) Thu, 26 Jul 2007 00:35:45 +0200,
Amaury Forgeot d'Arc écrivait (wrote):
Apparemment, ftp et smtp fonctionnent aussi à coups de CRLF.
Ce sont sans doute des Windowsiens qui ont inventé ces protocoles...


Pas du tout.

Mais quand il a fallut choisir une fin de ligne "réseau", ceux qui
l'on fait se sont dit (avec raison) qu'en mettant les deux caractères,
la fin de ligne serait reconnu par tout le monde (avec parfois un
caractère parasite avant ou après mais c'est moins grave que de ne pas
voir de fin de ligne du tout).



J'ai une autre explication : les machines à écrire qui ont servi assez
tard de console sur les mainframes et les minis avaient besoin des 2
caractères : retour à la ligne, puis saut de ligne.
Quand DEC a 'inventé' le mini moderne avec un écran comme console (le
PDP7 je crois), ils ont fait l'économie du lf, mais n'ont pas été
suivis par tout le monde, d'où les deux écoles.
Voilà qui ne nous rajeunit pas...


C'est effectivement l'explication sur la diversité des choix du codage
des fins de lignes sur les ordinateurs ou systèmes en général (c'est
aussi lié aux imprimantes plus qu'aux machines à écrire qui faisaient
déjà les deux opérations à la fois mais proposaient bien en option de
ne faire que l'une des deux).

Mais, pour le choix du codage des fins de lignes dans les protocoles
réseaux (le choix remonte quand même à bien moins loin... disons une
trentaine d'années grand maximum pour les plus vieux protocoles et
pour HTML tout juste 17 ans), je pense que mon explication tient
aussi...

Mais c'est vrai que tout ça ne nous rajeunit pas... ;-)

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>



1 2