Quando un browser effettua una richiesta HTTP, si presenta così:
GET /search?q=cats HTTP/1.0
Host: www.google.com
Connection: close
... a cui il server dovrebbe inviare una risposta simile alla seguente:
HTTP/1.0 200 Success
Content-Type: text/html; charset=UTF-8
Content-Length: 1337
<!DOCTYPE html>
<html>
<head><title>cats - Google Search</title>
<body>
<h1>About 415,000,000 results</h1>
…
</body>
</html>
Qualsiasi codice in esecuzione sul server che ascolta le richieste su un socket TCP, legge la richiesta e risponde con la risposta appropriata sarà sufficiente. Un modo stupido è solo quello di sputare una risposta predefinita a chiunque si connetta alla porta TCP 80, usando uno script shell:
$ nc -l 8000 <<'RESPONSE'
HTTP/1.0 200 Success
Content-Type: text/html; charset=UTF-8
Content-Length: 1337
<!DOCTYPE html>
<html>
<head><title>cats - Google Search</title>
<body>
<h1>About 415,000,000 results</h1>
…
</body>
</html>
RESPONSE
Naturalmente, questa tecnica sembra a malapena conforme al protocollo HTTP .
Un passo avanti rispetto a questa risposta predefinita è questo semplice programma Python, che utilizza la http.server
libreria in Python 3.
#!/usr/bin/python3
import http.server
class Handler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
payload = '<!DOCTYPE html>... insert cats here ...'.encode('UTF-8')
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=UTF-8')
self.send_header('Content-Length', len(payload))
self.end_headers()
self.wfile.write(payload)
http.server.HTTPServer(('', 80), Handler).serve_forever()
Il server HTTP può essere scritto in qualsiasi lingua; questo è solo un esempio. Ovviamente, questo esempio è molto rudimentale. Il payload è hardcoded - il programma ignora completamente il contenuto della richiesta - l'URL, la stringa di query, l'intestazione Accept-Language, ecc. È possibile aggiungere codice per generare risposte significative in base alla richiesta, ma il codice otterrebbe molto complesso. Inoltre, i programmatori preferiscono concentrarsi sulla scrittura dell'applicazione Web, senza doversi preoccupare dei dettagli su come gestire una richiesta HTTP.
Una soluzione più appropriata sarebbe quella di utilizzare un server Web, come Apache HTTPD , IIS o nginx . Un server Web è solo un programma in ascolto sui socket TCP pertinenti, accetta più richieste (possibilmente contemporaneamente) e decide come generare una risposta in base all'URL della richiesta, alle intestazioni e ad altre regole. Idealmente, molti dettagli, come SSL, controllo degli accessi e limiti delle risorse, vengono gestiti tramite la configurazione anziché tramite il codice. La maggior parte delle volte, il server Web formulerà una risposta che consiste solo nel contenuto dei file nel filesystem.
Per i contenuti dinamici, tuttavia, il server Web può essere configurato per eseguire del codice per generare la risposta. Un meccanismo per farlo è con CGI: il server imposta alcune variabili di ambiente in base alla richiesta, esegue un programma e copia il suo output nel socket TCP. Una soluzione leggermente più sofisticata sarebbe quella di avere un modulo che aggiunga supporto al web server per chiamare il codice in un altro linguaggio di programmazione (es. Mod_php per Apache ). Un'altra opzione è scrivere il server Web nella stessa lingua dell'applicazione Web, nel qual caso l'invio della richiesta è solo una chiamata di funzione. Questo è il caso di node.js e dei motori servlet Java come Apache Tomcat .
La scelta della tecnologia dipende davvero da te e dipende dal linguaggio di programmazione che preferisci utilizzare, dall'ambiente di hosting a tua disposizione, dai requisiti di prestazione, dall'opinione popolare e dalle mode di passaggio. Il CGI, ad esempio, non è stato favorito di recente, poiché la necessità di avviare programmi esterni limita la scalabilità.