¿Es esto posible?
Si
Sé que suena extraño y parece más un ejercicio de inutilidad, pero no lo es.
En este artículo, le diré cómo puede usar C ++ en el desarrollo de sitios web, y le daré algunas buenas razones para esto.
No solo será interesante, sino también útil y muy práctico.
Hospedaje
Probablemente piense: una configuración tan inusual solo puede implementarse en un entorno especializado. Sin embargo, este no suele ser el caso. A pesar del hecho de que un servidor especial regular o virtual sería una solución ideal para muchos sitios (no solo sitios C ++), en la mayoría de los casos puede usar C ++ en servicios de alojamiento compartido.
Cualquier alojamiento web que admita CGI (es decir, en principio, todos) podrá admitir un sitio en C ++. Dependiendo del proveedor, puede compilar su sitio localmente o no, y necesita el compilador incluido en su cuenta. Revíselos si planea editar y compilar a través de SSH directamente en el servidor web.
Ejemplo simple
En los ejemplos anteriores, uso la cuenta de alojamiento cPanel. Son asequibles, económicos y consistentes. Pero puede adaptar fácilmente estos métodos a un servidor virtual o dedicado o una instancia de Amazon EC2 con algunas modificaciones simples a su configuración de Apache.
cPanel nos proporciona la carpeta cgi-bin, pero no la necesitamos. En la mayoría de los casos, cualquier archivo con la extensión .cgi se procesará automáticamente si tiene los permisos correctos (generalmente 0755). Aquí están los archivos necesarios (asegúrese de usar la TAB en el Makefile)
Makefile:
all: g++ -O3 -s hello.cpp -o hello.cgi clean: rm -f hello.cgi
hola.cpp:
#include <iostream> #include <string> #include <stdlib.h> using namespace std; void set_content_type(string content_type) { cout << "Content-type: " << content_type << "\r\n\r\n"; } void set_page_title(string title) { cout << "<title>" << title << "</title>\n"; } void h1_text(string text) { cout << text << "\n"; } int main() { set_content_type("text/html"); // Output HTML boilerplate cout << "<!doctype html>\n"; cout << "<html lang=\"en\">\n"; cout << "<head>\n"; set_page_title("Hello, World!"); cout << "</head>\n"; cout << "<body>\n"; h1_text("Hello, World!"); cout << "</body>\n"; cout << "</html>"; return 0; }
Si tiene compiladores incluidos en su cuenta (es posible que deba solicitar al equipo de soporte su alojamiento web), solo use SSH en su cuenta, coloque estos archivos en la carpeta public_html, luego haga lo siguiente:
make
Se ejecutará el archivo hello.cgi. Si ingresa la dirección del archivo en un navegador, por ejemplo, así:
http:
Luego reemplace your-test-site.com con su nombre de dominio o URL de alojamiento. "Hola Mundo" debería aparecer en la pantalla.
Antes de sumergirse en el código en sí, veamos cómo funciona en un servidor web. Cuando Apache acepta la solicitud, lo primero que observa es el controlador interno o la regla de reescritura, luego busca en el disco el archivo que coincide con la solicitud. En nuestro caso, encuentra hello.cgi y lo recupera. Nuestro programa no acepta entradas, pero solo muestra el mensaje "Hola mundo". Apache luego recibe estos datos y se los devuelve al usuario.
Hablando sobre el código, debe mencionarse que podría ser más fácil. No fue necesario incluir funciones separadas set_content_type, set_page_title y h1_text. Hay ayudantes simples que mantienen la limpieza en la función principal. Todo esto simplemente puede llevarse a la función principal, y funcionará exactamente de la misma manera.
Pero espero que vea una ventaja al resaltar estas características. Si necesita crear una función para cada elemento HTML, puede usar este código para crear una respuesta de respuesta limpia en su programa:
void p(string text) { cout << "<p>" << text << "</p>\n"; }
Luego usa algo como:
p("This would be paragraph text.");
Para mostrar un párrafo.
Incluso podría desarrollar esta idea para que las funciones auxiliares como p, h1_text, etc., devuelvan el texto en lugar de la salida directa a la salida estándar a través de cout. Al mismo tiempo, puede crear un sistema de plantillas o anidar respuestas para crear páginas complejas con un código C ++ muy racionalizado y eficiente.
Este ejemplo es lo más simple posible, indica solo los puntos principales. Tiene acceso completo a cada encabezado de respuesta, lo que le brinda un control completo sobre el bucle de respuesta.
Más acerca de la entrada
Nuestro ejemplo no acepta ninguna entrada, solo devuelve "Hola Mundo". Pero Apache responde a cada solicitud con una gran cantidad de información a través de variables de entorno. Puede usar la función getenv () en la biblioteca estándar de C para obtener sus valores (no olvide agregar #include <stdlib.h> al comienzo del código). Por ejemplo, si necesita encontrar el URI de solicitud completo, usaría:
string request_uri = getenv("REQUEST_URI");
para obtener este valor Otras variables útiles:
- REMOTE_ADDR: obtención de la dirección IP del visitante
- REQUEST_METHOD: devuelve un método (es decir, GET, POST, etc.)
- DOCUMENT_ROOT: ruta del sitio (generalmente ~ / public_html en sistemas compartidos o / var / www / html en servidores virtuales / dedicados).
- QUERY_STRING - Una cadena de consulta para obtener variables GET.
Ejemplo más claro
Por supuesto, es posible analizar las variables GET manualmente, y el procesamiento de las variables POST se puede hacer al verificar la entrada estándar. Incluso puede recibir y configurar cookies cambiando los encabezados de solicitud y respuesta. Pero ambos enfoques son demasiado tediosos.
Puede escribir sus propios shells o utilizar la biblioteca GNU cgicc lista para usar. Contiene funciones auxiliares para modificar HTML y procesar formularios. Al trabajar con proyectos grandes, el uso de una biblioteca de este tipo ahorraría bastante tiempo.
En Debian y Ubuntu, puede instalar la biblioteca y los encabezados usando:
apt install libcgicc5 libcgicc5-dev
Pero CentOS / RHEL no tiene sus propios paquetes. Para instalar en ellos, ejecute:
cd /usr/local/src wget ftp:
NOTA: 3.2.19 era la última versión en el momento de la escritura, pero puede buscar una copia más reciente en
ftp.gnu.org/gnu/cgicc . También usé / usr como prefijo para evitar problemas al vincular bibliotecas. En todo caso, cámbialos con calma.
Después de instalar cgicc, puede compilarlo. Pruebe este ejemplo, que toma la entrada de un formulario y lo muestra en un navegador:
Makefile:
all: g++ -O3 -s hello.cpp -o hello.cgi g++ -O3 -s cgicc.cpp -o cgicc.cgi /usr/lib/libcgicc.a clean: rm -f hello.cgi cgicc.cgi
cgicc.html:
<!doctype html> <html lang="en"> <head> <title>cgicc Test</title> </head> <body> <form method="POST" action="cgicc.cgi"> <label for="name">Name</label> <input name="name" type="text" value=""> <input name="submit" type="submit" value="Submit"> </form> </body> </html>
cgicc.cpp:
#include <iostream> #include <string> #include <stdio.h> #include <stdlib.h> #include <cgicc/CgiDefs.h> #include <cgicc/Cgicc.h> #include <cgicc/HTTPHTMLHeader.h> #include <cgicc/HTMLClasses.h> using namespace std; using namespace cgicc; void set_content_type(string content_type) { cout << "Content-type: " << content_type << "\r\n\r\n"; } void set_page_title(string title) { cout << "<title>" << title << "</title>\n"; } void h1_text(string text) { cout << text << "\n"; } int main() { Cgicc cgi; string name; set_content_type("text/html"); cout << "<!doctype html>\n"; cout << "<html lang=\"en\">\n"; cout << "<head>\n"; set_page_title("cgicc Test"); cout << "</head>\n"; cout << "<body>\n"; cout << "<p>"; // Grab the "name" variable from the form name = cgi("name"); // Check to make sure it isn't empty. if (!name.empty()) { cout << "Name is " << name << "\n"; } else { cout << "Name was not provided."; } cout << "</p>\n"; cout << "</body>\n"; cout << "</html>"; return 0; }
Es posible que hayas notado que enlacé estáticamente la biblioteca cgicc en el Makefile. Aunque esto no es necesario (puede reemplazarlo con -Icgicc), prefiero vincular estáticamente el código binario que envío al servidor para que todo lo necesario para ejecutar el programa se envíe como un conjunto.
En este ejemplo, la biblioteca cgicc hace el trabajo duro de las variables POST y nos devuelve "nombre".
No escapé de la variable de entrada POST, pero se recomienda, especialmente en lugares de producción, especialmente si interactúa con la base de datos.
Esta es solo una pequeña parte de las posibilidades de cgicc. Puedes
leer la documentación completa
aquí .
Rendimiento / rendimiento
C ++ es increíblemente rápido para trabajar con un buen código. La interfaz CGI ralentiza un poco las cosas, pero aun así obtendrá una mejor ejecución que en lenguajes interpretados como PHP.
Como dicen, siempre hay algo por lo que luchar. En un entorno especializado o virtual, puede usar el soporte FastCGI de Nginx o Apache para reducir el pequeño retraso (y discreto, si el servidor no está muy cargado) en el momento en que se carga el programa. No hubo demoras en mis pruebas, pero para trabajar con un sitio web con tráfico cargado sería útil estudiar estas soluciones para una ejecución aún más rápida / trabajo rápido
Opcional
Sería fácil envolver un programa C ++ en un contenedor Docker delgado. Esto le proporcionará una gran flexibilidad al colocar un sitio. También puede acceder a la base de datos MySQL incluyendo los encabezados de desarrollo MySQL C / C ++ en su programa. Si está familiarizado con el uso de MySQL con PHP, notará que los nombres de las variables son muy similares.
En lugar de crear procesos de línea de comandos adicionales para el procesamiento de imágenes, puede incluir encabezados ImageMagick C ++ para procesar estas imágenes directamente en su programa
Qué viaje tan largo y extraño
Crear un sitio en C ++ es práctico, especialmente si el rendimiento es importante. No recomendaría esto para un blog o sitio personal, se pueden hacer fácilmente en WordPress. Pero si tiene una necesidad urgente de velocidad y un deseo de escribir bien en un camino trillado, considere C ++ para su próximo proyecto de nicho en la web.