Am intampinat problema urmatoare: dupa rularea serverului Perfect primeam mesajul “The file //index.html was not found.” la adresa http://127.0.0.1:8080/.
Desi are o rezolvare extrem de simpla, am vrut sa intru in profunzimea acestei probleme asa ca a fost nevoie sa inteleg notiunea de ruta (server-side route, voi vorbi in alt post de asta) si pentru a intelege notiunea de ruta am avut nevoie sa inteleg, mai mult, cum sunt comunicate datele prin HTTP (HyperText Transfer Protocol, un protocol special prin care serverul si clientul “vorbesc” unul cu celalalt prin request-uri si raspunsuri) cat si modul in care se fac cererile catre un anumit server.
Inainte de-a continua mi-am clarificat cativa termeni:
- protocol – set de reguli si norme care se aplica in comunicarea dintre doua entitati ale unei retele
- server – desi am fost tentat mult timp sa consider un calculator a fi server, acesta este doar un program instalat pe un calculator si nu calculatorul in sine. Dupa cum stim, pe un calculator pot rula mai multe servere: Apache, MySQL etc.
- client – un calculator care se conecteaza si foloseste resursele de la un alt calculator remote sau de la un server.
- agent sau user-agent – program sau script care se ocupa de cereri catre server si pregateste datele pentru user (ex: browser)
Cum functioneaza internetul?
1.) Initierea cererii & parsarea adresei URL
Odata ce ai introdus adresa URL in browser sau in consola, cand faci o cerere catre un server, primul lucru pe care trebuie sa il faca agentul este acela de-a “parsa” adresa URL si de-a genera o cerere pe care sa o trimita catre server.
protocol://server/request-URI
- protocolul descrie modul in care se va face comunicarea cu serverul si cum acesta va livra informatiile inapoi. ex: http:// sau ftp://
- server se refera la adresa URL sau IP, acesta poate include si PORT-ul daca serverul nu ruleaza la portul 80
- requestURI – numele fisierului de pe server, uneori exista scripturi care livreaza informatii pentru un anumit requestURI, chiar daca fisierul nu exista, fizic, pe server
Toti folosim astfel de adrese, spre exemplu: http://127.0.0.1/hello/marius
Aici protocolul este HTTP, serverul este 127.0.0.1 iar requestURI-ul este “/hello/marius“
2.) Trimiterea cererii
Browser-ul va trimite catre server, daca vorbim de HTTP, o cerere de forma:
[METH] [REQUEST-URI] HTTP/[VER] [fieldname1]: [field-value1] [fieldname2]: [field-value2] [request body]
- [METH] – metoda request-ului, ex: GET, POST
- [REQUEST-URI] – documentul sau adresa de pe server, ex: /index.html sau pur si simplu “/”
- [VER] – versiunea protocolului HTTP
- si mai multe campuri cu date folosite in general pentru a transmite informatii suplimentare serverului. ex: [fieldname1]: [field-value1] ar putea arata astfel… name: Marius cu metoda POST setata iar serverul va sti ca exista un field name cu valoarea Marius trimis prin POST.
GET /hello.txt HTTP/1.1
3.) Raspunsul serverului
Dupa cum ziceam mai sus, protocolul este un set de reguli si norme. Un server nu poate pur si simplu sa primeasca cererea, localizeaza fisierul sau executa anumite task-uri si returneaza pur si simplu continutul. Acesta trebuie sa respecte regulile protocolului folosit. Daca vorbim de HTTP raspunsul serverului trebui sa arate cam asa:
HTTP / [VER] [CODE] [TEXT] [HEADER] ... abia acum urmeaza BODY-ul ...
- [VER] – versiunea HTTP folosita
- [CODE] – codul de stare, acesta marcheaza daca cererea a fost realizata cu succes sau au aparut erori. Cele mai comune coduri sunt: 200 – OK, 403 – Forbidden si 404 – Not Found
- [TEXT] – text pentru utilizator, human-readable. Ex: OK, Forbidden, Not Found
- [HEADER] Urmeaza cateva linii care contin informatii despre document de forma camp: valoare.
Am facut request pentru a vedea header-ul returnat de webolink:
De notat existenta campului Content-Type, foarte util in scrierea de servicii web atunci cand trebuie sa suprascriem tipul de date default (text/html) cu application/json
BONUS: cand un server este configurat acestuia ii sunt specificate minim doua lucruri: PORTUL la care ruleaza si DIRECTORUL radacina (ROOT). Singurul port care nu mai necesita specificare la trimiterea unei cereri este portul 80. Cand accesam un URL si serverul se afla la portul 80 este optional sa specificam acest lucru, daca serverul este configurat sa ruleze la portul 8080 sau 3306 etc. atunci vom specifica ceva de genul: 127.0.0.1:8080 sau 127.0.0.1:3306.
Dupa rezolvarea portului serverul cauta in directorul root fisierul cerut prin request-URI. ex: 127.0.0.1/hello/sayHello.html va accesa in directorul root folderul hello si va incerca sa returneze fisierul sayHello.html. Daca acesta nu exista serverul poate sa evalueze cererea intr-un mod diferit si sa ruleze un script care va genera un raspuns custom.
Ex: cand eu trimit o cerere pentru /hello/marius, desi nu exista niciun fisier marius sau poate chiar niciun director hello, serverul va rula un script si va raspunde cu “Hello, Marius!“. La fel cand vom accesa /hello/mihai, va raspunde prin “Hello, Mihai!“
4.) Afisarea raspunsului
Si acum vine efectul magiei, userul vede pe ecran documentul de la URL-ul introdus la pasul 1.)
Practic acum iarasi vine o munca “istovitoare” de parsare a raspunsului pe care o face agentul.
Dupa cum am zis mai sus, HTTP este doar un mod prin care doua entitati (client si server) pot comunica insa acesta nu sta si la baza transferului efectiv al datelor. Pentru a intelege modul in care datele sunt transferate intre calculatoare, fie pe cale HTTP, fie FTP (File Transfer Protocol), va trebui sa intelegem modului in care functioneaza comunicarea TCP/IP (Transport Control Protocol). Nu intru in detalii asupra acestui subiect, mai multe aici: http://www.hostingadvice.com/blog/tcpip-make-internet-work/ sau, ceva mai avansat, aici: https://technet.microsoft.com/en-us/library/cc786128(v=ws.10).aspx
Super interesant articolul! Chiar iti poti da seama de multe lucruri, atunci cand iti sunt explicate asa cum trebuie!!
Bravo! Tot asa! 😉