Erreur 200 en utilisant des websocket

Avec Nginx => Apache => Gunicorn => Websocket

a marqué ce sujet comme résolu.

Bonjour,

J’ai un problème avec l’utilisation des websockets. Il me dit que tout va bien alors qu’il ne devrait pas. :-° . Plus exactement, j’ai des erreurs 200 (et parfois 400+504). En particulier, quand j’essaye de me connecter sur l’endpoint je reçois systématiquement un code 200.

Mon architecture est étrange mais je suis obligé de la suivre car il s’agit d’un clone de la configuration que je ne peux pas changer.

J’ai un Nginx en frontal qui s’occupe du SSL et d’upgrader la connexion des websocket. Puis un apache qui fait un proxy vers gunicorn qui lance mon application flask.

J’ai certainement dû me tromper dans une des étapes, mais je ne comprend pas laquelle. :/ N’hésitez pas non plus si vous avez des remarques sur la configuration et que ça n’a pas de rapport avec le sujet. Il y a des bizarreries qui ont dû apparaitre à force de faire des tests pour comprendre le fonctionnement de nginx et apache. En particulier, parmi les points qui sont flous pour moi :

  • Apache est-il ici un serveur mandataire direct ou indirect, sachant que nginx est là ?
  • faut-il gérer https du côté de apache ? faire passer le port avec ?
  • vaut-il mieux que l’application se considère sur 127.0.0.1 ou domain.tld ?
  • est-ce possible de logguer les requêtes websocket ?

Voici ma configuration :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
http {
    include       mime.types;

    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    #keepalive_timeout  300;

    #gzip  on;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    server {
        listen 80;
        listen   [::]:80;
        server_name maisel-telecom-paristech.fr;#maisel.janniaux.me;
        error_log /var/log/maisel/nginx_errors;
        rewrite ^ https://$server_name$request_uri? permanent;
    }

    server {
        listen 443 ssl;
        listen   [::]:443 ssl;
        server_name domain.tld;

        ssl_certificate /etc/letsencrypt/live/domaine.tld/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers 'DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-CAMELLIA256-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-CAMELLIA128-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256';

        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        ssl_dhparam /etc/nginx/dhparam.pem;
        add_header Strict-Transport-Security "max-age=31536000;";



        location / {
            proxy_set_header X-Real-IP  $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $host:$server_port;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header SCRIPT_NAME "/questionnaire";
            include uwsgi_params;
            #proxy_set_header Host $host;
            proxy_pass http://127.0.0.1:8880;
            proxy_redirect default;
        }
        location /socket.io/ {
                proxy_pass http://127.0.0.1:8880/socket.io/;
                include uwsgi_params;
                proxy_http_version 1.1;
                proxy_redirect off;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                proxy_set_header SCRIPT_NAME '';
                proxy_buffering off;
                proxy_read_timeout 86400;

        }
    }
    include sites-enabled/*;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<VirtualHost *:8880>
        ServerName domaine.tld
        DocumentRoot "/srv/http/domain/public/"

        ProxyRequests on
        ProxyPass /socket.io/ "unix:/var/run/maisel/gunicorn-domain.socket|http://127.0.0.1/socket.io/"
        ProxyPass /questionnaire/ "unix:/var/run/maisel/gunicorn-domain.socket|http://127.0.0.1/questionnaire/"
        ProxyPassReverse /questionnaire/ "http://127.0.0.1/"
        ProxyPassReverse /socket.io/ "http://127.0.0.1/"

        ProxyPreserveHost Off

        Alias /admin "/srv/http/domain/domain-questionnaire/dist/"
        Alias /static "/srv/http/domain/domain-questionnaire/dist/static/"
        Alias /css "/srv/http/domain/domain-questionnaire/dist/css/"

        Alias /uploads/ "/srv/http/domain/domain-questionnaire/api/uploads/"
        <Location /uploads>
                Deny from all
                AuthUserFile ....
                AuthName authorization
                AuthType Basic
                Satisfy Any
                require valid-user
                Header Set Cache-Control "max-age=0, no-store"
        </Location>

        <Location /admin>
                Deny from all
                AuthUserFile ....
                AuthName authorization
                AuthType Basic
                Satisfy Any
                require valid-user
                Header Set Cache-Control "max-age=0, no-store"
        </Location>

        redirectMatch "^/$" "/questionnaire/"

        #<Location /questionnaire>
                #ProxyPreserveHost On
                RequestHeader set X-FORWARDED-PROTOCOL ssl
                RequestHeader set X-FORWARDED-SSL on
        #</Location>
</VirtualHost>

Merci à vous !

+0 -0

https://fr.wikipedia.org/wiki/Liste_des_codes_HTTP

  • 200 : OK -> Requête traitée avec succès.
  • 504 : Gateway Time-out -> Temps d’attente d’une réponse d’un serveur à un serveur intermédiaire écoulé.
  • 400 : Bad Request -> La syntaxe de la requête est erronée

Et de manière générale :

+2 -0

Salut :)
Le code HTTP 200 signifie que tout va bien ;) "HTTP 200 : OK"

Dryusdan

Il ne doit pas y avoir de code de retour 200, mais 101 (de souvenir, qui indique qu’on a bien fait l’upgrade) lorsqu’on utilise des websockets ;)

EDIT : globalement je pense que le 400 doit venir de problèmes avec la connexion du websocket (mauvaise upgrade ?) et le 504 du nginx => apache => gunicorn avec une connexion qui ne renvoit rien ? La première requête qui foire en 400 attend pendant 1 min.

+0 -0

Il ne doit pas y avoir de code de retour 200, mais 101 (de souvenir, qui indique qu’on a bien fait l’upgrade) lorsqu’on utilise des websockets

Alors ça veut soit dire que t’utilise pas les websockets, soit l’erreur 101 c’est en HTTP/2 (me souvient pas en avoir vu en HTTP1/1 )

:)

Il ne doit pas y avoir de code de retour 200, mais 101 (de souvenir, qui indique qu’on a bien fait l’upgrade) lorsqu’on utilise des websockets

Alors ça veut soit dire que t’utilise pas les websockets, soit l’erreur 101 c’est en HTTP/2 (me souvient pas en avoir vu en HTTP1/1 )

:)

Dryusdan

101 n’est pas une erreur non plus. C’est un code d’information. Il est arrivé avec http 1.1, http 1.0 n’ayant pas de 1xx.

+1 -0

J’utilise des websockets, mais ceux-ci ne passent pas l’upgrade du coup, et j’obtiens une erreur "Error during WebSocket handshake: Unexpected response code: 200".

EDIT: est-ce qu’il ne manquerait pas l’information type proxy_http_version du côté de apache ?

EDIT2: en bypassant apache, j’ai bien un 101 switching protocol, donc il s’agit bien de la configuration d’apache.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte