COLUMNA: Agora imos de mergullo no código de distribución
e ter un ollar para o contexto en que o código que escribe
estará en funcionamento.
Ao final do día, está indo a aplicar
a totalidade do servidor web.
Pero nós fornecen Lo co esqueleto
código que ten algunhas funcións, particularmente relacionadas coa rede.
Imos dar un ollo.
>> Entón, aquí enriba cara arriba do ficheiro é unha banda
de recurso de proba requisitos macro.
Agora, esta é só unha característica c, segundo o cal segundo unha morea de páxinas man
tes que definir algúns dos esas constantes para ser verdade
ou ser incluso números específicos, para que ten acceso a determinadas funcións.
Se non, eles serán non declarado e non terá acceso.
Entón eu fixen iso por medio ler as páxinas do manual.
Agora alí en baixo, na liñas 15 a 17, nos
ten unha morea de límites declarados.
>> E nós temos prestado estes a partir dun servidor web popular chamado Apache.
E estes son só números que van
para limitar o número total de bytes que se permiten
en varios contextos para a solicitude HTTP que un navegador se admite para me enviar.
Logo definimos octetos.
Agora, un octeto é só un xeito elegante de dicir un byte, ou oito bits.
Acontece que no pasado un byte non era necesariamente oito bits,
así octeto é sempre oito bits.
Polo tanto, neste caso adoptado o que é común na rede
mundo de chamar oito bytes un octeto.
>> Aquí eu especifiquei que vai octetos ser 512, de xeito que moi parecido en medicina forense
cando lemos unha morea de bytes de cada vez, tamén aquí,
imos ler un banda de octetos de cada vez.
Axiña unha morea de arquivos de cabeceira.
Como eu sabía para incluír estes?
Ben, eu simplemente ler o home páxinas a un número de funcións
que imos usar neste distribución código e inclúen aqueles en
Fun instruído a.
>> E agora temos un tipo de datos.
Temos declarou un octeto de ser un char.
E nós veremos máis tarde que iso é utilizado ao longo do código.
E nós temos declarado todo grupo de prototipos,
e imos camiñar rapidamente a través cada unha destas funcións.
Por último, e quizais o máis importante ter en
mente neste momento no a historia, é que non
son, en realidade, un conxunto grupo de variables globais
na parte superior do ficheiro, raíz, CFD, SFD, solicitude, arquivo e corpo.
>> Agora, xeralmente, utilizando tantos mundial variables ou variables globais en todo,
Non é a práctica de volta.
Pero acontece tamén estamos usando un técnica chamada de manipulación de sinal máis tarde
no código, o que nos permite detectar cando o usuario chega algo
como CTRL C e desactivar o servidor graciosamente.
E, para facelo correctamente e, en realidade, liberar memoria,
necesitamos ter acceso a estas variables globais.
>> E agora imos dar un ollo ao principal, que impulsa a totalidade deste programa.
En primeiro lugar, no alto aquí ter un número variable de erro
que parece non ter un tipo, pero iso é
porque é realmente definida nun ficheiro chamado
erro errno.h que está incluído máis arriba.
Se fai o home errno para realmente ver a definición de tal cousa,
vai ver que este é un variable global especial que
defínese por un grupo enteiro de funcións non escrita
por nós, pero polos autores do Linux e outros sistemas para realmente definir
un número para esa variable cando algo sae mal, para que poida globalmente
descubrir o que deu errado.
>> Agora, debaixo verá unha nova técnica quizais usando getopt,
unha función que axuda mando parse Argumentos da liña de xeito que non facer
ten que preocuparse en perder tempo imaxinando como analizar algo como 8080,
ou trazo p, ou trazo h para obter axuda.
getopt esencialmente fai iso por nós.
Consulte a páxina de manual para máis.
>> A continuación, facer un pouco de erro verificación para asegurarse de
que o número de porto está dentro o intervalo especificado no spec.
Logo vemos unha chamada á función comezar, cuxa definición imos
mirar nun momento, e como o seu nome suxire, este inicia o servidor web.
Aquí temos unha chamada a unha función chamado de sinal que di:
se e cando escoitar Control C do teclado do usuario, dalle chamar
un manipulador función chamada que está pasando cousas para, finalmente, limpar e deixar
o servidor.
>> Abaixo que é o que parece ser un ciclo infinito, a primeira liña das cales
efectivamente é unha chamada a unha función chamada
axustar, que nós mesmos aplicar, máis tarde, a fin
para liberar algúns dos nosos estados globais.
Despois que é unha liña de código que condicional
está comprobando o retorno valor do contacto.
Agora looks conectados como un predicado, algo que retorna verdadeiro ou falso.
E fai, pero non hai algo especial en conectado
na medida en que é unha chamada de bloqueo.
Vai sentir alí e esperar ata que o navegador do usuario
tenta conectarse a este web servidor e só entón el
volver verdadeiro ou falso, para que poidamos continuar cara ao interior deste if.
>> Unha vez alí, observe esta función a un función chamada de análise, o que escribimos,
que analiza todo octetos, todo dos bytes procedentes dun navegador
ao servidor, para que poidamos entregar Lo de volta, en definitiva o valor para outro
desas variables globais que tendas de todo bytes en só
cabeceiras de que solicitude, non o corpo
se non houbese un corpo realmente a el.
>> Agora baixo comezamos a analizar estes cabezallos para extraer
un subconxunto da información que nos preocupa.
En concreto, o per especificación, primeiro
quería pedir liña, que é só que moito primeira liña que
espero que di algo así como get cortar ou algún camiño e, a continuación, HTTP 1.1.
Estamos a usar esa metáfora dunha agulla nun palheiro
buscar especial caracteres ou enderezos.
E, de feito, hai un número de funcións no noso código de distribución
que, ademais, poden ser útiles cando se mira para valores particulares.
>> En definitiva, nós copiar estes bytes nunha liña variable chamada,
que notar, tamén, temos alocados na pila
por medio dunha matriz Deseñada de forma dinámica.
E nós estamos tentando deliberadamente para evitar chamar malloc
porque de novo, porque Control de C sendo
unha característica potencial deste programa, non quero ter ese código de súpeto
interrompida polo bater do usuario Control C, o resultado dos cales
é que eu non podería ter unha oportunidade de balde algo que malloced.
Entón eu estou tentando utilizar a mesma cantidade da pila é que podo aquí.
>> A continuación, un grupo enteiro de para dos.
A especificación pode expoñer o que se espera aquí,
pero os comentarios danlle unha información do que está por vir.
Vostede primeiro que validar a liña de solicitude
e asegúrese de que el se parece o especificacións gramática, por así dicir,
di que debería.
Logo cómpre extraer algo chamado a consulta, o material para fóra
tras un signo de interrogación, como vimos co noso exemplo Google
de paso nun parámetro de HD.
Nós entón concatenar xuntos a raíz do servidor web
co camiño que está que a primeira liña de solicitude
e formar a ruta completa o ficheiro que quere buscar.
>> Despois diso, imos estar seguro se o ficheiro existe e é lexible.
E entón nós estamos indo a extraer o seu extensión de arquivo, o .html ou o .PHP,
ou algunha extensión que está no final da cadea solicitado.
Logo é un todo chea de código que escribimos
para xerar efecto PHP contido xerado por ti.
En poucas palabras, este código leva o nome
do ficheiro que desexa PHP para interpretar.
Nós pasalo por algo chamado un tubo en intérprete de PHP.
Volva resposta como se a resposta fose ela mesma un arquivo.
E, entón, interactuar sobre o ficheiro de bytes, tirando-los todos nun buffer
para que poidamos, en última instancia imprimir-las.
>> Efectivamente, todos estes chama aquí a dprintf
nos permite imprimir algo chamado un descritor de ficheiro, o que
é só un número enteiro que representa un ficheiro.
Moi semellante en espírito, pero fundamentalmente diferente dun ficheiro
punteiro estrela.
Observe como pode usar a sintaxe como printf aquí para que eu poida dinamicamente
inserir algo como a lonxitude ao valor dun cabeceira HTTP
chamado Content-Length.
E, finalmente, eu usei o dereito de realmente escribir función
o corpo da solicitude.
>> Desafortunadamente, só aplicado soporte para dinamicamente
arquivos PHP xerada.
Non aplicar o soporte para arquivos estáticos, como gifs, e JPEG
e arquivos CSS e HTML.
Isto, por desgraza, é deixarse ​​para ti para responder ao obxectivo cliente
esta a facer.
Entón, alí vai descubrir que non hai non moita inspiración dentro dese bloque,
pero se un pouco máis arriba coa forma como nós fomos sobre a interpretación do código PHP,
as funcións que vai empregar son un pouco diferentes.
>> De feito, pode pedir algunhas das características
quizais a partir dos forense conxunto de problemas, porque
ao final do día todo o que necesitas facer aquí é cando vostede sabe que abrir o ficheiro
e unha vez que sabe que se chama Tipo MIME ou tipo de contido,
ten que ler neses bytes e dalgunha forma cuspi-los de volta para fóra.
>> E agora un tour por esta outras funcións do arquivo.
Ata primeiro está conectado, que simplemente retorna true
cando finalmente escoita un conexión desde un usuario.
Logo é erro.
Erro, á súa vez, como unha función que escribiu para tratar con todas as diferentes 400
eo estado de HTTP 500 códigos que pode querer
para enviar de volta para o usuario, xunto cunha mensaxe estándar.
>> A continuación é a carga, especialmente función de carne, cuxo propósito na vida
é para ler dunha estrela do punteiro do ficheiro do contido dun ficheiro nun buffer mundial
que declarou a nivel mundial arriba [? principal. ?]
Este é un pouco complexo, porque nós ten que ler os bytes do ficheiro
pero comprobar en cada iteración se nós xa
alcanzou o fin do ficheiro ou outra cousa deu mal.
E usamos realloc para asegurarse de que calquera que sexa tapón Utilizamos está crecendo
e crecendo e crecendo e sempre quedando á fronte do número de bytes
que necesitamos para caber dentro.
Handler, con todo, é a función que recibe
chamado por medio de ter Control C rexistrado como un sinal
que queremos interceptar.
Observe aquí no manipulador que, en definitiva
chamadas de parar, o que naturalmente para o servidor web.
E, por desgraza, lookup non está implementado.
En espírito, este é un función moi sinxelo.
Dada a extensión do ficheiro, el que devolve-lo está o chamado MIME
tipo ou tipo de contido.
E nós especificar na especificación o que este cartografía debe ser.
Pero ten que traducir en definitiva, ao código c.
>> A continuación é a nosa función semellante de carne chamado de análise, cuxo propósito na vida
é ler, non a partir dun ficheiro, pero desde unha conexión de rede.
En concreto, a lectura e análise Solicitude HTTP que está vindo dun navegador
ao servidor de xeito que en definitiva, podemos analizar
con só as cabeceiras na solicitude liña e volver aqueles para ti
por medio dunha memoria temporal global que declaramos riba [? principal. ?]
>> Reset, con todo, é un función que definimos
que se chama de forma iterativa dentro do principal cada vez que está a piques
listo para comezar a escoitar para unha nova conexión
de xeito que sempre sabemos o estado das nosas variables
e para que nós tamén liberou calquera memoria que
pode ser asignado para unha conexión de rede anterior.
Axiña iníciase, o función que escribimos
que contén un conxunto chea de código de rede
que finalmente inicia o servidor web.
>> Última up é a función chamado stop, que
fai exactamente iso, para o servidor web.
Pero, primeiro, el libera calquera memoria que aínda se asignado.
Pero, en definitiva chama exit sen tan sequera voltar o control
a nosa función principal.
En definitiva, un dos a maioría das técnicas importantes
ao aplicar este servidor web é vai ser un pouco de intento e erro,
ter un navegador xanela aberta á dereita e unha fiestra de terminal en
á esquerda, a consola de servidores fiestra, de xeito que
pode ver as mensaxes que son sendo presentada na pantalla.
>> Pero mellor aínda sería un terceiro fiestra, unha fiestra segundo terminal,
en que usa o Telnet, o uso para o cal está prescrito no spec.
E Telnet é só un moi programa de rede sinxelo
que permite que finxir ser un navegador dunha fiestra
mentres conversaba coa outra xanela.
Desta forma, podes ver exactamente as ordes textuais
que están volvendo do servidor ao cliente
sen ter de desentullo en torno a creador de Chrome
ferramentas en outra forma Interface clunkier.