Cuando un navegador realiza una solicitud HTTP, se ve así:
GET /search?q=cats HTTP/1.0
Host: www.google.com
Connection: close
... a lo que el servidor debe enviar una respuesta similar a esta:
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>
Cualquier código que se ejecute en el servidor que escuche las solicitudes en un socket TCP, lea la solicitud y responda con la respuesta adecuada será suficiente. Una forma tonta es simplemente escupir una respuesta enlatada a cualquiera que se conecte al puerto TCP 80, utilizando un script de 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
Por supuesto, esa técnica apenas parece cumplir con el protocolo HTTP .
Un paso adelante de esa respuesta enlatada es este sencillo programa de Python, que utiliza la http.server
biblioteca en 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()
El servidor HTTP se puede escribir en cualquier idioma; Eso es solo un ejemplo. Obviamente, este ejemplo es muy rudimentario. La carga útil está codificada: el programa ignora por completo el contenido de la solicitud: la URL, la cadena de consulta, el encabezado Accept-Language, etc. Puede agregar código para generar respuestas significativas basadas en la solicitud, pero luego el código se volvería muy complejo. Además, los programadores prefieren centrarse en escribir la aplicación web, sin tener que preocuparse por los detalles de cómo manejar una solicitud HTTP.
Una solución más apropiada sería usar un servidor web, como Apache HTTPD , IIS o nginx . Un servidor web es solo un programa que escucha en los zócalos TCP relevantes, acepta múltiples solicitudes (posiblemente simultáneamente) y decide cómo generar una respuesta basada en la URL de solicitud, encabezados y otras reglas. Idealmente, muchos de los detalles, como SSL, control de acceso y límites de recursos, se solucionan mediante la configuración en lugar del código. La mayoría de las veces, el servidor web formulará una respuesta que consta solo del contenido de los archivos en el sistema de archivos.
Sin embargo, para el contenido dinámico, el servidor web puede configurarse para ejecutar algún código para generar la respuesta. Un mecanismo para hacerlo es con CGI: el servidor establece algunas variables de entorno basadas en la solicitud, ejecuta un programa y copia su salida al socket TCP. Una solución un poco más sofisticada sería tener un módulo que agregue soporte al servidor web para llamar al código en otro lenguaje de programación (por ejemplo, mod_php para Apache ). Otra opción es escribir el servidor web en el mismo idioma que la aplicación web, en cuyo caso el envío de la solicitud es solo una llamada de función. Ese es el caso de los motores de servlet node.js y Java como Apache Tomcat .
La elección de la tecnología depende realmente de usted y depende del lenguaje de programación que prefiera usar, el entorno de alojamiento que esté disponible para usted, los requisitos de rendimiento, la opinión popular y las modas pasajeras. CGI, por ejemplo, no se ha visto favorecido últimamente, ya que la necesidad de lanzar programas externos limita la escalabilidad.