- Greivin Mauricio Fernández Brizuela c.2022437510
- Daniel Alonso Garbanzo Carvajal c.2022117129
- Ericka Michelle Cerdas Mejias c.2022138199
IC-6600 - Principios de Sistemas Operativos
- Fecha de entrega: 4 de octubre
Este proyecto implementa un servidor HTTP simple desde cero utilizando Rust. El servidor soporta las principales operaciones HTTP (GET, POST, PUT, DELETE, PATCH) y gestiona sesiones de usuario con cookies. Está diseñado para manejar múltiples solicitudes concurrentes utilizando hilos y asegura el acceso seguro a los datos de sesión mediante Arc
y Mutex
.
- Rust instalado, en caso de no tener Rust se puede instalar siguiendo las instrucciones en este enlace
- Una vez instalado, para correr los tests se corre el siguiente comando.
cargo test
- Para levantar el servidor se corre el siguiente comando
# Dirigirse al folder del server
cd rust-http
# Levantar servidor
cargo run
- Para realizar una solicitud se realiza mediante alguna herramienta como
curl
,Postman
oAPIDog
. La solicitud se realiza a la urlhttp://localhost:8080/{endpoint}
donde endpoint es el archivo donde se desea realizar la operación.
# Ejemplo usando curl
curl --location --request PATCH 'http://localhost:8080/users/420' \
--header 'Content-Type: application/json' \
--header 'Host: localhost:8080' \
--header 'Connection: keep-alive' \
--header 'Cookie: sessionId=991a02eb-16c2-48fb-ab87-459b778bca3f' \
--data-raw '{
"key": 212121
}'
El servidor está estructurado en tres componentes principales:
Server: El server
se encarga de manejar las cookies y mantiene la conexión abierta, puede procesar hasta 100 requests de manera simultánea al tener 100 hilos en un thread pool estático.
Client: El client
se encarga de manejar el request, esto incluye hacer el parsing del mismo y manejar el método del request de manera correcta.
Methods: methods
se encarga de manejar los diferentes métodos HTTP (GET, POST, PUT, DELETE, PATCH). La implementación de cada método se realizó para hacer las operaciones correspondientes a los archivos en la carpeta rust-http/files
.
La concurrencia se logra utilizando las características de la biblioteca estándar de Rust:
- Hilos: Cada conexión entrante entra al threadpool estático, el cual tiene 100 hilos. Estos hilos se encargan de manejar el request de manera adecuada.
- Datos Compartidos: Se utiliza el patrón
Arc<Mutex<Server>>
para compartir de forma segura el acceso a los datos de sesión del servidor entre hilos.Arc
permite múltiples propietarios, yMutex
asegura que solo un hilo pueda acceder o modificar los datos a la vez.
El servidor maneja la gestión de sesiones utilizando cookies. Cuando un nuevo cliente se conecta, se genera un ID de sesión único utilizando la crate uuid
, y se almacena en el HashMap
de sesiones del servidor. Si una solicitud contiene una cookie de sesión, el servidor verifica las sesiones existentes y reutiliza la sesión si es válida.
El servidor tiene manejo de errores para requests que están mal formados o les hacen falta datos para crear o modificar. Entre los errores se manejan los siguientes: 400: Bad Request
, 404: Not Found
, 500: Internal Server Error
. En caso de que haya un error al parsear el JSON se envía un status code 500
con su respectivo mensaje de error. Si hacen falta datos en el request o el request está mal formado se envía un status code 400
con su respectivo mensaje de error.
El servidor soporta las siguientes operaciones HTTP:
- GET: Recupera recursos basados en la ruta solicitada.
- POST: Crea un archivo con los datos enviados en el cuerpo de la solicitud.
- PUT: Actualiza recursos con los datos proporcionados.
- DELETE: Elimina recursos especificados por la ruta.
- PATCH: Actualiza parcialmente recursos con los datos proporcionados.
Se crearon 27 tests para probar todas las funciones del servidor y asegurar su funcionamiento.
Todos los tests pasan de manera exitosa.
Se utilizó el paquete de cargo-llvm-cov
, el cual se puede encontrar aquí.
Según la herramienta, se logró un coverage de un 100% de las funciones, sin embargo, solamente se logró un 74.04% de coverage en las regiones y un 85.42% de coverages en las líneas.
Por lo tanto, concluimos que se obtuvo un coverage promedio de 86.48%.
Para probar que el servidor funciona de manera exitosa se usó la aplicación de APIDog para enviar los diferentes requests
Endpoint: get
Endpoint: post
Endpoint: post
Endpoint: users/420
Endpoint: users/420
Para probar que el servidor maneja múltiples requests de manera exitosa, se intentó usar APIDog. Sin embargo, daba problemas de conexión al utilizar muchos hilos. Por lo tanto, se diseñaron las pruebas en esta aplicación para posteriomente exportarlas a JMeter.
Una breve corrida de prueba se muestra a continuación:
Method: PATCH
Endpoint: /users/420
Threads: 200