Skip to content

MartaFontsere/Webserver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

169 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

WebServer - Nginx-Style HTTP Server

A high-performance HTTP/1.1 web server implementation inspired by NGINX, built from scratch in C++98. This project implements a fully functional web server with support for multiple virtual hosts, CGI execution, file uploads, and modern HTTP features.

πŸš€ Features

Core HTTP Features

  • HTTP/1.1 Protocol - Full implementation with persistent connections
  • Multiple HTTP Methods - GET, POST, DELETE, HEAD support
  • Non-blocking I/O - Event-driven architecture using poll()
  • Chunked Transfer Encoding - Support for streaming large requests/responses
  • Virtual Hosts - Multiple server blocks with different configurations
  • Custom Error Pages - Configurable error pages per status code

Advanced Capabilities

  • CGI Support - Execute Python, Bash, and other CGI scripts
  • File Uploads - Handle multipart/form-data with size limits
  • Directory Listing - Auto-index functionality for directories
  • HTTP Redirects - 301/302 redirects with customizable rules
  • Static File Serving - Efficient serving of HTML, CSS, JS, images
  • Request/Response Chunking - Handle large payloads efficiently

Configuration System

  • NGINX-style Config - Familiar configuration file syntax
  • Syntax Validation - Parse-time validation of config structure
  • Semantic Validation - Runtime validation of config values
  • Flexible Routing - Location blocks with pattern matching
  • Multiple Servers - Run multiple servers on different ports

πŸ“‹ Requirements

  • Compiler: g++ or clang++ with C++98 support
  • OS: Linux or macOS
  • Build Tool: GNU Make
  • Optional: Python 3.x (for CGI tests)

πŸ”§ Installation

Quick Start

# Clone the repository
git clone https://github.com/MartaFontsere/Webserver.git
cd WebServer_oficial

# Build the project
make

# Run with default configuration
./webServer.out

# Run with custom configuration
./webServer.out tests/configs/default.conf

Build Targets

make          # Compile the server
make clean    # Remove object files
make fclean   # Remove object files and executable
make re       # Recompile everything

🎯 Usage

Basic Usage

# Start server with default config
./webServer.out

# Start server with custom config file
./webServer.out path/to/config.conf

# Graceful shutdown
Ctrl+C  # Sends SIGINT for clean shutdown

Configuration File Example

server {
    listen 8080;
    host 127.0.0.1;
    server_name localhost;
    root ./www;
    index index.html index.php;
    client_max_body_size 1048576;
    error_page 404 /404.html;
    error_page 500 /500.html;

    location / {
        allow_methods GET POST DELETE HEAD;
        root ./www;
        index index.html;
        autoindex on;
    }

    location /cgi-bin {
        allow_methods GET POST;
        cgi_path /usr/bin/python3;
        cgi_ext .py;
    }

    location /uploads {
        allow_methods GET POST DELETE;
        upload_path ./www/uploads;
        client_max_body_size 5242880;
    }
}

πŸ§ͺ Testing

Quick Tests

# Run automated test suite
./tests/scripts/test-autoindex.sh
./tests/scripts/test-post-delete.sh
./tests/scripts/test_cgi.sh

# Test with web browser
# Start server: ./webServer.out tests/configs/default.conf
# Open browser: http://localhost:8080/

Manual Testing

Static File Serving

# Serve welcome page
http://localhost:8080/

# Serve specific file
http://localhost:8080/tests/files/document1.txt

Directory Listing (Autoindex)

# Auto-generated directory listing
http://localhost:8080/tests/files/

# Subdirectory listing
http://localhost:8080/tests/files/subdir/

# Index file takes priority (no autoindex)
http://localhost:8080/tests/public/

Error Handling

# 403 Forbidden (directory without index and autoindex off)
http://localhost:8080/tests/private/

# 404 Not Found
http://localhost:8080/nonexistent.html

File Upload (POST)

# Upload interface
http://localhost:8080/post-delete/test.html

# Or use curl
curl -X POST -F "file=@test.txt" http://localhost:8080/uploads/

File Deletion (DELETE)

# Delete file via curl
curl -X DELETE http://localhost:8080/uploads/test.txt

# Or use web interface
http://localhost:8080/post-delete/test.html

CGI Execution

# Python CGI script
http://localhost:8080/cgi-bin/test.py

# Bash CGI script
http://localhost:8080/cgi-bin/test.sh

πŸ“ Project Structure

WebServer_oficial/
β”œβ”€β”€ main.cpp                    # Entry point and signal handling
β”œβ”€β”€ Makefile                    # Build configuration (auto-detects sources)
β”œβ”€β”€ includes/                   # Header files
β”‚   β”œβ”€β”€ config/                 # Configuration classes
β”‚   β”œβ”€β”€ config_parser/          # Config file parser
β”‚   β”œβ”€β”€ core/                   # Server core
β”‚   β”œβ”€β”€ http/                   # HTTP protocol handling
β”‚   β”œβ”€β”€ network/                # Network I/O
β”‚   └── cgi/                    # CGI execution
β”œβ”€β”€ src/                        # Source files
β”‚   β”œβ”€β”€ config/                 # Configuration implementation
β”‚   β”œβ”€β”€ config_parser/          # Parser implementation
β”‚   β”œβ”€β”€ core/                   # Server implementation
β”‚   β”œβ”€β”€ http/                   # HTTP implementation
β”‚   β”œβ”€β”€ network/                # Network implementation
β”‚   └── cgi/                    # CGI implementation
β”œβ”€β”€ tests/                      # Test suite
β”‚   β”œβ”€β”€ configs/                # Test configuration files
β”‚   └── scripts/                # Automated test scripts
β”œβ”€β”€ www/                        # Document root (static files)
└── README.md                   # This file

πŸ› οΈ Troubleshooting

Port Already in Use

If you see this error:

Error en bind(): Address already in use
❌ Error: no se pudo crear el socket.

Solution:

# Find process using the port
lsof -i :8080

# Kill the process
kill -9 <PID>

# Or kill all instances
pkill webServer.out

Permission Issues (403 Forbidden)

Testing 403 errors with restricted files:

# Remove all permissions (for testing)
chmod 000 www/tests/files/secret.pdf

# Restore permissions (before commit)
chmod 644 www/tests/files/secret.pdf

⚠️ Note: Git cannot track files with 000 permissions. Always restore permissions before committing.

CGI Scripts Not Executing

Ensure CGI scripts have execution permissions:

chmod +x www/cgi-bin/script.py
chmod +x www/cgi-bin/script.sh

πŸ—οΈ Architecture

Modular Design

The server is organized into independent modules:

  • config_parser: Parses and validates configuration files
  • config: Converts parsed config to typed structures
  • network: Socket management and I/O multiplexing
  • http: HTTP protocol parsing and response generation
  • core: Server engine and request routing
  • cgi: CGI script execution and environment setup

Request Flow

Client β†’ Network β†’ HTTP Parser β†’ Router β†’ Handler β†’ HTTP Response β†’ Network β†’ Client
                                    ↓
                              CGI / Static / Upload

Key Technologies

  • I/O Multiplexing: poll() for non-blocking event-driven I/O
  • Memory Safety: RAII principles, STL containers (no raw pointers)
  • C++98 Standard: Full compatibility with older compilers
  • Signal Handling: Graceful shutdown on SIGINT/SIGTERM

πŸ“š Documentation

Detailed documentation available in module-specific README files:

🀝 Contributing

This is a student project for 42 School. While external contributions are not accepted, feel free to fork and learn from the code.

πŸ‘₯ Team

πŸ“„ License

This project is part of the 42 School curriculum and follows their academic guidelines.

πŸŽ“ Project Information

School: 42 Barcelona
Project: Webserv
Language: C++98
Started: October 27, 2025

(opciΓ³n 2)

Redirecciones:

  • Terminal:
    - make
    - ./webServer.out tests/configs/default.conf
  • Navegador:
    - http://localhost:8080/google El navegador deberΓ­a saltar automΓ‘ticamente a google.com (estamos probando el comando return 301 de la configuraciΓ³n)

PRUEBAS DE ERRORES Y LÍMITES

PΓ‘gina de Error Personalizada:

LΓ­mites de Body (413 Payload Too Large)

  • Terminal:
    - make
    - ./webServer.out tests/configs/default.conf
  • Terminal:
    - /tests/scripts/test_limits.sh
    Verifica que peticiones mayores de 100 bytes (en esta config) son rechazadas

PRUEBAS AVANZADAS:

Test multiclient:

  • Terminal 1:
    - make
    - ./webServer.out tests/configs/default.conf
  • Terminal 2:
    - python3 tests/scripts/number_clients_stress_test.py
    Lanza 20 clientes concurrentes para verificar que el servidor no se bloquea.

Test timeout (nc):

  • Terminal 1:
    - make
    - ./webServer.out tests/configs/default.conf
  • Terminal 2: - nc - v localhost 8080 (y esperar sin escribir nada) El servidor deberΓ­a cerrar la conexiΓ³n tras el tiempo de inactividad configurado

Test Virtual Host:

  • Terminal 1:
    - make
    - ./webServer.out tests/configs/default.conf
  • Terminal 2: - ./tests/scripts/test_vhosts.sh
    Verifica que el servidor responde distinto segΓΊn el header Host: marta.com.

Test Alias:

  • Terminal 1:
    - make
    - ./webServer.out tests/configs/default.conf
  • Terminal 2: - ./tests/scripts/test_alias.s Verifica que /test-alias/ sirve archivos de una carpeta distinta a la raΓ­z (tests/test_assets)

Test MΓΊltiples puertos:

  • Terminal 1:
    - make
    - ./webServer.out tests/configs/default.conf
  • Terminal 2: - ./tests/scripts/test_ports.sh
    Verifica que el servidor escucha en el 8080 y en el 9999 simultΓ‘neamente

PRUEBAS DE GESTIΓ“N DEL SERVIDOR

Test Cierre limpio del servidor:

  • Terminal 1:
    - make
    - ./webServer.out tests/configs/default.conf
    - Pulsar Ctrl+C en la terminal del servidor
    VerΓ‘s el mensaje πŸ›‘ Signal received, shutting down gracefully.... El puerto 8080 se liberarΓ‘ inmediatamente.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •