1. Indice

2. HTTP

L’HyperText Transfer Protocol è un protocollo di livello applicazione er lo scambio di ipermedia.

Segue l’architettura client/server, dove il client (browser) chiede un documento e il server HTTP risponde con la risorsa.

È un protocollo stateless, dove il server non tiene traccia delle precedenti connessioni, e ogni scambio di richiesta/risposta è indipendente dai precedenti.

Nella prima versione 1.0 (1996) le comunicazioni erano non presistenti, ma già un anno dopo HTTP 1.1 prevedeva comunicazioni persistenti per le risorse,

Con l’aumento dei dispositivi monbili e dell’utilizzo di contenuti multimediali e della richiesta di esperienze web più veloci ed efficienti, si è implementata una nuova versione del protocollo HTTP 2 che ha introdotto una serie di nuove tecnologie, come Server Push, Multiplexing, Priorità del flusso, Compressione header, Protocollo binario, …

Nel 2022 l’evoluzione in HTTP 3 ha mirato a migliorare l’efficienza, passando da una semplice richiesta GET ad un protocollo QUIC, un protocollo avanzato basato su UDP con multiplexing e crittografia integrata. QUIC riduce la latenza e aumenta la sicurezza.

Vediamo degli esempi di messaggi HTTP:

Richiesta

:method: GET
:scheme: https
:authority: www.example.com
:path: /index.html
user-agent: curl/7.79.1
accept: */*

Risposta

HTTP/3 200 OK
Date: Wed, 26 Jan 2024 12:34:56 GMT
Server: Apache/2.4.46 (Unix)
Last-Modified: Mon, 10 Jan 2024 10:15:20 GMT
Content-Length: 438
Content-Type: text/html; charset=UTF-8
<qui ci sono i dati>

3. APACHE HTTP server

Apache è un server che permette di hostare server web, implementato tramite apache2.

sudo apt update
sudo apt upgrade
sudo apt install apache2

Dopo l’installazione dovrebbe avviarsi automaticamente, ma è comunque possibile verificare tramite:

systemctl status apache2

È possibile verificare anche http://localhost in un qualsiasi browser sulla stessa macchina. In questo caso verrà mostrata la pagina che si trova in /var/www/html/index.html.

Per interagire con un server APCHE è possibile:

sudo apache2ctl <comando> # start, stop, restart, status, configtest

# opuure #
sudo service apache2 <comando> # start, stop, restart, reload

3.1. Configurazione

La directory principale si trova in /etc/apache2. Al suo interno il file di configurazione principale è /etc/apache2/apache2.conf.

La configurazione si specifica attraverso delle direttive, eventualmente raggruppate da direttive contenutore:

# Commento descrittivo
Direttiva1 valore
Direttiva2 valore

<Contenutore valore>
	Direttiva3 valore
	Direttiva4 valore
</Contenutore> # Fine contenutore

In generale si trovano altre configurazioni aggiuntive in:

Il sistema modulare funziona così:

# File apache2.conf
...
# Includo la lista di porta sulle quali stare in ascolto
Include ports.conf

# ----------------------- #
# File ports.conf

Listen 80

Per (dis)abilitare un file si utilizza il comando:

a2enconf <nome_file> # abilito

a2disconf <nome_file> # disabilito

Questo comando crea un soft link nella directory /etc/apache2/conf-enabled, file he viene incluso di default all’interno di apache2.conf.

Dopo una qualsiasi modifica è necessario riavviare il server per ricaricare la configurazione.

Per i moduli si (dis)abilitano:

a2enmod <nome_file> # abilito
a2dismod <nome_file> # disabilito

Se due moduli adassero in conflitto, il server ritorna un messaggio di errore durante il caricamento della nuova configurazione.

3.2. Direttive Globali

Sono configurazioni generali che vengono applicate al server Apache nel suo complesso, indipendentemente dai siti web o dai virtual host ospitati. Sono impostate nel file apache2.conf e possono riguardare:

A meno che non vengano sovrascritte a livello di virtual host o dorectory, vengono applicate a tutte le richieste e a tutte le risorse servite dal server.

La prima direttiva che vediamo è la server root. Di default la root del server è:

ServerRoot /etc/apache2

Questa specifica la directory principale contenente i file di configurazione di Apache, e rappresenta la base sulla quale sono risolti tutti i path relativi.

Questa direttiva è configurata automaticamente all’avvio di apache2ctl, infatti nel file apache2.conf è commentata.

Altre direttive sono:

KeepAlive on 			# se offrire o meno le connessioni persistenti HTTP 1.1
KeepAliveTimeout 5		# quanti secondi attendere la richiesta successiva dal client prima di chiudere la connessione
MaxKeepAliveRequest 100	# qauante richieste può fare al massimo un client sulla stessa connessione prima di chiuderla

Queste direttive sono ad oggi deprecate, ma comunque presenti nel file quindi è bene sapere cosa fanno. In particolare un valore troppo alto per la KeepAliveTimeout potrebbe bloccare inutilmente un processo che sta servendo un client lento o disconnesso.

Un altra direttiva importante è la seguente:

Listen 80
Listen 8080

Questa direttiva obbligatoria, presente in /etc/apache2/ports.conf che viene incluso in apache2.conf, permette di specificare le porte che userà Apache per mettersi in ascolto di connessioni.

Per recuperare gli errori è possibile utilizzare un file di log, specificandolo:

ErrorLog /var/log/apache2/error.log		# directory di default

Il formato e la verbosità dei messaggi possono essere definiti con le altre direttive ErrorLogFormat e LogLevel.

3.3. Direttive per i siti web - Virtual Host

Nel caso più semplice, un server web è in esecuzione su una macchina con un unico indirizzo IP offrendo un solo sito Web.

In questo caso, per avere $n$ siti web saranno necessarie $n$ macchine, utilizzando quindi tantissime risorse.

COn il name-based Virtual Hosting si possono configurare più siti sullo stesso server Web, sulla stessa macchina con lo stesso indirizzo IP.

Il server Web discrimina le richieste dei client in base al campo Host della richiesta HTTP:

GET /index.html HTTP/1.1
Host: www.mysite1.com
...

I virtual host si mettono in /etc/apache2/sites-available:

a2ensite <nome_file>	# abilita un sito al riavvio del server
a2dissite <nome_file>	# disabilita un sito al riavvio del server

Per definire un virtual host si utilizza la seguente sintassi:

<VirtualHost ip:porta>
...
</VirtualHost>

Nel caso più semlice Apache ha un Virtual Host abilitato di default in /etc/apache2/sites-available/000-default.conf:

<VirtualHost *:80>
	#ServerName www.example.com				Nome simbolico del sito
	ServerAdmin webmaster@localhost
	...
	DocumentRoot /var/www/html
	ErrorLog ${APACHE_LOG_DIR}/error.log	# uguale alla direttiva globale
	CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Questa configurazione risponde a tutti gli IP sulla porta 80.

3.4. Moduli Utili

Il modulo /etc/apache2/mods-availaable/dir.conf, abilitato didefualt, permette di specificare attraverso la direttiva DirectoryIndex il file da prelevare in caso non venga specificato dal client.

DirectoryIndex index.html index.cgi index.pl index.php ...

In questo modo quando l’utente digita www.mysite.com riceverà il file www.mysite.com/index.html

Il modulo /etc/apache2/mods-availaable/userdir.conf, NON abilitato didefualt, permette invece ai singoli utenti di mettere i propri file nella cartella speciicfata e renderli accessibili tramite l’indirizzo www.mysite.com/~username/.

UserDir public_html

4. Multi-Processing Module

Affinché il server possa accettare e servire più richieste contemporaneamente Apache ricorre ad un Multi-Processing Module MPM, responsabile di gestire i socket, fare binfig delle porte, accettare connessioni e servirle, eventualmente usande processi e thread figli.

Su UNIX si può scegliere tre:

4.1. MPM prefork

Implementa un server multiprocesso senza thread. All’avvio, un processo padre lancia un certo numero di processi figli (preforking) che restano in ascolto accettando e servendo connessioni. Dopo aver servito una connessione tornano disponibili per una nuova connessione.

Il padre gestisce il pool dei figli, cercando di mantenere sempre alcuni figli disponibili.

Il preforking permette di diminuire l’overhead della fork() ad ogni connessione.

ogni figlio viene riciclato per MaxConnectionsPerChild connessioni, e poi viene ucciso per evitare memory leak accidentali. Il server genera all’avvio StartServer n figli. Il numero massimo di figli creabili dalle connessioni aggiuntive è MaxRequestWorkers.

I figli inattivi devono essere compresi nell’intervallo [MinSpareServers; MaxSpareServers].

Tutte queste variabili si trovano in /etc/apache2/mods-available/prefork.conf

Questo approccio ha come vantaggio:

Ha però anche degli svantaggi:

4.2. MPM Worker

Permette di avere un server-multiprocesso e multi-thread riducendo l’overhead.

Il processo padre genera un certo numero di figli, e ogni figlio genera:

Anche in questo caso il server genera StartServer n figli, che verranno riciclati per MaxConnectionsPerChild connessioni.

I figli generano all’inizio ThreadsPerChild, e il numero massimo di thread totali è MaxRequestWorkers, e anche in questo caso i thread devono essere compresi tra [MinSpareThreads, MaxSpareThreads],,

Il numero massimo di figli è necessariamente MaxRequestWorkers/ThreadsPerChild.

4.3. MPM Event

È una versione migliorata di MPM worker, ed è il modulo di defautl dalla versione 2.4.

Oltre ad accettare le connessioni, il thread listener gestisce le connessioni temporaneamente inattive. Ad esempio:

In questo modo aumentiamo il numero di connessioni servibili contemporaneamente a parità di numero di thread, eliminando i tempi morti.

Alcuni limiti globali sono: