Índice de contenidos
- 1. Introducción
- 2. Entorno
- 3. Creación del proyecto
- 4. Importación de las dependencias necesarias
- 5. Creación e importación del certificado
- 6. Creación y configuración del HTTP/2 Server
- 7. Creación del Handler para las Requests entrantes
- 8. Configuración del puerto de escucha
- 9. Arranque del servidor con la extension ALPN usando la JDK
- 10. Probando el servidor usando Google Chrome
- 11. Conclusiones
- 12. Contacto y GitHub repository
- 13. Referencias
1. Introducción
En este tutorial aprenderás como poder crear un servidor HTTP/2 desde cero utilizando el framework Vert.x en pocos sencillos pasos, así como la solución de los problemas más comunes que tendremos que afrontar si queremos arrancar aplicaciones HTTP/2 en Java.
2. Entorno
El tutorial está escrito usando el siguiente entorno:
- Hardware: Portátil MacBook Pro Retina 15′ (2.3 Ghz Intel Core I7, 16GB DDR3).
- Sistema Operativo: Mac OS Sierra 10.12
- Entorno de desarrollo: Eclipse Neon
- Apache Maven 3.3.3
- Java JDK 1.8.0_u45
- Google Chrome 61.0.3163.100
3. Creación del proyecto
Creamos un proyecto Maven, a través del arquetipo “quick-start-maven”, y eliminamos todo aquello que le sobra (como es el fichero App.java y AppTest.java).
En este tutorial, únicamente nos vamos a centrar en cómo montar un servidor HTTP2 con Vert.x.
4. Importación de las dependencias necesarias
Basándonos en la documentación oficial de Vert.x, añadimos en el fichero ‘pom.xml’ las dependencias necesarias para poder crear y configurar un servidor HTTP2.
<dependencies> <dependency> <groupId>io.vertx</groupId> <artifactId>vertx-core</artifactId> <version>3.4.2</version> </dependency> </dependencies>
5. Creación e importación del certificado
Aunque en la RFC del protocolo HTTP/2 no se explícita que sea obligatorio el uso de conexión cifrada, no existe prácticamente ningún navegador que soporte HTTP/2 sin haber cifrado la conexión, principalmente porque se aprovecha el TLS Handshake como medio para negociar la conexión HTTP/2
Por tanto, para este tutorial vamos a generar un certificado auto-firmado, el cual utilizaremos más tarde en nuestro servidor HTTP/2.
Para generar el certificado auto-firmado utilizaremos la herramienta Java KeyTool. Incluiremos directamente el JKS en el src/main/resources del proyecto
keytool -genkey -keyalg RSA -alias vertx_http2 -keystore keystore_vertx.jks -storepass pass1234 -keysize 2048
6. Creación y configuración del HTTP/2 Server
En este apartado se mostrará como crear un servidor HTTP/2 con Vert.x. Hay que tener en cuenta, que para que Vert.x utilice el protocolo HTTP/2, hay que habilitar de forma explícita el uso de ALPN. Será aquí donde se configurará la ubicación del KeyStore generado en el paso anterior.
VertxHttp2Server.java
final Vertx vertx = Vertx.factory.vertx(); final HttpServerOptions options = new HttpServerOptions() .setLogActivity(true) .setUseAlpn(true) .setSsl(true) .setKeyStoreOptions(new JksOptions().setPath("keystore_vertx.jks").setPassword("pass1234")); final HttpServer httpServer = vertx.createHttpServer(options);
Con este fragmento de código, ya tendremos lista la base para nuestro servidor HTTP2. Vamos ahora a configurar un Handler para las request entrantes
7. Creación del Handler para las Requests entrantes
En este tutorial simplemente crearemos la clásica respuesta «Hello World!», a través del objeto HttpResponse. Para ello, añadiremos el Handler correspondiente a la request de nuestro servidor HTTP2.
httpServer.requestHandler(httpRequest -> { System.out.println("HTTP Request recibida!"); httpRequest.response().end("Hello World!"); });
A continuación pasaremos finalmente a asociar nuestro servidor HTTP2 con un puerto
8. Configuración del puerto de escucha
Finalmente, terminamos de codificar nuestro servidor HTTP2, configurando el puerto de escucha donde arrancará el servidor. En este caso, vamos a configurarlo en el puerto 8443.
Añadiremos además un par de trazas de logging, para saber que el servidor ha arrancado correctamente
httpServer.listen(8443, result -> { if (result.succeeded()) { System.out.println("Server is now listening!"); } else { System.out.println("Failed to bind!"); } });
9. Arranque del servidor con la extension ALPN usando la JDK
Es posible que cuando intentemos arrancar nuestra aplicación, nos aparezca el siguiente error
Exception in thread "main" io.vertx.core.VertxException: ALPN not available for JDK SSL/TLS engine at io.vertx.core.net.impl.SSLHelper.resolveEngineOptions(SSLHelper.java:89) at io.vertx.core.net.impl.SSLHelper.(SSLHelper.java:169) at io.vertx.core.http.impl.HttpServerImpl.(HttpServerImpl.java:158) at io.vertx.core.impl.VertxImpl.createHttpServer(VertxImpl.java:268) at io.drodriguezhdez.tutorials.http2.vertx.VertxHttp2Server.run(VertxHttp2Server.java:21) at io.drodriguezhdez.tutorials.http2.vertx.VertxHttp2Server.main(VertxHttp2Server.java:12)
Esto es debido a que tenemos que tener en cuenta que en este tutorial se ha utilizado la versión 1.8 de la JDK de Java, por lo que para poder arrancar nuestro servidor HTTP2 necesitamos vitaminar de alguna forma las clases de arranque de la JDK, ya que debemos recordar que la version 1.8 de JDK NO tiene soporte nativo para la extension ALPN
Como en este tutorial vamos a utilizar TLS a través de la JDK, es necesario utilizar una de las librerías de ALPN de Jetty en tiempo de arranque. La elección de la versión de la librería dependerá de nuestra versión de JDK con la que vayamos a ejecutar la aplicación.
En este caso, como la versión que estoy utilizando es la 1.8.0_u45, mi version de alpn-boot correspondiente es la 8.1.3.v20150130. Podéis consultar todas las correspondencias en la siguiente página: Table 15.1. ALPN vs. OpenJDK versions
Una vez se disponga de la librería, es necesario añadir la siguiente propiedad a las VM properties de arranque
-Xbootclasspath/p:<path/to/alpn-boot/library>/alpn-boot-<version>.jar
Si todo funciona correctamente, al arrancar nuestra aplicación deberemos recibir el correspondiente mensaje de success por consola
10. Probando el servidor usando Google Chrome
Para poder probar si nuestro servidor está corriendo en HTTP/2, vamos a utilizar Google Chrome previa instalación de una extensión que nos va a permitir saber si la conexión con el servidor se está realizando en HTTP/2
Podéis encontrar la extensión en el siguiente enlace: HTTP/2 and SPDY Indicator for Google Chrome
Finalmente, accedemos a la URL donde está escuchando nuestro servidor HTTP/2, en este caso: https://localhost:8443 y comprobamos que el indicador nos dice que estamos en una conexión HTTP/2
Y en nuestro log del servidor, podemos comprobar que efectivamente estamos recibiendo peticiones HTTP que estamos manejando sin ningún problema.
11. Conclusiones
En este tutorial hemos realizado un ejemplo de cómo implementar un servidor HTTP/2 utilizando Vertx, así como la resolución de los principales problemas de arranque utilizando versiones de Java JDK 1.8 o inferiores.
12. Contacto y GitHub repository
¿Habéis tenido algún que otro problema con el tutorial? Déjame un comentario en este artículo o coméntamelo a través de mi cuenta de Twitter: @drodriguezhdez.
Echa un vistazo al código del tutorial en mi repositorio de GitHub: Source code del Tutorial.
13. Referencias
- Vert.x core Manual
- How to Create a Self Signed Certificate using Java Keytool
- Jetty – Application Layer Protocol Negotiation (ALPN)