Cómo escribir un navegador web desde cero usando C ++

Fui parte del equipo central que comenzó a hacer tal cosa en 2007. Usted lo conoce como Google Chrome.

Calificaré “desde cero” en que Chrome no es un derivado de ningún navegador anterior. Sin embargo, no es desde cero en el sentido de que aprovechó muchas bibliotecas existentes, especialmente Webkit. Pero por volumen como lo fue en 2015, aproximadamente el 55% del código fue desde cero: código que no existía en 2007.

Sin utilizar un montón de bibliotecas existentes, el proyecto probablemente habría fallado al llegar demasiado tarde o al ser cancelado antes de eso. Los esfuerzos a esta escala necesitan justificación y “nos gusta desde cero” no es uno de ellos.

Por lo tanto, la pregunta más importante que desea hacerse no es el cómo sino el por qué. ¿De qué manera los navegadores existentes tienen deficiencias que desea abordar? La respuesta a esa pregunta será su brújula para las tareas por delante.

Por ejemplo, si su respuesta es que son inseguros, entonces estará buscando mejores lenguajes de programación o verificación automática de software. Como tal, comience allí y escriba un único componente pequeño. Sugiero el análisis de URL, luego busque algo más complejo, como el procesamiento Unicode, etc.

Si su respuesta es que son lentos, entonces debe invertir en crear bibliotecas que generen código de forma instantánea y análisis de JavaScript. Hay un montón de compensaciones que puede hacer allí que podrían dar sus frutos. Un mejor almacenamiento en caché también es un buen lugar para comenzar.

Pero si no hay una razón en particular, entonces básicamente quieres aprender cómo funcionan los navegadores. Como tal, la mejor manera de comenzar es escribir el motor de representación html más simple que pueda en el idioma que mejor conozca. Es decir, html entra y salen píxeles. Puede aprovechar las “pruebas de píxeles” de Webkit para validar la salida de su programa.

Para las personas que te dicen que no vale la pena hacerlo, no estoy de acuerdo. Las piezas de software más críticas que usa hoy en día, Chrome, Linux, NGINX, comenzaron con una persona insatisfecha / curiosa y una voluntad del tamaño de una montaña.

En cuanto a mí, ahora soy parte del equipo central que está escribiendo un sistema operativo desde cero [1]. ¡Entonces a ti te digo buena suerte!

[1] Fuchsia no es Linux

FYI: Hay más de 16 millones de líneas de código en el navegador FireFox … ¡así que calibre sus expectativas en consecuencia!

El navegador web más simple que conozco es “lynx”, que es un navegador de solo texto que no admite el 90% de las cosas que necesita un navegador moderno. Contiene alrededor de 170,000 líneas de código.

Entonces, incluso algo como lynx no es un proyecto en el que solo una persona pueda escribir en un par de años de esfuerzo dedicado a tiempo completo.

Supongo que los pasos generales serían:

  • Implemente algo que use el protocolo http / https para descargar archivos del servidor.
  • Escribe un analizador HTML.
  • Escribe un renderizador HTML.
  • Escriba un montón de cosas de GUI para manejar menús, pestañas, etc.
  • Escribe un analizador CSS.
  • Integre eso en su renderizador HTML.
  • Implementar JavaScript (¡Eeek!)
  • Escribir pantalla de video, material de generación de sonido.

Pero si aún no eres muy experto en esas cosas, ¡podría ver que cada una de esas viñetas toma un año!

Este es definitivamente el tipo de cosas “Si tienes que hacer la pregunta, no puedes hacerlo”.

Escribiré esta respuesta asumiendo que la palabra “desde cero” en realidad no significa nada. Eso sería prácticamente imposible de lograr con el tiempo, el conocimiento y muchos otros factores necesarios para lograrlo.

Dicho esto, le sugiero que comience utilizando las bibliotecas disponibles:

  1. Motor de diseño web
  2. Motor de JavaScript
  3. UI Toolkit

En la mayoría de los casos, 1 y 2 están agrupados. La alternativa realmente probada que conozco hasta ahora es Mozilla Gecko y Chromium’s Blink. Después de eso, necesitará un kit de herramientas para ayudarlo a crear componentes de la interfaz de usuario como Menús, Barras de herramientas, Diálogos, etc. Puede escribir código directamente en la plataforma del sistema operativo subyacente como Cocoa para OSX, Win32API para Windows o GTK / KDE para Linux.

Le sugiero que obtenga un kit de herramientas de desarrollo multiplataforma como wxWidgets y QT. (Sesgada) le sugiero que eche un vistazo a wxWidgets. Es posible que necesite bibliotecas como libcurl para crear administradores de descargas confiables. Las bibliotecas Poco / Boost también pueden ser beneficiosas en algún momento.

Ayudé a escribir un navegador web muy temprano en C ++, basado en la biblioteca wwwlib de Tim Berners Lee (creo que ese era el nombre). Esa biblioteca era solo de línea de comandos, y escribimos un contenedor de C ++ usando la biblioteca de Microsoft Foundation Class.

A veces me jacto de haber cambiado el código escrito por Lee y Marc Andreessen, quien contribuyó al código de Lee.

Unos años más tarde, cuando me estaba preparando para una entrevista para un puesto de desarrollador de MFC, codifiqué un navegador simple como un proyecto de demostración para la entrevista que podría mostrar un subconjunto de HTML 1.1. Conseguí el trabajo.

En esencia, un navegador web es solo un gran analizador. Aliméntelo con un marcado html y, a medida que los objetos salgan del analizador, haga su mejor esfuerzo para representarlos de una manera que tenga sentido para el usuario.

Conceptualmente no son difíciles, pero dado el monstruoso conjunto de marcas que los navegadores modernos tienen que enfrentar, puede ver por qué se necesitan equipos de cientos de personas para mantener los principales navegadores del mundo.

Después de leer algunas respuestas, me volveré un poco meta en esto:

Mucha gente te dirá que te rindas. No tienes ninguna posibilidad de todos modos, etc.

Haré lo contrario. Yo digo, ¡adelante! Claro, con toda probabilidad no tendrá “éxito” en el sentido de terminar con un producto útil y comercializable a la par con Chrome.

Pero, hombre, ¡las lecciones que aprenderás en el camino! Definitivamente serás un mejor programador al final de esto.

Trabajo en codificación (obviamente), y codifico mucho los fines de semana, solo por diversión. Comencé una gran cantidad de proyectos de fin de semana, solo uno de los cuales (¡UNO!) Está en un estado utilizable, y solo yo lo estoy usando. Pero aún así, no me gustaría perder ninguno de ellos. Ahí es donde puedo probar cosas nuevas, divertirme, inspirarme y mi trabajo diario definitivamente se beneficia de ello.

Tu solo ? Sin ninguna ayuda de bibliotecas de terceros? Eso te llevaría décadas hacer eso.

Antes de decir algo alentador, primero intente leer, comprender completamente e implementar los siguientes contenidos, ya que son el paso más básico para su navegación web: establecer una conexión con el servidor.

Protocolo de transferencia de hipertexto – HTTP / 1.1

RFC 2818 – HTTP sobre TLS

El protocolo Secure Sockets Layer (SSL) Versión 3.0

El protocolo de seguridad de la capa de transporte (TLS) versión 1.2

Protocolo Diffie-Hellman

Algoritmo de hashing seguro

El algoritmo de resumen de mensaje MD5

Infraestructura X.509

¿Todavía quieres continuar?

Envuelve una biblioteca como WebKit en una interfaz de usuario y usa algo como la biblioteca de Chrome Networking para conectarla a la red. El resultado final será algo así como el navegador Steam en el juego. Hay muchas opciones para cada una de las bibliotecas requeridas, y bastante plomería, pero este es un proyecto individual factible.

Si quiere decir, cómo escribo WebKit, la respuesta es que no, es un software en una escala que solo puede ser realizado por un gran equipo bien financiado con suficientes expertos adecuados. Varias de esas bibliotecas principales del navegador son de código abierto, por lo que puede contribuir si lo desea, y eso sería una buena educación en muchas facetas de la ingeniería de software.

No es tan difícil si tienes las bibliotecas adecuadas. Aquí, la respuesta de StackOverflow:

#include “as / SOCK_Connector.h”

int main (int argc, ACE_TCHAR * argv [])
{
// Encabezado de solicitud HTTP
char * szRequest = “GET /video/nice.mp4 HTTP / 1.1 \ r \ nHost: example.com \ r \ n \ r \ n”;
int ilen = strlen (szRequest);

// nuestro búfer
salida de caracteres [16 * 1024];

Servidor ACE_INET_Addr (80, “ejemplo.com”);
ACE_SOCK_Stream peer;
Conector ACE_SOCK_Connector;
int ires = connector.connect (par, servidor);
int suma = 0;
peer.send (szRequest, ilen);
mientras (cierto)
{
ACE_Time_Value timeout = ACE_Time_Value (15);
int rc = peer.recv_n (salida, 16 * 1024, y tiempo de espera);
si (rc == -1)
{
descanso;
}
suma + = rc;
}
peer.close ();
printf (“Bytes transferidos:% d”, suma);

devuelve 0;
}

Aquí tienes, tienes un navegador web. Puede enviar solicitudes a los servidores y recibir un código html puro de ellos.

Con gran dificultad. El problema es que la cantidad de opciones para HTML válido en estos días es alucinante. Debe recibir el HTML / CSS / Javascript, analizarlo, mostrar correctamente el resultado. Año, posiblemente siglos de esfuerzo para un solo desarrollador.

Incluyendo kernel?
Es fácil, todo lo que necesita es tiempo y una buena comprensión de un poco más que solo C ++, esto no será suficiente.

Desglose por idiomas.

  1. C ++ : 1,650,784 líneas, 7,264 archivos.
  2. C – 1,119,835 líneas, 2,007 archivos
  3. Encabezados C / C ++ : 719,761 líneas, 7,902 archivos
  4. HTML : 384,433 líneas, 1,899 archivos.
  5. Bourne Shell – 157,373 líneas, 159 archivos.
  6. Javascript : 145,717 líneas, 710 archivos.
  7. Python – 105,418 líneas, 704 archivos.
  8. XML : 43.214 líneas, 74 archivos.
  9. m4 – 43,201 líneas, 49 archivos.
  10. Ensamblaje : 41,285 líneas, 28 archivos.
  11. Perl – 17.368 líneas, 25 archivos.
  12. CSS : 14,650 líneas, 154 archivos.
  13. hacer – 13,300 líneas, 143 archivos.
  14. IDL – 10,453 líneas, 69 archivos.
  15. Tcl / Tk – 6,969 líneas, 36 archivos.
  16. yacc – 4,786 líneas, 3 archivos.
  17. Objetivo C : 2.811 líneas, 32 archivos.
  18. Teamcenter def – 2,802 líneas, 17 archivos.
  19. PHP – 1,475 líneas, 5 archivos.
  20. C # – 1,226 líneas, 11 archivos.
  21. Bourne Again Shell – 767 líneas, 12 archivos.
  22. lex – 633 líneas, 2 archivos.
  23. SQL : 556 líneas, 20 archivos.
  24. XSLT – 324 líneas, 3 archivos.
  25. awk – 253 líneas, 6 archivos.
  26. Lote DOS – 252 líneas, 15 archivos.
  27. Java – 166 líneas, 2 archivos.
  28. Ir – 150 líneas, 1 archivo.
  29. sed – 134 líneas, 3 archivos.
  30. Lisp – 120 líneas, 2 archivos.
  31. DTD – 116 líneas, 2 archivos.
  32. Scripts de MSBuild : 100 líneas, 1 archivo.
  33. YAML – 36 líneas, 5 archivos.
  34. Ruby – 15 líneas, 1 archivo.
  35. Vim Scripts – 5 líneas, 1 archivo.

Tómate un café y pon en marcha ese IDE. Esperamos con ansias la prueba de ritmo en 2184.

Como otros han señalado, completamente inviable.

Pero Windows, Mac, Android, iOS tienen clases existentes de “navegador web” que proporcionan la funcionalidad principal para los navegadores web.

Necesitaría una muy, muy buena razón para reemplazar una línea de código (para iniciar un nuevo navegador) con un millón de líneas de código (para implementar un navegador web desde cero).

En primer lugar, ¿por qué lo harías? Los navegadores web son una muy sofisticada tranquilidad de software. Necesitan poseer muchas cosas. Motor de renderizado, para reconocer los tráficos entrantes, deben ser extensibles, deben ser compatibles con JavaScript.

Hay componentes de navegador web en c ++ de RAD y creo que visual C ++ también lo tiene … pero si quieres escribirlo desde cero … simplemente no lo intentes. 🙂

Claro que puedes, pero es realmente una gran cantidad de trabajo.