Cuando un navegador realiza una solicitud HTTP, se ve así:
GET /search?q=cats HTTP/1.0
Host: www.google.com
Connection: close
... a la que el servidor debe enviar una respuesta como 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, usando 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 el 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 de forma rígida: 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á muy complejo. 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 adecuada sería utilizar un servidor web, como Apache HTTPD , IIS , o nginx . Un servidor web es solo un programa que escucha en los sockets TCP relevantes, acepta múltiples solicitudes (posiblemente de manera simultánea) y decide cómo generar una respuesta basada en la URL de solicitud, los encabezados y otras reglas. Idealmente, muchos de los detalles, como SSL, control de acceso y límites de recursos, se cuidan a través de la configuración en lugar del código. La mayor parte del tiempo, el servidor web formulará una respuesta que consiste solo en el 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 ligeramente 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 más 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 con node.js y motores de servlet de 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.