ALTAVOZ: Ahora vamos a bucear en el código de distribución
y echar un vistazo en el contexto en el que el código que escribir
que se va a operar.
Al final del día, usted va a poner en práctica
la totalidad del servidor web.
Pero hemos proporcionado que con el esqueleto
código que tiene algunas funciones, particularmente en relación con la creación de redes.
Vamos a echar un vistazo.
>> Así que aquí hacia la parte superior del fichero es un manojo
de la función de probar los requisitos de macro.
Ahora bien, esto es sólo una característica de c, según el cual de acuerdo con un montón de páginas de manual
usted tiene que definir algunas de estas constantes para ser verdad
o ser incluso números específicos de manera que usted tiene acceso a ciertas funciones.
De lo contrario van a ser no declarada y usted no tendrá acceso.
Así que he hecho esto por medio de la lectura de las páginas de manual.
Ahora abajo, en las líneas 15 y 17, que
tienen un montón de límites declarados.
>> Y hemos prestado estos de una servidor web popular llamado Apache.
Y estos son sólo números que se va
para limitar el número total de bytes que se permite
en los diversos contextos de la petición HTTP que se permite a un navegador de enviarme.
A continuación, definimos octetos.
Ahora un octeto es sólo una forma elegante de decir un byte, u ocho bits.
Resulta que en antaño un byte no era necesariamente ocho bits
de modo octeto es siempre ocho bits.
Así que en este caso hemos adoptado lo que es común en la red
mundo de llamar a ocho bytes de un octeto.
>> Aquí he especificado que octetos voluntad ser de 512, por lo que al igual que en el análisis forense
cuando leemos un montón de bytes a la vez, también en este caso,
vamos a leer un manojo de octetos a la vez.
Siguiente un montón de archivos de cabecera.
¿Cómo sé que incluya estos?
Bueno, yo simplemente leí el hombre páginas para un número de funciones
que vamos a utilizar en esta distribución código e incluir en los
Me dio instrucciones para.
>> Y ahora tenemos un tipo de datos.
Hemos declarado un octeto para ser un char.
Y veremos más adelante que eso es utilizado en todo el código.
Y hemos declarado una manojo entero de prototipos,
y vamos a caminar rápidamente por cada una de esas funciones.
Por último, y quizás lo más importante tener en
la mente en este momento de la historia, es que no
son, de hecho su conjunto montón de variables globales
en la parte superior del archivo, raíz, CFD, SFD, solicitud, archivo y el cuerpo.
>> Ahora generalmente, utilizando tantos mundial variables o variables globales en absoluto,
no es la práctica de nuevo.
Pero resulta que también estamos utilizando un técnica llamada manejo de señales más tarde
en el código, lo que nos permite detectar cuando el usuario pulsa algo
como CTRL C y se cerrará el servidor con gracia.
Y con el fin de hacer eso con gracia y en realidad liberar memoria,
necesitamos tener acceso a estas variables globales.
>> Y ahora vamos a echar un vistazo a principal, que impulsa la totalidad de este programa.
En primer lugar, en la parte superior aquí tener una variable de número de error
que parece no tener un tipo, pero eso es
porque en realidad definido en un archivo llamado
errno.h error que se incluye más arriba.
Si lo hace el hombre errno a realidad véase la definición de esta cosa,
verás que se trata de un variable global especial que
es fijado por un manojo entero de funciones no escrita
por nosotros, sino por los autores de Linux y otros sistemas para establecer realmente
un número a esa variable cuando algo va mal, para que pueda a nivel mundial
averiguar lo que salió mal.
>> Ahora abajo verás una nueva técnica tal vez usando getopt,
una función que ayuda comando de análisis sintáctico argumentos de la línea para que no nos hacemos
tiene que preocuparse de perder el tiempo pensando la manera de analizar algo así como 8080,
o un guión p, o un guión h para obtener ayuda.
getopt básicamente hace que para nosotros.
Consulte la página de manual para más.
>> A continuación, hacemos un poco de error comprobación para asegurarse de
que el número de puerto está dentro del rango especificado en la especificación.
A continuación, vemos una llamada a la función iniciar, cuya definición nos va
mira en un momento, y como su nombre sugiere, este inicia el servidor web.
Aquí tenemos una llamada a una función llama señal que dice:
siempre y cuando escuche Control C de teclado del usuario, siga adelante y llame
un controlador de función llamada que está pasando lo que en última instancia, limpias y dejar de
el servidor.
>> Debajo de eso es lo que parece ser un bucle infinito, la primera línea de los cuales
efectivamente es una llamada a una función llamada
restablecer, que nosotros mismos aplicar más adelante con el fin
para liberar a algunos de nuestros estados globales.
Después de que es una línea de código que condicionalmente
está comprobando el retorno valor de conectado.
Miradas Ahora conectados como un predicado, algo que devuelve verdadero o falso.
Y lo hace, pero hay algo especial en conectado
en que se trata de una llamada de bloqueo.
Será sentarse allí y esperar hasta que el navegador del usuario
intenta conectarse a esta web servidor y sólo entonces será
return true o false para que procedamos en el interior de esta sentencia if.
>> Una vez allí, observe esta función a un función llamada de análisis, lo que escribimos,
que analiza todos los octetos, todo de los bytes procedentes de un navegador
para el servidor, por lo que podemos entregar de vuelta en última instancia, un valor a uno
de esas variables globales que almacena todos los bytes en sólo
las cabeceras de ese solicitud, no el cuerpo
si no eran en realidad un cuerpo a la misma.
>> Ahora abajo comenzamos a analizar los encabezados para extraer
un subconjunto de la información que nos preocupamos.
Específicamente, por la especificación, nosotros primero
quería pedir línea, que es sólo que muy primera línea que
esperemos que dice algo así como get reducir o algún camino y luego HTTP 1.1.
Estamos utilizando esta metáfora de una aguja en un pajar
buscar en particular caracteres o direcciones.
Y de hecho, hay un número de funciones en nuestro código de distribución
que usted, también, puede ser que encuentre útil en la búsqueda de valores particulares.
>> En última instancia, copiamos estos bytes en una línea de variable llamada,
que notamos, también, tenemos asignado en la pila
por medio de una matriz de tamaño dinámico.
Y estamos tratando deliberadamente para evitar llamar a malloc
porque, de nuevo, porque de Control C siendo
una posible opción de este programa, no quiero tener este código de repente
interrumpido por los golpes de usuario Control C, el resultado de los cuales
es que yo no podría tener una oportunidad para algo gratis que he malloced.
Así que estoy tratando de usar tanto de la pila es lo que pueda aquí.
>> El siguiente, un montón de a dos.
La especificación expondrá exactamente lo que se espera aquí,
pero los comentarios que dan una pista de lo que está por venir.
Primero tiene que validar la línea de petición
y asegúrese de que parece que el especificaciones gramática, por así decirlo,
dice que debería.
A continuación, deberá extraer algo llamado la consulta, la materia hacia fuera
después de un signo de interrogación, como vimos con nuestro ejemplo Google
de pasada en un parámetro HD.
Luego se concatena juntos la raíz del servidor web
con la ruta que está en esa primera línea de petición
y formar la ruta completa el archivo que queremos buscar.
>> Después de eso, vamos a asegurarnos que el archivo existe y es legible.
Y luego vamos a extraer su extensión de archivo, los archivos .html o .php la,
o alguna extensión que está en el final de la cadena solicitada.
El siguiente es un todo montón de código que escribimos
para generar realmente PHP contenido para usted generado.
En pocas palabras, esta código toma en el nombre
del archivo que desea PHP interpretar.
Nosotros pasamos por algo llamado un tubo en el intérprete de PHP.
Vuelve la respuesta como si la respuesta fuera un archivo en sí mismo.
Y luego iteramos sobre ese archivo de bytes, tirando todos en un búfer
por lo que podemos en última instancia imprimirlos.
>> De hecho, todos estos pide aquí para dprintf
nos permite imprimir algo llamado un descriptor de archivo, que
es simplemente un entero que representa un archivo.
Muy similar en espíritu, pero fundamentalmente diferente de un archivo
indicador de la estrella.
Observe cómo se puede utilizar la sintaxis como printf aquí para que yo pueda dinámicamente
insertar algo así como la longitud por el valor de una cabecera HTTP
llamado Content-Length.
Y en última instancia, he utilizado la función derecho a escribir en realidad
el cuerpo de la solicitud.
>> Por desgracia, sólo implementamos soporte para dinámicamente
archivos PHP generados.
No nos implementamos apoyo a archivos estáticos como gifs y archivos JPEG,
y archivos CSS y HTML.
Eso, por desgracia, se deja a usted para responder a la finalidad cliente
esto que ver.
Así que allí usted encontrará que hay no mucho inspiración dentro de ese bloque,
pero si un poco más arriba de lo nos fuimos sobre la interpretación de código PHP,
las funciones que se van a usar son un poco diferentes.
>> De hecho, usted puede pedir prestado parte de la funcionalidad
tal vez de la medicina forense conjunto de problemas, porque
al final del día todo lo que necesita hacer aquí es una vez que sabes lo que abrir el archivo
y una vez que usted sabe que el llamado Tipo MIME o tipo de contenido,
usted necesita leer en esos bytes y de alguna manera ellos escupir de vuelta.
>> Y ahora un recorrido por este otras funciones de archivo.
Hasta se conecta primero, que simplemente devuelve true
cuando por fin se oye un la conexión de un usuario.
El siguiente es el error.
Error, por su parte, como una función que escribió para manejar todas las diferentes 400
y el estado HTTP 500 códigos que usted puede ser que desee
para enviar de nuevo al usuario, junto con un mensaje estándar.
>> El siguiente paso es la carga, un particular función carnoso, cuyo propósito en la vida
está a leer de una estrella archivo puntero del contenido de un archivo en una memoria intermedia mundial
que declaramos a nivel mundial por encima de [? principal. ?]
Esto es un poco compleja porque hay que leer los bytes del archivo
pero comprobar en cada iteración si ya hemos
golpear el final del archivo o algo ha ido mal.
Y utilizamos realloc para asegurarse de que cualquier búfer que estamos usando es cada vez mayor
y creciendo y creciendo y siempre mantenerse a la vanguardia de la cantidad de bytes
que tenemos que encajar allí.
Handler, por su parte, es la función que recibe
llamado por manera de tener Control C registrada como una señal de
que queremos interceptar.
Nótese aquí en handler que en última instancia
llamadas detienen, que por supuesto detiene el servidor web.
Y, por desgracia, de búsqueda no se ha implementado.
En espíritu, este es un función bastante simple.
Dada la extensión de archivo, necesita para volver está el llamado MIME
tipo o tipo de contenido.
Y se especifica en el pliego de condiciones lo que la cartografía debe ser.
Pero hay que traducir que en última instancia al código c.
>> El siguiente es nuestra función similar a carne denominado parse, cuyo propósito en la vida
es leer, no desde un archivo, pero a partir de una conexión de red.
En concreto, la lectura y análisis de la Petición HTTP que ha llegado desde un navegador
al servidor para que en última instancia, podemos analizar
a tan sólo los encabezados de la solicitud línea y volver a aquellos que
por medio de un tampón global que declaramos anteriormente [? principal. ?]
>> Cambiar, por su parte, es un función que definimos
que es llamada de forma iterativa el interior de principal cada vez que estás a punto
listo para empezar a escuchar para una nueva conexión
de manera que siempre sabemos el estado de nuestras variables
y por lo que hemos también liberado cualquier memoria que
podría haber sido asignado para una conexión de red anterior.
El siguiente paso es empezar, la función que escribimos
que contiene un conjunto gran cantidad de código de red
que en última instancia se inicia el servidor web.
>> Dura hasta es la función llamado parada, que
hace exactamente eso, detiene el servidor web.
Pero primero que libera cualquier memoria que aún se ha asignado.
Pero llama en última instancia de salida sin ni siquiera devolver el control
a nuestra función principal.
En última instancia, una de las la mayoría de las técnicas importantes
en la aplicación de este servidor web es va a ser un poco de ensayo y error,
tener un navegador ventana abierta a la derecha y una ventana de terminal en
izquierda, la consola de servidores ventana, de modo que usted
puede ver los mensajes que se encuentran que se muestra en la pantalla.
>> Pero mejor aún sería tercera ventana, una segunda ventana de terminal,
en el que se utiliza Telnet, el uso para los que se prescribe en la especificación.
Y Telnet es sólo una muy programa de red simple
que le permite a finges ser un navegador en una ventana
mientras habla con la otra ventana.
De esta manera usted puede ver exactamente los comandos textuales
que están regresando del servidor al cliente
sin tener que meter alrededor de desarrollador de Chrome
herramientas en una por lo demás interfaz clunkier.