Comments on: Comment fonctionne HTTP ? http://sametmax.com/comment-fonctionne-http/ Du code, du cul Mon, 28 Oct 2019 11:54:55 +0000 hourly 1 https://wordpress.org/?v=4.9.7 By: Sam http://sametmax.com/comment-fonctionne-http/#comment-62692 Fri, 20 Jun 2014 12:33:53 +0000 http://sametmax.com/?p=10596#comment-62692 Ok, donc c’est bien la structure d’une API qui la rend bloquante, et non l’implémentation socket qui permet bien de gérer cela.

]]>
By: foX http://sametmax.com/comment-fonctionne-http/#comment-62672 Fri, 20 Jun 2014 12:09:14 +0000 http://sametmax.com/?p=10596#comment-62672 @Alex : en effet, je ne savais pas qu’on pouvais avoir le comportement à la http 1.0 en fermant également la connexion pour indiquer la fin de réponse. Merci pour l’info.

]]>
By: herison http://sametmax.com/comment-fonctionne-http/#comment-62671 Fri, 20 Jun 2014 12:06:35 +0000 http://sametmax.com/?p=10596#comment-62671 @sam

Bonne questions, voici une épave ébauche de serveur sans thread qui peux prendre plusieurs clients en gardant les connexion ouvertent.

class Server:
    def __init__(self):
        self.sock = socket.socket()
        self.sock.setblocking(False) # rend la socket non-blocante.
        self.sock.bind(("127.0.0.1", 7777))
        self.sock.listen(5)
        self.clients = []

    def run(self):
        while True:
            try:
                sock_client, addr_info = self.sock.accept()
            except BlockingIOError:
                pass # Personne veux se connecter, pas grave, je m'occupe des clients.
            else:
                sock_client.setblocking(False)
                self.clients.append(sock_client)

            for client in self.clients:
                try:
                    print(client.recv(50))
                except BlockingIOError:
                    pass # Le clients n'envoie rien pas grave, je passe à l'autre.
                else:
                    try:
                        client.send(b"Coucou")
                    except BrokenPipeError: # Le client à fermé la connection
                        self.clients.remove(client) # on le gicle de la liste

            sleep(0.25) # pour pas crammer le cpu

    def __del__(self):
        self.sock.close()

class Client:
    def __init__(self, msg):
        self.sock = socket.socket()
        self.sock.connect(("127.0.0.1", 7777))
        for i in range(10):
            self.sock.send(bytes('{} ({})'.format(msg, i), 'utf-8'))
            print(self.sock.recv(7))
        self.sock.close()

# Bon là les thread c'est juste pour simuler 
# les gonz qui se connectent. Tu peut trés bien
# mettre les client ds un autre shell sans les thread
from threading import Timer
Timer(1, Client, args=("salut",)).start()
Timer(1, Client, args=("le",)).start()
Timer(1, Client, args=("monde",)).start()

server = Server()
server.run()

]]>
By: foX http://sametmax.com/comment-fonctionne-http/#comment-62670 Fri, 20 Jun 2014 12:03:10 +0000 http://sametmax.com/?p=10596#comment-62670 @Sam : c’est la connexion tcp qui reste ouverte. Un process peut conserver la connexion TCP ouverte sans bloquer le fil d’exécution derrière. C’est l’appel système select qui permet à une application mono thread de gérer plusieurs connexions ouvertes de manière non bloquante.

]]>
By: Alex http://sametmax.com/comment-fonctionne-http/#comment-60494 Wed, 18 Jun 2014 23:14:12 +0000 http://sametmax.com/?p=10596#comment-60494 @foX: je vois pas pourquoi tu devrais chipoter, HTTP 1.1 est un protocole stateless les requêtes contiennent l’information nécessaire à la construction de la réponse. N’oublions pas que la RFC indique qu’il n’est pas impossible d’avoir une implémentation par dessus UDP ou tout autre protocole.

De plus, tu parles du champ Content-length, celui-ci n’est pas obligatoire dans le cas d’un serveur qui fermeraient les connections (Section 4.4 ). C’est également sans parler de la mécanique de messages Chunked. Bien sûr que pour des raisons de performance (et c’est pas forcement le cas article), on ne ferme pas le socket à la fin de la réponse, rien ne l’en empêche de le faire, c’est purement un choix technique et/ou une configuration sur le serveur.

Il est également intéressant de montrer que le protocole avait été conçu comme un protocole synchrone (requête puis réponse) mais qu’au final la plupart des implémentations ne le sont pas. Ce qui permet de tricher en envoyant la réponse avant même d’avoir reçu la requête Article récent décrivant la découverte.

]]>
By: Sam http://sametmax.com/comment-fonctionne-http/#comment-60232 Wed, 18 Jun 2014 17:20:23 +0000 http://sametmax.com/?p=10596#comment-60232 @foX: si la connexion reste ouverte, comment ça se fait que ça bloque pas les workers WSGI synchrones non threadés type gunicorn ?

@policier moustachu: on l’a sur le blog.

]]>
By: policier moustachu http://sametmax.com/comment-fonctionne-http/#comment-60042 Wed, 18 Jun 2014 14:03:40 +0000 http://sametmax.com/?p=10596#comment-60042 J’adore la techno kitsh. Autre titre phare : le theme de Mortal Kombat

]]>
By: policier moustachu http://sametmax.com/comment-fonctionne-http/#comment-60020 Wed, 18 Jun 2014 13:44:11 +0000 http://sametmax.com/?p=10596#comment-60020 the schumacher song !!! Depuis le temps que je recherchais ce titre. Merci les gars.

]]>
By: foX http://sametmax.com/comment-fonctionne-http/#comment-59966 Wed, 18 Jun 2014 12:34:37 +0000 http://sametmax.com/?p=10596#comment-59966

# On ferme la connexion : le protocole HTTP est stateless,
# c’est à dire qu’il n’y a pas de maintien d’un état
# côté client ou serveur et chaque requête est indépendante
# de toutes les autres.

Presque ;-). Je chipotte, mais justement en HTTP 1.1 c’est plus sioux. Au niveau HTTP en effet, les requêtes sont indépendantes. La session est gérée (ou pas !) au niveau de l’application par divers moyens, et les fameux cookies sont un des moyens permettant de garder l’état pour savoir qui est qui et recoller les bouts.
Mais au niveau TCP, ce n’est heureusement pas stateless. Donc après la réponse, le serveur ne fait pas un close() sur la socket TCP, et le client non plus. Cela permet d’envoyer plusieurs requetes HTTP dans la même connexion TCP.

Pourquoi ça ? Et bien pour des raisons de perf. L’ouverture d’une connexion TCP a un coût (syn, ack, synack) et il est plus rapide de garder les tuyaux ouverts entre un client et le serveur web, une page page web étant souvent constituée de dizaines de ressources demandant chacune un appel HTTP. De plus, cela limite le nombre de connexion TCP en //, ce qui a un coût au niveau de tous les équipements réseaux sur le chemin de votre requête (firewal, reverse proxy, …).

C’est pour cela que le header sur la taille de la réponse est obligatoire en HTTP 1.1, car le client doit savoir quand ça s’arrette. En HTTP 1.0, c’est facile, il lit jusqu’à qu’à recevoir un close() de la part du serveur. Mais en HTTP 1.1 la socket reste ouverte, donc le client doit lire jusqu’à x octets, ensuite la connexion reste ouverte pour envoyer une autre requête.

On peut même multiplexer plusieurs requêtes dans une même connexion TCP, c’est à dire que le client fait plusieurs demandes à la suite sans attendre la réponse de chacune, puis reçoit plusieurs réponses, au lieu de simplement sérialiser. C’est plus rock’n roll et pas toujours pris en charge (souvent désactivé dans les browser). Cela s’appelle le pipelining http.

]]>
By: Romain http://sametmax.com/comment-fonctionne-http/#comment-59953 Wed, 18 Jun 2014 11:45:50 +0000 http://sametmax.com/?p=10596#comment-59953 Merci pour l’exemple d’utilisation d’asyncio ;)

]]>