WebSocket
WebSocket es una tecnología que proporciona un canal de comunicación bidireccional y full-duplex sobre un único socket TCP. Está diseñada para ser implementada en navegadores y servidores web, pero puede utilizarse por cualquier aplicación cliente/servidor. La API de WebSocket está siendo normalizada por el W3C, mientras que el protocolo WebSocket ya fue normalizado por la IETF como el RFC 6455. Debido a que las conexiones TCP comunes sobre puertos diferentes al 80 son habitualmente bloqueadas por los administradores de redes, el uso de esta tecnología proporcionaría una solución a este tipo de limitaciones proveyendo una funcionalidad similar a la apertura de varias conexiones en distintos puertos, pero multiplexando diferentes servicios WebSocket sobre un único puerto TCP (a costa de una pequeña sobrecarga del protocolo).
En el lado del cliente, WebSocket está ya implementado en Mozilla Firefox 8, Google Chrome 4 y Safari 5, así como la versión móvil de Safari en el iOS 4.2,[1] y en Internet Explorer 10.[2]
Negociación del protocolo WebSocket
Para establecer una conexión WebSocket, el cliente envía una petición de negociación WebSocket, y el servidor envía una respuesta de negociación WebSocket, como se puede ver en el siguiente ejemplo:
Petición del navegador al servidor:
GET /demo HTTP/1.1
Host: example.com
Connection: Upgrade
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
Sec-WebSocket-Protocol: sample
Upgrade: WebSocket
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5
Origin: http://example.com
^n:ds[4U
Respuesta del servidor:
HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: http://example.com
Sec-WebSocket-Location: ws://example.com/demo
Sec-WebSocket-Protocol: sample
8jKS'y:G*Co,Wxa-
Los 8 bytes con valores numéricos que acompañan a los campos Sec-WebSocket-Key1 y Sec-WebSocket-Key2 son tokens aleatorios que el servidor utilizará para construir un token de 16 bytes al final de la negociación para confirmar que ha leído correctamente la petición de negociación del cliente.
La negociación o handshake se construye concatenando los números que acompañan al primer campo, y dividiéndolo por el número de espacios en blanco en el propio campo. Esto mismo se repite para el segundo campo. Los dos números resultantes se concatenan entre sí y con los 8 bytes que van después de los campos. El resultado final es una suma MD5 de la cadena concatenada.[3]
Esta negociación puede parecerse a la negociación HTTP, pero no es así. Permite al servidor interpretar parte de la petición de negociación como HTTP y entonces cambiar a WebSocket.
Una vez establecida, las tramas WebSocket de datos pueden empezar a enviarse en ambos sentidos entre el cliente y el servidor en modo full-duplex. Las tramas de texto pueden ser enviadas en modo full-duplex también, en ambas direcciones al mismo tiempo. La información se segmenta en tramas de únicamente 2 bytes. Cada trama empieza con un byte 0x00, termina con un byte 0xFF, y contiene datos UTF-8 entre ellos. Tramas de datos binarios no están soportadas todavía en el API. Las tramas WebSocket de texto utilizan un terminador, mientras que las tramas binarias utilizan un prefijo de longitud.
Paso a través de servidores proxy
La implementación de cliente del protocolo WebSocket intenta detectar si el agente de usuario está configurado para utilizar un proxy a la hora de conectar a un host y puerto remoto, y si es así, utiliza el método HTTP CONNECT para establecer un túnel persistente.
Aunque el protocolo WebSocket es indiferente a la conexión sobre servidores proxy o cortafuegos, implementa una negociación compatible con HTTP para que los servidores HTTP puedan compartir sus puertos HTTP y HTTPS por defecto (80 y 443) con una pasarela o servidor WebSocket. El protocolo WebSocket define un prefijo ws:// y wss:// para indicar una conexión WebSocket y Websocket Secure, respectivamente. Ambos esquemas utilizan un mecanismo HTTP upgrade para actualizar al protocolo WebSocket. Algunos servidores proxy no interfieren en la conexión y funcionan perfectamente con WebSocket; otros afectan al correcto funcionamiento de WebSocket, provocando que la conexión falle. En algunos casos puede que se requiera configuración adicional en el servidor proxy, y algunos servidores proxy puede que necesiten actualizarse para soportar WebSocket.
Si el tráfico sin cifrar de WebSocket pasa por un proxy explícito o transparente en su camino al servidor WebSocket, entonces, independientemente de que el proxy se comporte como debiera, esta conexión, a día de hoy, muy probablemente fallará (a medida que WebSocket se extienda, los servidores proxy lo tendrán en cuenta). De ahí que las conexiones sin cifrar de WebSocket se deberían utilizar sólo en las topologías más sencillas. [4]
Si se utiliza una conexión WebSocket cifrada, se necesitará utilizar una capa TLS en la conexión Websocket Secure para asegurar que un comando HTTP CONNECT se manda cuando el navegador está configurado para utilizar un servidor proxy explícitamente. Esto establece un túnel, que proporciona una comunicación TCP de bajo nivel y punto a punto a través del proxy HTTP, entre el cliente WebSocket Secure y el servidor Websocket. En el caso de servidores proxy trasparentes, el navegador no será consciente del uso de un servidor proxy, así que no mandará una petición HTTP CONNECT. En cualquier caso, como el tráfico está cifrado, los servidores proxy trasparentes intermedios podrían simplemente permitir el tráfico cifrado a través de ellos, de manera que la conexión WebSocket funcionará sin problemas si se utiliza WebSocket Secure. Utilizar cifrado no es gratis en lo que a consumo de recursos se refiere, pero nos asegura la tasa de éxito más alta.
Desafortunadamente, una actualización reciente al borrador (versión 76) rompió completamente la compatibilidad con proxies inversos y pasarelas, ya que los 8 bytes de datos que el cliente debe enviar después de las cabeceras no se anuncian en una cabecera Content-Length, por lo que los intermediarios no reenvían los datos hasta que se completa la negociación. Y como la negociación necesita de esos 8 bytes para completarse, ésta nunca se completa y entra en un punto muerto. En el estado actual de las cosas, no es recomendable modificar estos componentes intermediarios para que soporten este comportamiento HTTP no estándar, porque hacerlo llevería a estos componentes a ser vulnerables a ataques HTTP smuggling, ya que un atacante simplemente tendría que hacer un intento de actualización al protocolo WebSocket en una petición para ser capaz de mandar más datos de los que el servidor HTTP de destino pudiera parsear, saltándose así algunos filtros de seguridad obligatorios. No se sabe si esta problemática se solucionará en un nuevo borrador o no.[5]
Esquema de URL
La especificación del protocolo WebSocket define dos nuevos esquemas de URI, ws: y wss:,[6] para conexiones no cifradas y cifradas respectivamente. Además del nombre del esquema, el resto de componentes del URI se definen con la sintaxis genérica de URI.[7]
Navegadores que soportan websockets
Se ha implementado una versión segura del protocolo de WebSocket en Firefox 6,[8] Safari 6, Google Chrome 14,[9] Opera 12.10 e Internet Explorer 10.[10] El reporte [11] muestra la conformidad de estos navegadores con los aspectos específicos del protocolo.
Una versión más antigua pero más insegura fue implementada en Opera 11 y Safari 5, además de en la versión móvil de Safari en iOS 4.2.[12] BlackBerry Browser en OS7 implementa también WebSockets.[13] Por sus vulnerabilidades, ha sido deshabilitado en Firefox 4 y 5,[14] y Opera 11.[15]
Existe el comando --enable-websocket-over-spdy
para Google Chrome que habilita una versión previa experimental de WebSocket sobre SPDY.[16]
Protocolo | Fecha versión preliminar | Internet Explorer | Firefox[17] (PC) | Firefox (Android) | Chrome (PC, Mobile) | Safari (Mac, iOS) | Opera (PC, Móvil) | Android Browser |
---|---|---|---|---|---|---|---|---|
hixie-75 | 4 de febrero de 2010 | 4 | 5.0.0 | |||||
hixie-76 hybi-00 |
6 de mayo de 2010 23 de mayo de 2010 |
4.0 (disabled) | 6 | 5.0.1 | 11.00 (disabled) | |||
7 hybi-07 | 22 de abril de 2011 | 6[18] | ||||||
8 hybi-10 | 11 de julio de 2011 | 7[19] | 7 | 14[20] | ||||
13 RFC 6645 | December, 2011 | 10[21] | 11 | 11 | 16[22] | 6 | 12.10[23] | 4.4 |
Véase también
Referencias
- Marsal, Katie (23 de noviembre de 2010). «Apple adds accelerometer, WebSockets support to Safari in iOS 4.2» (html). Apple community, AppleInsider (en inglés). Archivado desde el original el 25 de noviembre de 2010. Consultado el 17 de junio de 2019. «Mobile Safari in iOS 4.2, released on Monday, also supports WebSockets, a W3C HTML5 API that will help chat and real-time applications that rely on a connection to a server using TCP sockets. »
- «WebSockets (Windows)». Microsoft. 28 de septiembre de 2012. Consultado el 3 de octubre de 2014.
- http://www.whatwg.org/specs/web-socket-protocol/
- How Web Sockets Interact With Proxy Servers
- WebSocket -76 es incompatible con proxies HTTP inversos
- IANA Uniform Resource Identifer (URI) Schemes
- http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
- Dirkjan Ochtman (27 de mayo de 2011). «WebSocket enabled in Firefox 6». Mozilla.org. Archivado desde el original el 26 de mayo de 2012. Consultado el 30 de junio de 2011.
- «Chromium Web Platform Status». Consultado el 3 de agosto de 2011.
- «WebSockets (Windows)». Microsoft. 28 de septiembre de 2012. Consultado el 7 de noviembre de 2012.
- «WebSockets Protocol Test Report». Tavendo.de. 27 de octubre de 2011. Archivado desde el original el 19 de abril de 2012. Consultado el 10 de diciembre de 2011.
- Katie Marsal (23 de noviembre de 2010). «Apple adds accelerometer, WebSockets support to Safari in iOS 4.2». AppleInsider.com. Consultado el 9 de mayo de 2011.
- «Web Sockets API». BlackBerry. Archivado desde el original el 10 de junio de 2011. Consultado el 8 de julio de 2011.
- Chris Heilmann (8 de diciembre de 2010). «WebSocket disabled in Firefox 4». Hacks.Mozilla.org. Consultado el 9 de mayo de 2011.
- Aleksander Aas (10 de diciembre de 2010). «Regarding WebSocket». My Opera Blog. Archivado desde el original el 15 de diciembre de 2010. Consultado el 9 de mayo de 2011.
- Peter Beverloo. «List of Chromium Command Line Switches». peter.sh. Consultado el 10 de diciembre de 2011.
- «WebSockets (support in Firefox)». developer.mozilla.org. Mozilla Foundation. 30 de septiembre de 2011. Archivado desde el original el 26 de mayo de 2012. Consultado el 10 de diciembre de 2011.
- «Bug 640003 - WebSockets - upgrade to ietf-06». Mozilla Foundation. 8 de marzo de 2011. Consultado el 10 de diciembre de 2011.
- «Bug 640003 - WebSockets - upgrade to ietf-07(comment 91)». Mozilla Foundation. 22 de julio de 2011.
- «Chromium bug 64470». code.google.com. Google. 25 de noviembre de 2010. Consultado el 10 de diciembre de 2011.
- «WebSockets in Windows Consumer Preview». IE Engineering Team. Microsoft. 19 de marzo de 2012. Consultado el 23 de julio de 2012.
- «WebKit Changeset 97247: WebSocket: Update WebSocket protocol to hybi-17». trac.webkit.org. Consultado el 10 de diciembre de 2011.
- «A hot Opera 12.50 summer-time snapshot». Opera Developer News. 3 de agosto de 2012. Archivado desde el original el 5 de agosto de 2012. Consultado el 3 de agosto de 2012.
Enlaces externos
- Grupo de trabajo del IETF sobre Hipertexto-Bidireccional (HyBi)
- The WebSocket protocol - Draft de Internet del IETF
- The WebSocket protocol (Network Working Group) - Antiguo protocolo
- The WebSocket API Archivado el 7 de junio de 2015 en Wayback Machine. - Draft del W3C con la especificación de la API
- WebSockets.org - sitio web dedicado a WebSockets
- WebSocketsTest.com - un sitio web para probar el soporte y funcionamiento de WebSockets en tu navegador.
- HTML5 Server-Push Technologies, Part 2 Archivado el 27 de septiembre de 2011 en Wayback Machine. - explicación de WebSockets