Onion Information
Obrada HTTP zahtjeva i stvaranje odgovora u jeziku PHP - GASERI
U ovom dijelu nastavljamo koristiti ugrađeni web poslužitelj interpretera PHP-a i pretpostavljamo da je pokrenut tako da poslužuje sadržaj direktorija public u kojem se nalazi datoteka index.php
Onion Details
Page Clicks: 0
First Seen: 03/15/2024
Last Indexed: 10/23/2024
Onion Content
Preskoči na sadržaj Obrada HTTP zahtjeva i stvaranje odgovora u jeziku PHP U ovom dijelu nastavljamo koristiti ugrađeni web poslužitelj interpretera PHP-a i pretpostavljamo da je pokrenut tako da poslužuje sadržaj direktorija public u kojem se nalazi datoteka index.php . Usmjeravanje zahtjeva Usmjeravanje po putanji Promijenimo kod u datoteci public/index.php tako da odgovara na zahtjeve upućene na putanju /grafit sadržajem Uvijek me uhvate kad šaram grafite po z , a na sve ostale zahtjeve sadržajem Hello, world! . To možemo izvesti korištenjem uvijek dostupne varijable koja sadrži putanju u HTTP zahtjevu, a ta varijabla je $_SERVER["REQUEST_URI"] iz polja $_SERVER ( dokumentacija ). Provjeru putanje vršimo na način: Uvijek me uhvate kad šaram grafite po z \n " ; } else { echo " Hello, world! \n " ; } Uvjerimo se da naše usmjeravanje zahtjeva upućenih na putanju /grafit radi ispravno: $ curl http://localhost:8000/grafit Uvijek me uhvate kad šaram grafite po z Dodatno možemo postaviti statusni kod odgovora funkcijom http_response_code() ( dokumentacija ) iz dijela Network . Postavimo statusni kod na 206 Partial Content ( više detalja o HTTP statusnom kodu 206 Partial Content na MDN-u ) kod odgovora na zahtjeve upućene na putanju /grafit : Uvijek me uhvate kad šaram grafite po z \n " ; } else { echo " Hello, world! \n " ; } Uvjerimo se da se statusni kod odgovora promijenio: $ curl -v http://localhost:8000/grafit * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > GET /grafit HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse Uvijek me uhvate kad šaram grafite po z * Closing connection 0 Isti kod vidimo na strani poslužitelja: [Mon Nov 2 23:28:59 2020] [::1]:52808 Accepted [Mon Nov 2 23:28:59 2020] [::1]:52808 [206]: GET /grafit [Mon Nov 2 23:28:59 2020] [::1]:52808 Closing Preusmjeravanje zahtjeva na drugu putanju Zaglavlje odgovora možemo dopuniti dodatnim elementima korištenjem funkcije header() ( dokumentacija ) iz dijela Network . Primjerice, možemo svakom korisničkom agentu kod odgovaranja na njegov zahtjev jasno reći koja je PHP-ova maskota dodavanjem vlastitog nestandardnog zaglavlja PHP-Mascot na način: GET / HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse Uvijek me uhvate kad šaram grafite po z \n " ; } else if ( $_SERVER [ "REQUEST_URI" ] == "/grafiti" ) { http_response_code ( 302 ); header ( "Location: /grafit" ); } else { echo " Hello, world! \n " ; } Uvjerimo se da preusmjeravanje radi korištenjem cURL-ovog parametra --location , odnosno -L koji će učiniti da cURL ponovi HTTP zahtjev na novoj lokaciji navedenoj u zaglavlju Location : $ curl -v -L http://localhost:8000/grafiti * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > GET /grafiti HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse GET /grafit HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse Uvijek me uhvate kad šaram grafite po z * Closing connection 1 Na strani poslužitelja poruke su oblika: [Mon Nov 2 23:38:20 2020] [::1]:52822 Accepted [Mon Nov 2 23:38:20 2020] [::1]:52822 [302]: GET /grafiti [Mon Nov 2 23:38:20 2020] [::1]:52822 Closing [Mon Nov 2 23:38:20 2020] [::1]:52824 Accepted [Mon Nov 2 23:38:20 2020] [::1]:52824 [206]: GET /grafit [Mon Nov 2 23:38:20 2020] [::1]:52824 Closing Relativne putanje u zaglavlju Location se rijetko koriste. Ako želimo u zaglavlje Location upisati čitav URL, možemo iskoristiti dodatne varijable iz ranije korištenog polja $_SERVER : $_SERVER["SERVER_NAME"] -- ime poslužitelja (u našem slučaju localhost ) $_SERVER["SERVER_PORT"] -- vrata poslužitelja (u našem slučaju 8000 ) pa umjesto koda: Hello, post-world! \n " ; } else { echo " Hello, world! \n " ; } Uvjerimo se da provjera metode radi: $ curl -X POST http://localhost:8000/ Hello, post-world! Provjere putanje i metode možemo kombinirati korištenjem logičkih operatora negacije ( ! ), "i" ( && ) i "ili" ( || ) ( dokumentacija ). Primjerice, možemo u HTTP odgovoru postaviti statusni kod na 400 Bad Request ( više detalja o HTTP statusnom kodu 400 Bad Request na MDN-u ) ako se koristi metoda POST na putanji /grafit , ali dozvoliti ostale metode na navedenoj putanji. Za to nam treba logički operator "i" ( && ): Zahtjev metodom POST na /grafit nije ispravan \n " ; } else if ( $_SERVER [ "REQUEST_URI" ] == "/grafit" ) { http_response_code ( 206 ); echo " Uvijek me uhvate kad šaram grafite po z \n " ; } else { echo " Hello, world! \n " ; } Lako ćemo se uvjeriti da se postavljeni statusni kod javlja u HTTP odgovoru: $ curl -v -X POST http://localhost:8000/grafit * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > POST /grafit HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse Zahtjev metodom POST na /grafit nije ispravan * Closing connection 0 Odgovarajuća poruka na strani poslužitelja je oblika: [Tue Nov 3 08:54:07 2020] [::1]:52918 Accepted [Tue Nov 3 08:54:07 2020] [::1]:52918 [400]: POST /grafit [Tue Nov 3 08:54:07 2020] [::1]:52918 Closing Dosad smo izvodili zahtjeve HTTP metodama GET i POST. Pored njih postoji još nekoliko HTTP metoda, kojima se detaljnije bavimo u nastavku. Ovdje je za ilustraciju procesa slanja zahtjeva i formiranja odgovora na zahtjev zanimljivo promotriti način rada metoda HEAD i CONNECT. Specifičnosti metode HEAD Zahtjev HTTP metodom HEAD učinit će da poslužitelj vrati odgovor koji ima samo zaglavlja, odnosno nema tijelo ( više detalja o HTTP metodi HEAD na MDN-u ). Uzmimo da je datoteka index.php sadržaja: Ovaj dio neće biti sadržan u odgovoru \n " ; } Napravimo HTTP zahtjev HEAD cURL-om da se uvjerimo da naš poslužitelj radi kako treba: $ curl -v -X HEAD http://localhost:8000/ Warning: Setting custom HTTP method to HEAD with -X/--request may not work the Warning: way you want. Consider using -I/--head instead. * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > HEAD / HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Mark bundle as not supporting multiuse CONNECT / HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.72.0 > Accept: */* > * Empty reply from server * Connection #0 to host localhost left intact curl: ( 52 ) Empty reply from server Kako metoda CONNECT nije implementirana, na strani poslužitelja imamo poruku o neispravnom HTTP zahtjevu: [Wed Dec 30 19:44:37 2020] [::1]:52244 Accepted [Wed Dec 30 19:44:37 2020] [::1]:52244 Invalid request (Malformed HTTP request) [Wed Dec 30 19:44:37 2020] [::1]:52244 Closing Dohvaćanje i obrada zaglavlja zahtjeva Korištenjem varijabli iz polja $_SERVER možemo dohvatiti i druga zaglavlja HTTP zahtjeva: korištenjem varijable $_SERVER["HTTP_HOST"] zaglavlje Host koje sadrži ime domaćina (u našem slučaju localhost ); više detalja o HTTP zaglavlju Host na MDN-u korištenjem varijable $_SERVER["HTTP_USER_AGENT"] zaglavlje User-Agent koje sadrži korisnički agent, odnosno ime i verziju web klijenta koji se koristi (u našem slučaju curl/7.72.0 ); više detalja o HTTP zaglavlju User-Agent na MDN-u korištenjem varijable $_SERVER["HTTP_ACCEPT"] zaglavlje Accept koje sadrži skup MIME tipova koje klijent prihvaća (u našem slučaju */* , odnosno svi); više detalja o HTTP zaglavlju Accept na MDN-u korištenjem varijable $_SERVER["HTTP_REFERER"] zaglavlje Referer koje sadrži adresu s koje je resurs zatražen; više detalja o HTTP zaglavlju Referer na MDN-u Provjera imena domaćina Jedan HTTP poslužitelj može posluživati sadržaj više različitih domaćina. Primjerice, domaćine na domenama www.math.uniri.hr , www.phy.uniri.hr i www.biotech.uniri.hr poslužuje poslužitelj na domeni webovi.uniri.hr i IPv4 adresi 193.198.209.33 . U praksi je takav način posluživanja vrlo poželjan zbog korištenja jedne IPv4 adrese za posluživanje sadržaja s mnogo različitih domena. Naime, dok domena ima za praktične potrebe sasvim dovoljno, bazen dostupnih IPv4 adresa je iscrpljen i blokovi IPv4 adresa se prodaju za cijenu od nekoliko desetaka dolara po adresi . Ovo je Fakultet informatike i digitalnih tehnologija. " ; } else if ( $_SERVER [ "HTTP_HOST" ] == "www.riteh.rm.miletic.net" ) { echo " Ovo je Tehnički fakultet. \n " ; } else { echo " Hello, world! \n " ; } Kod korištenja cURL-a zaglavlja poslana u HTTP zahtjevu navodimo parametrom --header , odnosno -H . Isprobajmo različite vrijednosti zaglavlja Host : $ curl -v -H 'Host: www.riteh.rm.miletic.net' http://localhost:8000/ * Trying 127 .0.0.1:8000... * connect to 127 .0.0.1 port 8000 failed: Veza odbijena * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > GET / HTTP/1.1 > Host: www.riteh.rm.miletic.net > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse Ovo je Tehnički fakultet. * Closing connection 0 $ curl -v -H 'Host: www.inf.rm.miletic.net' http://localhost:8000/ * Trying 127 .0.0.1:8000... * connect to 127 .0.0.1 port 8000 failed: Veza odbijena * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > GET / HTTP/1.1 > Host: www.inf.rm.miletic.net > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse Ovo je Fakultet informatike i digitalnih tehnologija. * Closing connection 0 $ curl -v -H 'Host: www.inf.uniri.hr' http://localhost:8000/ * Trying 127 .0.0.1:8000... * connect to 127 .0.0.1 port 8000 failed: Veza odbijena * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > GET / HTTP/1.1 > Host: www.inf.uniri.hr > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse Hello, world! * Closing connection 0 U slučaju da ne navedemo zaglavlje Host , ono će imati vrijednost imena domene i vrata koja smo naveli u URL-u (u našem slučaju localhost:8000 ) pa će poslužitelj poslati očekivani odgovor: $ curl -v http://localhost:8000/ * Trying 127 .0.0.1:8000... * connect to 127 .0.0.1 port 8000 failed: Veza odbijena * Trying ::1:8000... * Connected to localhost ( ::1 ) port 8000 ( #0) > GET / HTTP/1.1 > Host: localhost:8000 > User-Agent: curl/7.81.0 > Accept: */* > * Mark bundle as not supporting multiuse Hello, world! * Closing connection 0 Ispis korisničkog agenta Moguće je razlikovati korisničke agente na sličan način kao domaćine i servirati različit sadržaj ovisno o vrijednosti korisničkog agenta navedenoj u primljenom HTTP zahtjevu. Web standardi su namijenjeni za sve korisničke agente ( više detalja o web standardima na MDN-u ) pa se takvo prilagođavanje uglavnom ne preporuča. Stoga ćemo se u primjeru ograničiti na ispis korisničkog agenta: Vaš korisnički agent je: $ua . \n " ; Isprobajmo cURL-om: curl -v http://localhost:8000/ *...