11
votes

JSR-356: Comment abandonner une connexion Websocket pendant la poignée de main?

Je dois pouvoir abandonner une connexion Websocket pendant la poignée de main au cas où la demande HTTP ne répond pas à certains critères. D'après ce que je comprends, le bon endroit à faire est à l'intérieur du ServerendPointConfig.configurator.modifyhandhandhake () Méthode de mon propre Configurateur Mise en œuvre . Je ne peux tout simplement pas comprendre quoi faire pour abandonner la connexion. Il y a un Paramètre Handshakeresponse qui permet d'ajouter des en-têtes à la réponse, mais je ne pouvais pas Trouvez tout en-tête qui fait le travail.

Alors, comment puis-je abandonner une connexion Websocket pendant la poignée de main? Est-ce que même possible?


0 commentaires

4 Réponses :


3
votes

Vous avez raison, utilisez Â'MODIFYHAKE () Â 'pour mettre à jour les en-têtes de réponse, il vous suffit de supprimer ou de définir la valeur de l'en-tête SEC-WebSocket-Accepter , vérifiez cela de La spécification

Le | Sec-Websocket-accepter | champ d'en-tête indique si Le serveur est prêt à accepter la connexion. Si présent, cela Le champ d'en-tête doit inclure un hachage de la nonce du client envoyé dans | Sec-Websocket-clé | avec un guide prédéfini. Toute autre valeur ne doit pas être interprété comme une acceptation de la connexion par le serveur. xxx

Ces champs sont vérifiés par le client WebSocket pour les pages scriptées. Si le | Sec-Websocket-accepter | la valeur ne correspond pas aux attentes valeur, si le champ d'en-tête est manquant ou si le code d'état HTTP est Pas 101, la connexion ne sera pas établie et des cadres de soins Websocket ne sera pas envoyé.

Votre code ressemblerait à ceci: xxx

Le navigateur interprétera ce serveur comme Server n'a pas accepté la connexion. Par exemple dans Chrome, je reçois le message

Erreur lors de la poignée de main de la bande Web


3 commentaires

Cela devrait fonctionner, mais juste pour des raisons de mise en œuvre plus propre, je vous suggère de mettre en œuvre un filtre de servlet et de vérifier la demande.


Bonjour @leo, j'ai déjà essayé cette approche avant que cela ne fonctionne pas (au moins sur Tomcat). Il me semble que le code serveur définit l'en-tête SEC-SEXCASE-Accepter après l'appel sur ModifyHandshake () . Lors de l'impression des en-têtes de réponse à l'intérieur ModifyHandshake () Comme ceci: LOGGER.INFO ("Réponse.Getheaders () =>" + Response.Getheaders ()); Nous obtenons cette : réponse.Getheaders () => {}


Eh bien, je l'ai testé avec Wildfly, qui utilise un contraint, je suppose que cela peut être un détail de mise en œuvre.



2
votes

Je connais - vieux fil mais je ne vois aucune amélioration à ce sujet. Donc, peut-être que quelqu'un peut discuter de ma solution à ce problème.

J'ai essayé la version Leos, exécutant sauvage 8.0, STRINTOW 1.0 P>

/** some verification foo code...**/

config.getUserProperties().put("isValid",true);


2 commentaires

Un problème avec ceci est que vous êtes alors un peu tard: la connexion WebSocket a été établie et vous devez la fermer à nouveau. Il devrait être possible de dire "non, désolé, accès refusé" déjà avec la poignée de main HTTP.


Mais si la réglage de la valeur "SEC-WebSocket-Accepter" la valeur de la chaîne vide ne fonctionne pas sur Tomcat. Que puis-je faire? Ce doit être sur Tomcat.



3
votes

Le moyen le plus simple consiste à configurer un filtre Web simple dans votre web.xml qui sera exécuté avant la poignée de main.

smth comme: xxx

et dans le Web. xml: xxx

et votre point de serveur doit être smth comme: xxx


2 commentaires

Malheureusement, cela ne fonctionne pas pour moi (sur Jetty 9.4)


Les filtres ne doivent réellement pas exécuter sur une mise à niveau HTTP: Stackoverflow.com/a/25996042/39334 "En pratique, vous devriez travailler avec L'attente que les mises à niveau se produisent avant le traitement du servlet (et cela inclut des filtres), car c'est la manière dont la spécification est écrite. Il existe des bugs ouverts contre la spécification sur la manière dont les interactions avec les filtres et ce que doivent être traités, mais ceux-ci sont actuellement sans réponse et de manière lâchée. prévu pour une future version de la spécification Javax.websocket. "



1
votes

Une autre technique:

Lorsque vous jetez une analyse RunTimeException à partir de ServerendpointConfig.configurator # ModifierHandshake , la connexion n'est pas établie.

Cela fonctionne à Tomcat 8. Vous avez eu l'idée d'un exemple de jetty Donc, je suppose que cela fonctionne également à la jetée.


1 commentaires

Oui, cela fonctionne à Jetty 9.4, mais il enregistre une lourde ligne de warn avec l'exception complète - pas du tout idéal. De plus, sur le client, il déclenche Onerror puis sur la cloison 1006 fermée_abnormalement - au moins dans Firefox. Cependant, ce code de fermeture peut également venir pour plusieurs autres scénarios. Il devrait vraiment y avoir un code de fermeture «accès refusé» explicite, qui pourrait être déclenché à partir de la poignée de main HTTP.