SPEAKER: Ora diamo immersione nel codice di distribuzione
e dare un'occhiata al contesto in cui il codice si scrive
sta per essere operativo.
Alla fine della giornata, si sta andando a implementare
la totalità del server web.
Ma abbiamo fornito con lo scheletro
codice che hanno alcune funzionalità, soprattutto relative al networking.
Diamo uno sguardo.
>> Così qui verso l'alto del file è un po '
di funzionalità di testare requisiti macro.
Ora, questo è solo una caratteristica di c, per cui secondo un gruppo di pagine man
è necessario definire alcuni dei queste costanti per essere vero
o di essere addirittura numeri specifici in modo che si ha accesso a determinate funzioni.
In caso contrario, essi saranno SOMMERSO e non avrete accesso.
Quindi ho fatto questo titolo di leggere le pagine di manuale.
Ora in basso, in linee 15 a 17, si
hanno un sacco di limiti dichiarati.
>> E abbiamo preso in prestito questi da un popolare web server chiamato Apache.
E questi sono solo numeri che sono in corso
di limitare il numero totale di byte che sono ammessi
in vari contesti della richiesta HTTP che un browser può inviare me.
Avanti, definiamo ottetti.
Ora un ottetto è solo un modo di fantasia di dire un byte, o otto bit.
Risulta in passato un byte non era necessariamente otto bit,
così ottetto è sempre otto bit.
Quindi, in questo caso, abbiamo adottato ciò che è comune nella rete
mondo di chiamare otto byte un ottetto.
>> Qui ho specificato che sarà ottetti essere 512, in modo che tanto come in medicina legale
quando leggiamo un gruppo di byte alla volta, anche qui,
stiamo andando a leggere un mazzo di ottetti alla volta.
Avanti tutta una serie di file di intestazione.
Come facevo a sapere di includere questi?
Beh ho semplicemente letto l'uomo pagine per un certo numero di funzioni
che useremo in questa distribuzione codice e include in quelli
Sono stato incaricato di.
>> E ora abbiamo un tipo di dati.
Abbiamo dichiarato un ottetto di essere un char.
E vedremo in seguito che questo è utilizzato in tutto il codice.
E abbiamo dichiarato un tutta una serie di prototipi,
e noi cammineremo rapidamente attraverso ciascuna di queste funzioni.
Infine, e forse più importante tenere a
mente a questo punto la storia, è che non c'è
sono, infatti un intero gruppo di variabili globali
nella parte superiore del file, radice, CFD, SFD, richiesta, di file e il corpo.
>> Ora in generale, con tanti globale variabili o variabili globali a tutti,
non è la pratica di nuovo.
Ma si scopre che stiamo utilizzando anche un tecnica chiamata gestione del segnale più tardi
nel codice, che ci permette di rilevare quando l'utente preme qualcosa
come CTRL C e si spegnerà il server con grazia.
E per farlo con grazia e in realtà liberare memoria,
abbiamo bisogno di avere accesso a queste variabili globali.
>> E ora diamo uno sguardo al principale, che spinge l'interezza di questo programma.
Innanzitutto, nella parte superiore qui avere un numero variabile di errore
che appare di non avere un tipo, ma questo è
perché in realtà è definito in un file chiamato
errore che errno.h è incluso più in alto.
Se fate uomo errno effettivamente vedi la definizione per questa cosa,
vedrete che questo è un speciale variabile globale che
è impostato per un intero gruppo di funzioni non scritta
da noi, ma da Linux autori e altri sistemi per impostare effettivamente
un numero di variabili che quando qualcosa va storto in modo che possiate globale
capire cosa ha fatto andare storto.
>> Ora in basso vedrete una nuova tecnica magari utilizzando getopt,
una funzione che aiuta il comando parse gli argomenti della riga in modo che non facciamo
devono preoccuparsi perdite di tempo per capire come analizzare qualcosa come 8080,
o un trattino p, o trattino h per ottenere aiuto.
getopt fa in sostanza, che per noi.
Vedere la pagina man di più.
>> Avanti, facciamo un po 'di errore controllo per assicurarsi che
che il numero di porta è entro l'intervallo specificato nelle specifiche.
Successivamente, vediamo una chiamata alla funzione avviare, la cui definizione ti
guardare in un momento, e come il suo nome suggerisce, questo avvia il server web.
Qui abbiamo una chiamata a una funzione chiamato segnale che dice:
se e quando si sente di controllo C da la tastiera dell'utente, andare avanti e chiamare
un gestore funzione chiamata che sta andando cose da pulire definitiva e smettere
il server.
>> Sotto questo è quello che sembra essere un loop infinito, la prima linea di cui
effettivamente è una chiamata ad una funzione chiamata
reset, che ci siamo implementare successivamente per
per liberare alcuni dei nostri stati globali.
Dopo che è una linea di codice condizionale
sta controllando il ritorno valore collegato.
Ora sembra collegati come un predicato, qualcosa che restituisce vero o falso.
E lo fa, ma non c'è qualcosa di speciale in collegato
in che si tratta di una chiamata di blocco.
Si siederà lì e aspettare fino browser di un utente
tenta di connettersi a questo sito web server e solo allora sarà vero
restituire true o false in modo che si proceda all'interno di questo if.
>> Una volta lì, notare questa funzione per un funzione chiamata parse, che abbiamo scritto,
che analizza tutti gli ottetti, tutte dei byte provenienti da un browser
al server, in modo che si possa consegnare si torna in ultima analisi, un valore a uno
di queste variabili globali memorizza tutti i byte in proprio
le intestazioni di tale richiesta, non il corpo
se ci fosse effettivamente un corpo ad esso.
>> Ora in basso cominciamo a analizzare queste intestazioni per estrarre
un sottoinsieme delle informazioni che ci sta a cuore.
In particolare, per la specificazione, per prima
voluto richiedere la linea, che è solo che prima linea
speriamo che dice qualcosa come get tagliare o qualche percorso e quindi HTTP 1.1.
Stiamo utilizzando questa metafora di un ago in un pagliaio
cercare particolare caratteri o indirizzi.
E in effetti, c'è un certo numero di funzioni nel nostro codice di distribuzione
che anche voi, potrebbe trovare utile quando alla ricerca di valori particolari.
>> In ultima analisi, copiamo questi byte in una linea variabile chiamata,
che notiamo, troppo, abbiamo allocato sullo stack
per mezzo di una matrice di dimensioni dinamicamente.
E stiamo cercando deliberatamente per evitare di chiamare malloc
perché ancora una volta, perché di controllo C essere
una caratteristica potenzialità di questo programma, abbiamo non vogliono avere questo codice improvvisamente
interrotto dal colpire utente Controllo C, il cui risultato
è che potrei non avere una possibilità gratuitamente qualcosa che ho malloced.
Così sto cercando di utilizzare il più dello stack è che posso qui.
>> Next up, un intero gruppo di al dos.
La specifica sarà esporre esattamente quello che ci si aspetta qui,
ma i commenti che danno un accenno di quello che ci aspetta.
Innanzitutto è necessario convalidare la linea di richiesta
e assicurarsi che sembra che il specifiche grammatica, per così dire,
dice che dovrebbe.
È quindi necessario estrarre qualcosa chiamato la query, la roba
dopo un punto interrogativo, come abbiamo visto con il nostro esempio Google
di passaggio in un parametro HD.
Abbiamo poi concateniamo insieme la radice del server web
con il percorso che è in tale richiesta prima linea
e formare il percorso completo il file che vogliamo cercare.
>> In seguito, stiamo andando a fare in modo che il file esiste ed è leggibile.
E poi andremo a estrarne il estensione del file, .html o .php,
o qualche tale estensione che è alla molto fine della stringa richiesto.
Next up è un intero mucchio di codice che abbiamo scritto
di generare realmente PHP generated content per voi.
In poche parole, questo codice prende il nome
del file che si desidera PHP interpreti.
Noi passiamo da qualcosa chiamato un tubo in interprete di PHP.
Tornate la risposta, come se la risposta fosse un file stesso.
E poi iterare su tale file di byte, li tirano in un buffer
in modo che possiamo in definitiva stamparli.
>> Infatti, tutti questi chiamate qui per dprintf
ci permette di stampare qualcosa chiamato un descrittore di file, che
è solo un numero intero che rappresenta un file.
Molto simile nello spirito, ma fondamentalmente diverso da un file
puntatore stella.
Notate come è possibile utilizzare la sintassi come printf qui in modo che io possa dinamicamente
Inserire qualcosa come la lunghezza per il valore di un'intestazione HTTP
chiamato Content-Length.
E alla fine ho usato il Funzione diritto effettivamente scrivere
il corpo alla richiesta.
>> Purtroppo, abbiamo implementato solo Supporto per dinamicamente
file PHP generati.
Noi non implementare il supporto per file statici come GIF e JPEG,
e file CSS e HTML.
Questo, purtroppo, è lasciato a voi per rispondere allo scopo client
questo per fare.
Così in là troverete che non c'è non molto ispirazione all'interno di tale blocco,
ma se un po 'più in alto di quanto siamo andati su interpretare codice PHP,
le funzioni che useranno sono un po 'diverso.
>> In realtà, si può prendere in prestito alcune delle funzionalità
forse dalle forensics set problema, perché
alla fine della giornata tutto ciò che serve a fare qui è una volta di sapere cosa file aperto
e una volta che sai che è la cosiddetta Tipo MIME o tipo di contenuto,
avete bisogno di leggere in quei byte e in qualche modo li sputare indietro.
>> Ed ora un tour di questa altre funzioni del file.
Fino primo è collegato, che restituisce semplicemente true
quando finalmente sente un connessione da un utente.
Next up è errore.
Errore, nel frattempo, in funzione abbiamo ha scritto per gestire tutte le diverse 400
e lo stato HTTP 500 codici che si potrebbe desiderare
rispedire per l'utente, insieme con un messaggio standard.
>> Next up è carico, un particolare funzione carnosa, il cui scopo nella vita
è quello di leggere da una stella di file puntatore del contenuto di un file in un buffer globale
che abbiamo dichiarato a livello globale sopra [? principale. ?]
Questo è un po 'complessa, perché ci devono leggere i byte dal file
ma controllare ogni iterazione se abbiamo già
colpire la fine del file o qualcosa è andato storto.
E usiamo realloc fare in modo che qualunque tampone che stiamo usando è in crescita
e in crescita e in crescita e sempre stare davanti il ​​numero di byte
che abbiamo bisogno di adattarsi in là.
Handler, nel frattempo, è la funzione che ottiene
chiamato dal modo di avere registrati controllo C come segnale
che vogliamo intercettare.
Si noti qui in gestore che in ultima analisi,
chiamate fermano, che naturalmente arresta il server web.
E purtroppo, ricerca non è implementata.
Nello spirito, questo è un funzione abbastanza semplice.
Dato un estensione del file, è necessario per tornare è la cosiddetta MIME
tipo o tipo di contenuto.
E si precisa nella specifica cosa che la mappatura deve essere.
Ma è necessario tradurre in ultima analisi, il codice c.
>> Next up è la nostra funzione in modo simile carnosa chiamato parse, il cui scopo nella vita
è da leggere, non da un file, ma da una connessione di rete.
Lettura, particolare e l'analisi del Richiesta HTTP che è venuto da un browser
al server in modo che in ultima analisi, siamo in grado di analizzare
a soli le intestazioni nella richiesta linea e tornare quelli di voi
per mezzo di un buffer globale abbiamo dichiarato in precedenza [? principale. ?]
>> Reset, nel frattempo, è un funzione che definiamo
che viene chiamato iterativamente dentro di principale ogni volta che si sta
pronto per iniziare ad ascoltare per una nuova connessione
in modo che sappiamo sempre lo stato delle nostre variabili
e così che abbiamo anche liberata alcuna memoria
potrebbe essere stato assegnato per una connessione di rete precedente.
Il prossimo è avviare, il funzione che abbiamo scritto
che contiene un intero sacco di codice di rete
che inizia alla fine il server web.
>> Ultimo up è la funzione chiamato stop, che
fa esattamente questo, arresta il server web.
Ma prima si libera la memoria che ancora è stato assegnato.
Ma si chiede in definitiva uscita senza nemmeno restituire il controllo
la nostra funzione principale.
Infine, uno degli la maggior parte delle tecniche importanti
in sede di attuazione questo server web è sarà un po 'di tentativi ed errori,
avere una finestra aperta del browser a destra e una finestra terminale
a sinistra, la console server finestra, in modo che
può vedere i messaggi che sono la visualizzazione sullo schermo.
>> Ma meglio ancora sarebbe un terzo finestra, una seconda finestra terminale,
in cui si usa Telnet, l'uso per i quali è prescritto nelle specifiche.
E Telnet è solo un semplice programma di rete
che consente di far finta di essere un browser in una finestra
mentre parlando l'altra finestra.
In questo modo si può vedere esattamente i comandi testuali
che stanno tornando dal server al client
senza dover frugare intorno sviluppatore di Chrome
utensili in un altrimenti clunkier interfaccia.