¿Qué hemos realizado hasta el momento?

  1. Hemos aprendido a crear una conexión TCP.
  2. Logramos enviar y leer una solicitud HTTP.
  3. Logramos tener una vista al momento que nuestro servidor está activo.
  4. Hemos aprendido a enviar status 200 por el navegador.

Para tener nuestro servidor completo, necesitamos otro status que podría ayudarnos a validar si no obtenemos respuesta a nuestra solicitud. El tan temido 404 Not Found. Para esto ya sabemos como leer archivos html dentro de nuestra función principal, ahora debemos crear una nueva interfaz mostrando mensaje de error.

Haremos una modificación a nuestro código, esta vez usaremos ìf y else para manejar nuestras dos peticiones. Al código que ya hemos venido trabajando, nos posicionamos en nuestra función handle_connection, ahí es donde crearemos nuestras condiciones.

Agregaremos la siguiente línea a nuestro código:

let get = b"GET / HTTP/1.1\r\n";

Primero, agregamos la respuesta de nuestra solicitud en la una variable llamada get. Debido a que estamos leyendo bytes sin procesar en el buffer, transformamos get en una cadena de bytes agregando la sintaxis de cadena de bytes "b" al comienzo de la respuesta.

Ahora sí, comenzamos con nuestra condición:

if buffer.starts_with(get) {}

Esto significa que si buffer recibe una respuesta en get y nuestra condición se cumple, quiere decir que tendremos que arrojar nuestro mensaje con el status 200 de petición exitosa.

let contents = fs::read_to_string("hello.html").unwrap(); let response = format!("HTTP/1.1 200 OK\r\n\r\n{}", contents); stream.write(response.as_bytes()).unwrap(); stream.flush().unwrap();

Pero en caso de que esta condición no se llegara a cumplir, es decir, que se está enviando otro tipo de petición y no nuestra dirección, por ejemplo: `127.0.0.1:7373/algo´ esto debería arrojarnos un mensaje de error en nuestro navegador.

Para esto, primero crearemos un archivo html que nos muestre un mensaje de error en mi caso es 404.html.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Hola</title> </head> <body> <h1 style="text-align:center;">¡Oops!</h1> <h1 style="text-align:center;">Lamento el inconveniente, pero no encuentro la página que solicitas</h1> <img src="https://www.rust-lang.org/logos/error.png" style="display:block; margin:auto;" width="600" height="500" /> </body> </html>

Ya que tenemos nuestro mensaje de error para mostrar en el navegador, creamos nuestra respuesta en nuestra condicionante:

} else { let status_line = "HTTP/1.1 404 NOT FOUND\r\n\r\n"; let contents = fs::read_to_string("404.html").unwrap(); let response = format!("{}{}", status_line, contents); stream.write(response.as_bytes()).unwrap(); stream.flush().unwrap(); }

Si revisas, lo único que llega a cambiar es nuestra variable response que ahora es status_line donde recibe mensaje de error a la petición, y ahora leemos nuestro archivo 404.htmlen lugar de nuestro archivo de bienvenida.

Es hora de que ejecutes cargo run y veas los resultados.

Ya tenemos un servidor que puede enviar y recibir una sola petición, eso es un gran avance para ser nuestra 4ta clase. En las siguientes clases aumentaremos la dificultad creando un servidor que reciba varias peticiones a la vez.

Es hora de que juegues con tu código, de qué manera crees que pueda ser refactorizado, también puedes agregar control de errores para que te sea más fácil identificarlos.

Por el momento, deja en los comentarios el mensaje de error 404 que diseñaste.