1 00:00:00,000 --> 00:00:09,647 2 00:00:09,647 --> 00:00:11,730 SPEAKER: Ora diamo immersione nel codice di distribuzione 3 00:00:11,730 --> 00:00:14,470 e dare un'occhiata al contesto in cui il codice si scrive 4 00:00:14,470 --> 00:00:15,780 sta per essere operativo. 5 00:00:15,780 --> 00:00:17,350 Alla fine della giornata, si sta andando a implementare 6 00:00:17,350 --> 00:00:18,710 la totalità del server web. 7 00:00:18,710 --> 00:00:20,460 Ma abbiamo fornito con lo scheletro 8 00:00:20,460 --> 00:00:24,090 codice che hanno alcune funzionalità, soprattutto relative al networking. 9 00:00:24,090 --> 00:00:25,390 Diamo uno sguardo. 10 00:00:25,390 --> 00:00:27,560 >> Così qui verso l'alto del file è un po ' 11 00:00:27,560 --> 00:00:30,020 di funzionalità di testare requisiti macro. 12 00:00:30,020 --> 00:00:33,570 Ora, questo è solo una caratteristica di c, per cui secondo un gruppo di pagine man 13 00:00:33,570 --> 00:00:36,410 è necessario definire alcuni dei queste costanti per essere vero 14 00:00:36,410 --> 00:00:39,920 o di essere addirittura numeri specifici in modo che si ha accesso a determinate funzioni. 15 00:00:39,920 --> 00:00:42,470 In caso contrario, essi saranno SOMMERSO e non avrete accesso. 16 00:00:42,470 --> 00:00:45,340 Quindi ho fatto questo titolo di leggere le pagine di manuale. 17 00:00:45,340 --> 00:00:48,410 Ora in basso, in linee 15 a 17, si 18 00:00:48,410 --> 00:00:50,550 hanno un sacco di limiti dichiarati. 19 00:00:50,550 --> 00:00:53,370 >> E abbiamo preso in prestito questi da un popolare web server chiamato Apache. 20 00:00:53,370 --> 00:00:54,650 E questi sono solo numeri che sono in corso 21 00:00:54,650 --> 00:00:56,810 di limitare il numero totale di byte che sono ammessi 22 00:00:56,810 --> 00:01:01,930 in vari contesti della richiesta HTTP che un browser può inviare me. 23 00:01:01,930 --> 00:01:04,310 Avanti, definiamo ottetti. 24 00:01:04,310 --> 00:01:07,790 Ora un ottetto è solo un modo di fantasia di dire un byte, o otto bit. 25 00:01:07,790 --> 00:01:10,720 Risulta in passato un byte non era necessariamente otto bit, 26 00:01:10,720 --> 00:01:12,339 così ottetto è sempre otto bit. 27 00:01:12,339 --> 00:01:14,880 Quindi, in questo caso, abbiamo adottato ciò che è comune nella rete 28 00:01:14,880 --> 00:01:17,410 mondo di chiamare otto byte un ottetto. 29 00:01:17,410 --> 00:01:21,840 >> Qui ho specificato che sarà ottetti essere 512, in modo che tanto come in medicina legale 30 00:01:21,840 --> 00:01:24,170 quando leggiamo un gruppo di byte alla volta, anche qui, 31 00:01:24,170 --> 00:01:27,390 stiamo andando a leggere un mazzo di ottetti alla volta. 32 00:01:27,390 --> 00:01:28,922 Avanti tutta una serie di file di intestazione. 33 00:01:28,922 --> 00:01:30,255 Come facevo a sapere di includere questi? 34 00:01:30,255 --> 00:01:32,730 Beh ho semplicemente letto l'uomo pagine per un certo numero di funzioni 35 00:01:32,730 --> 00:01:35,620 che useremo in questa distribuzione codice e include in quelli 36 00:01:35,620 --> 00:01:37,390 Sono stato incaricato di. 37 00:01:37,390 --> 00:01:39,090 >> E ora abbiamo un tipo di dati. 38 00:01:39,090 --> 00:01:41,470 Abbiamo dichiarato un ottetto di essere un char. 39 00:01:41,470 --> 00:01:44,040 E vedremo in seguito che questo è utilizzato in tutto il codice. 40 00:01:44,040 --> 00:01:45,670 E abbiamo dichiarato un tutta una serie di prototipi, 41 00:01:45,670 --> 00:01:47,961 e noi cammineremo rapidamente attraverso ciascuna di queste funzioni. 42 00:01:47,961 --> 00:01:50,400 Infine, e forse più importante tenere a 43 00:01:50,400 --> 00:01:52,520 mente a questo punto la storia, è che non c'è 44 00:01:52,520 --> 00:01:54,520 sono, infatti un intero gruppo di variabili globali 45 00:01:54,520 --> 00:02:00,430 nella parte superiore del file, radice, CFD, SFD, richiesta, di file e il corpo. 46 00:02:00,430 --> 00:02:03,960 >> Ora in generale, con tanti globale variabili o variabili globali a tutti, 47 00:02:03,960 --> 00:02:05,280 non è la pratica di nuovo. 48 00:02:05,280 --> 00:02:09,090 Ma si scopre che stiamo utilizzando anche un tecnica chiamata gestione del segnale più tardi 49 00:02:09,090 --> 00:02:11,930 nel codice, che ci permette di rilevare quando l'utente preme qualcosa 50 00:02:11,930 --> 00:02:15,080 come CTRL C e si spegnerà il server con grazia. 51 00:02:15,080 --> 00:02:18,240 E per farlo con grazia e in realtà liberare memoria, 52 00:02:18,240 --> 00:02:20,800 abbiamo bisogno di avere accesso a queste variabili globali. 53 00:02:20,800 --> 00:02:24,510 >> E ora diamo uno sguardo al principale, che spinge l'interezza di questo programma. 54 00:02:24,510 --> 00:02:27,720 Innanzitutto, nella parte superiore qui avere un numero variabile di errore 55 00:02:27,720 --> 00:02:29,570 che appare di non avere un tipo, ma questo è 56 00:02:29,570 --> 00:02:31,500 perché in realtà è definito in un file chiamato 57 00:02:31,500 --> 00:02:34,800 errore che errno.h è incluso più in alto. 58 00:02:34,800 --> 00:02:38,780 Se fate uomo errno effettivamente vedi la definizione per questa cosa, 59 00:02:38,780 --> 00:02:41,230 vedrete che questo è un speciale variabile globale che 60 00:02:41,230 --> 00:02:43,350 è impostato per un intero gruppo di funzioni non scritta 61 00:02:43,350 --> 00:02:48,730 da noi, ma da Linux autori e altri sistemi per impostare effettivamente 62 00:02:48,730 --> 00:02:52,400 un numero di variabili che quando qualcosa va storto in modo che possiate globale 63 00:02:52,400 --> 00:02:54,830 capire cosa ha fatto andare storto. 64 00:02:54,830 --> 00:02:58,540 >> Ora in basso vedrete una nuova tecnica magari utilizzando getopt, 65 00:02:58,540 --> 00:03:01,790 una funzione che aiuta il comando parse gli argomenti della riga in modo che non facciamo 66 00:03:01,790 --> 00:03:05,540 devono preoccuparsi perdite di tempo per capire come analizzare qualcosa come 8080, 67 00:03:05,540 --> 00:03:08,350 o un trattino p, o trattino h per ottenere aiuto. 68 00:03:08,350 --> 00:03:10,300 getopt fa in sostanza, che per noi. 69 00:03:10,300 --> 00:03:11,750 Vedere la pagina man di più. 70 00:03:11,750 --> 00:03:13,960 >> Avanti, facciamo un po 'di errore controllo per assicurarsi che 71 00:03:13,960 --> 00:03:17,420 che il numero di porta è entro l'intervallo specificato nelle specifiche. 72 00:03:17,420 --> 00:03:20,240 Successivamente, vediamo una chiamata alla funzione avviare, la cui definizione ti 73 00:03:20,240 --> 00:03:24,040 guardare in un momento, e come il suo nome suggerisce, questo avvia il server web. 74 00:03:24,040 --> 00:03:26,960 Qui abbiamo una chiamata a una funzione chiamato segnale che dice: 75 00:03:26,960 --> 00:03:30,750 se e quando si sente di controllo C da la tastiera dell'utente, andare avanti e chiamare 76 00:03:30,750 --> 00:03:34,650 un gestore funzione chiamata che sta andando cose da pulire definitiva e smettere 77 00:03:34,650 --> 00:03:35,500 il server. 78 00:03:35,500 --> 00:03:39,470 >> Sotto questo è quello che sembra essere un loop infinito, la prima linea di cui 79 00:03:39,470 --> 00:03:41,660 effettivamente è una chiamata ad una funzione chiamata 80 00:03:41,660 --> 00:03:45,110 reset, che ci siamo implementare successivamente per 81 00:03:45,110 --> 00:03:47,470 per liberare alcuni dei nostri stati globali. 82 00:03:47,470 --> 00:03:50,480 Dopo che è una linea di codice condizionale 83 00:03:50,480 --> 00:03:52,576 sta controllando il ritorno valore collegato. 84 00:03:52,576 --> 00:03:55,700 Ora sembra collegati come un predicato, qualcosa che restituisce vero o falso. 85 00:03:55,700 --> 00:03:58,040 E lo fa, ma non c'è qualcosa di speciale in collegato 86 00:03:58,040 --> 00:03:59,960 in che si tratta di una chiamata di blocco. 87 00:03:59,960 --> 00:04:03,180 Si siederà lì e aspettare fino browser di un utente 88 00:04:03,180 --> 00:04:05,860 tenta di connettersi a questo sito web server e solo allora sarà vero 89 00:04:05,860 --> 00:04:10,160 restituire true o false in modo che si proceda all'interno di questo if. 90 00:04:10,160 --> 00:04:13,870 >> Una volta lì, notare questa funzione per un funzione chiamata parse, che abbiamo scritto, 91 00:04:13,870 --> 00:04:17,230 che analizza tutti gli ottetti, tutte dei byte provenienti da un browser 92 00:04:17,230 --> 00:04:21,010 al server, in modo che si possa consegnare si torna in ultima analisi, un valore a uno 93 00:04:21,010 --> 00:04:24,420 di queste variabili globali memorizza tutti i byte in proprio 94 00:04:24,420 --> 00:04:26,630 le intestazioni di tale richiesta, non il corpo 95 00:04:26,630 --> 00:04:28,920 se ci fosse effettivamente un corpo ad esso. 96 00:04:28,920 --> 00:04:32,980 >> Ora in basso cominciamo a analizzare queste intestazioni per estrarre 97 00:04:32,980 --> 00:04:35,490 un sottoinsieme delle informazioni che ci sta a cuore. 98 00:04:35,490 --> 00:04:37,740 In particolare, per la specificazione, per prima 99 00:04:37,740 --> 00:04:40,580 voluto richiedere la linea, che è solo che prima linea 100 00:04:40,580 --> 00:04:45,710 speriamo che dice qualcosa come get tagliare o qualche percorso e quindi HTTP 1.1. 101 00:04:45,710 --> 00:04:48,150 Stiamo utilizzando questa metafora di un ago in un pagliaio 102 00:04:48,150 --> 00:04:50,370 cercare particolare caratteri o indirizzi. 103 00:04:50,370 --> 00:04:53,120 E in effetti, c'è un certo numero di funzioni nel nostro codice di distribuzione 104 00:04:53,120 --> 00:04:56,930 che anche voi, potrebbe trovare utile quando alla ricerca di valori particolari. 105 00:04:56,930 --> 00:05:00,630 >> In ultima analisi, copiamo questi byte in una linea variabile chiamata, 106 00:05:00,630 --> 00:05:03,510 che notiamo, troppo, abbiamo allocato sullo stack 107 00:05:03,510 --> 00:05:05,890 per mezzo di una matrice di dimensioni dinamicamente. 108 00:05:05,890 --> 00:05:08,350 E stiamo cercando deliberatamente per evitare di chiamare malloc 109 00:05:08,350 --> 00:05:11,100 perché ancora una volta, perché di controllo C essere 110 00:05:11,100 --> 00:05:14,630 una caratteristica potenzialità di questo programma, abbiamo non vogliono avere questo codice improvvisamente 111 00:05:14,630 --> 00:05:17,479 interrotto dal colpire utente Controllo C, il cui risultato 112 00:05:17,479 --> 00:05:20,270 è che potrei non avere una possibilità gratuitamente qualcosa che ho malloced. 113 00:05:20,270 --> 00:05:23,660 Così sto cercando di utilizzare il più dello stack è che posso qui. 114 00:05:23,660 --> 00:05:26,040 >> Next up, un intero gruppo di al dos. 115 00:05:26,040 --> 00:05:28,930 La specifica sarà esporre esattamente quello che ci si aspetta qui, 116 00:05:28,930 --> 00:05:31,800 ma i commenti che danno un accenno di quello che ci aspetta. 117 00:05:31,800 --> 00:05:33,830 Innanzitutto è necessario convalidare la linea di richiesta 118 00:05:33,830 --> 00:05:37,760 e assicurarsi che sembra che il specifiche grammatica, per così dire, 119 00:05:37,760 --> 00:05:38,541 dice che dovrebbe. 120 00:05:38,541 --> 00:05:41,290 È quindi necessario estrarre qualcosa chiamato la query, la roba 121 00:05:41,290 --> 00:05:44,200 dopo un punto interrogativo, come abbiamo visto con il nostro esempio Google 122 00:05:44,200 --> 00:05:46,320 di passaggio in un parametro HD. 123 00:05:46,320 --> 00:05:49,050 Abbiamo poi concateniamo insieme la radice del server web 124 00:05:49,050 --> 00:05:52,520 con il percorso che è in tale richiesta prima linea 125 00:05:52,520 --> 00:05:56,010 e formare il percorso completo il file che vogliamo cercare. 126 00:05:56,010 --> 00:06:00,300 >> In seguito, stiamo andando a fare in modo che il file esiste ed è leggibile. 127 00:06:00,300 --> 00:06:05,100 E poi andremo a estrarne il estensione del file, .html o .php, 128 00:06:05,100 --> 00:06:09,920 o qualche tale estensione che è alla molto fine della stringa richiesto. 129 00:06:09,920 --> 00:06:11,940 Next up è un intero mucchio di codice che abbiamo scritto 130 00:06:11,940 --> 00:06:15,800 di generare realmente PHP generated content per voi. 131 00:06:15,800 --> 00:06:18,010 In poche parole, questo codice prende il nome 132 00:06:18,010 --> 00:06:20,250 del file che si desidera PHP interpreti. 133 00:06:20,250 --> 00:06:24,630 Noi passiamo da qualcosa chiamato un tubo in interprete di PHP. 134 00:06:24,630 --> 00:06:28,060 Tornate la risposta, come se la risposta fosse un file stesso. 135 00:06:28,060 --> 00:06:32,110 E poi iterare su tale file di byte, li tirano in un buffer 136 00:06:32,110 --> 00:06:34,180 in modo che possiamo in definitiva stamparli. 137 00:06:34,180 --> 00:06:37,230 >> Infatti, tutti questi chiamate qui per dprintf 138 00:06:37,230 --> 00:06:40,110 ci permette di stampare qualcosa chiamato un descrittore di file, che 139 00:06:40,110 --> 00:06:42,350 è solo un numero intero che rappresenta un file. 140 00:06:42,350 --> 00:06:45,360 Molto simile nello spirito, ma fondamentalmente diverso da un file 141 00:06:45,360 --> 00:06:46,620 puntatore stella. 142 00:06:46,620 --> 00:06:50,260 Notate come è possibile utilizzare la sintassi come printf qui in modo che io possa dinamicamente 143 00:06:50,260 --> 00:06:54,000 Inserire qualcosa come la lunghezza per il valore di un'intestazione HTTP 144 00:06:54,000 --> 00:06:55,270 chiamato Content-Length. 145 00:06:55,270 --> 00:06:57,990 E alla fine ho usato il Funzione diritto effettivamente scrivere 146 00:06:57,990 --> 00:07:00,040 il corpo alla richiesta. 147 00:07:00,040 --> 00:07:03,750 >> Purtroppo, abbiamo implementato solo Supporto per dinamicamente 148 00:07:03,750 --> 00:07:05,350 file PHP generati. 149 00:07:05,350 --> 00:07:08,520 Noi non implementare il supporto per file statici come GIF e JPEG, 150 00:07:08,520 --> 00:07:10,660 e file CSS e HTML. 151 00:07:10,660 --> 00:07:14,450 Questo, purtroppo, è lasciato a voi per rispondere allo scopo client 152 00:07:14,450 --> 00:07:15,090 questo per fare. 153 00:07:15,090 --> 00:07:20,050 Così in là troverete che non c'è non molto ispirazione all'interno di tale blocco, 154 00:07:20,050 --> 00:07:23,520 ma se un po 'più in alto di quanto siamo andati su interpretare codice PHP, 155 00:07:23,520 --> 00:07:25,520 le funzioni che useranno sono un po 'diverso. 156 00:07:25,520 --> 00:07:27,561 >> In realtà, si può prendere in prestito alcune delle funzionalità 157 00:07:27,561 --> 00:07:29,620 forse dalle forensics set problema, perché 158 00:07:29,620 --> 00:07:32,860 alla fine della giornata tutto ciò che serve a fare qui è una volta di sapere cosa file aperto 159 00:07:32,860 --> 00:07:35,690 e una volta che sai che è la cosiddetta Tipo MIME o tipo di contenuto, 160 00:07:35,690 --> 00:07:39,040 avete bisogno di leggere in quei byte e in qualche modo li sputare indietro. 161 00:07:39,040 --> 00:07:41,190 >> Ed ora un tour di questa altre funzioni del file. 162 00:07:41,190 --> 00:07:43,820 Fino primo è collegato, che restituisce semplicemente true 163 00:07:43,820 --> 00:07:47,350 quando finalmente sente un connessione da un utente. 164 00:07:47,350 --> 00:07:48,786 Next up è errore. 165 00:07:48,786 --> 00:07:52,296 Errore, nel frattempo, in funzione abbiamo ha scritto per gestire tutte le diverse 400 166 00:07:52,296 --> 00:07:55,360 e lo stato HTTP 500 codici che si potrebbe desiderare 167 00:07:55,360 --> 00:07:58,500 rispedire per l'utente, insieme con un messaggio standard. 168 00:07:58,500 --> 00:08:01,950 >> Next up è carico, un particolare funzione carnosa, il cui scopo nella vita 169 00:08:01,950 --> 00:08:06,920 è quello di leggere da una stella di file puntatore del contenuto di un file in un buffer globale 170 00:08:06,920 --> 00:08:09,000 che abbiamo dichiarato a livello globale sopra [? principale. ?] 171 00:08:09,000 --> 00:08:12,649 Questo è un po 'complessa, perché ci devono leggere i byte dal file 172 00:08:12,649 --> 00:08:14,690 ma controllare ogni iterazione se abbiamo già 173 00:08:14,690 --> 00:08:17,600 colpire la fine del file o qualcosa è andato storto. 174 00:08:17,600 --> 00:08:21,210 E usiamo realloc fare in modo che qualunque tampone che stiamo usando è in crescita 175 00:08:21,210 --> 00:08:24,440 e in crescita e in crescita e sempre stare davanti il ​​numero di byte 176 00:08:24,440 --> 00:08:25,675 che abbiamo bisogno di adattarsi in là. 177 00:08:25,675 --> 00:08:27,550 Handler, nel frattempo, è la funzione che ottiene 178 00:08:27,550 --> 00:08:30,630 chiamato dal modo di avere registrati controllo C come segnale 179 00:08:30,630 --> 00:08:32,140 che vogliamo intercettare. 180 00:08:32,140 --> 00:08:34,070 Si noti qui in gestore che in ultima analisi, 181 00:08:34,070 --> 00:08:36,780 chiamate fermano, che naturalmente arresta il server web. 182 00:08:36,780 --> 00:08:39,750 E purtroppo, ricerca non è implementata. 183 00:08:39,750 --> 00:08:41,940 Nello spirito, questo è un funzione abbastanza semplice. 184 00:08:41,940 --> 00:08:44,900 Dato un estensione del file, è necessario per tornare è la cosiddetta MIME 185 00:08:44,900 --> 00:08:46,320 tipo o tipo di contenuto. 186 00:08:46,320 --> 00:08:49,260 E si precisa nella specifica cosa che la mappatura deve essere. 187 00:08:49,260 --> 00:08:52,330 Ma è necessario tradurre in ultima analisi, il codice c. 188 00:08:52,330 --> 00:08:56,490 >> Next up è la nostra funzione in modo simile carnosa chiamato parse, il cui scopo nella vita 189 00:08:56,490 --> 00:08:59,350 è da leggere, non da un file, ma da una connessione di rete. 190 00:08:59,350 --> 00:09:03,510 Lettura, particolare e l'analisi del Richiesta HTTP che è venuto da un browser 191 00:09:03,510 --> 00:09:05,940 al server in modo che in ultima analisi, siamo in grado di analizzare 192 00:09:05,940 --> 00:09:09,530 a soli le intestazioni nella richiesta linea e tornare quelli di voi 193 00:09:09,530 --> 00:09:12,720 per mezzo di un buffer globale abbiamo dichiarato in precedenza [? principale. ?] 194 00:09:12,720 --> 00:09:14,880 >> Reset, nel frattempo, è un funzione che definiamo 195 00:09:14,880 --> 00:09:18,730 che viene chiamato iterativamente dentro di principale ogni volta che si sta 196 00:09:18,730 --> 00:09:20,799 pronto per iniziare ad ascoltare per una nuova connessione 197 00:09:20,799 --> 00:09:22,840 in modo che sappiamo sempre lo stato delle nostre variabili 198 00:09:22,840 --> 00:09:24,870 e così che abbiamo anche liberata alcuna memoria 199 00:09:24,870 --> 00:09:28,070 potrebbe essere stato assegnato per una connessione di rete precedente. 200 00:09:28,070 --> 00:09:30,060 Il prossimo è avviare, il funzione che abbiamo scritto 201 00:09:30,060 --> 00:09:31,920 che contiene un intero sacco di codice di rete 202 00:09:31,920 --> 00:09:34,420 che inizia alla fine il server web. 203 00:09:34,420 --> 00:09:36,680 >> Ultimo up è la funzione chiamato stop, che 204 00:09:36,680 --> 00:09:38,770 fa esattamente questo, arresta il server web. 205 00:09:38,770 --> 00:09:42,270 Ma prima si libera la memoria che ancora è stato assegnato. 206 00:09:42,270 --> 00:09:45,850 Ma si chiede in definitiva uscita senza nemmeno restituire il controllo 207 00:09:45,850 --> 00:09:47,480 la nostra funzione principale. 208 00:09:47,480 --> 00:09:49,480 Infine, uno degli la maggior parte delle tecniche importanti 209 00:09:49,480 --> 00:09:52,680 in sede di attuazione questo server web è sarà un po 'di tentativi ed errori, 210 00:09:52,680 --> 00:09:55,886 avere una finestra aperta del browser a destra e una finestra terminale 211 00:09:55,886 --> 00:09:57,760 a sinistra, la console server finestra, in modo che 212 00:09:57,760 --> 00:10:00,420 può vedere i messaggi che sono la visualizzazione sullo schermo. 213 00:10:00,420 --> 00:10:04,170 >> Ma meglio ancora sarebbe un terzo finestra, una seconda finestra terminale, 214 00:10:04,170 --> 00:10:07,135 in cui si usa Telnet, l'uso per i quali è prescritto nelle specifiche. 215 00:10:07,135 --> 00:10:09,640 E Telnet è solo un semplice programma di rete 216 00:10:09,640 --> 00:10:12,660 che consente di far finta di essere un browser in una finestra 217 00:10:12,660 --> 00:10:14,540 mentre parlando l'altra finestra. 218 00:10:14,540 --> 00:10:16,830 In questo modo si può vedere esattamente i comandi testuali 219 00:10:16,830 --> 00:10:18,700 che stanno tornando dal server al client 220 00:10:18,700 --> 00:10:20,810 senza dover frugare intorno sviluppatore di Chrome 221 00:10:20,810 --> 00:10:24,010 utensili in un altrimenti clunkier interfaccia. 222 00:10:24,010 --> 00:10:29,099