HTTP W 5-CIU PYTANIACH MICHAŁ KOPACZ
1 Co się dzieje po wpisaniu URL w przeglądarce?
https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
Uniform Resource Locator (ujednolicony format adresowania zasobów)
ZASÓB Zasobem może być wszystko co jest na tyle istotne by umieścić to pod danym URL. function sort() {... }
ul. Krzywa 12/5 55-323 Wrocław Polska 88050152312 NIE SĄ UJEDNOLICONE
scheme://username:password@host:port/path?query_string#fragment_id
SCHEMAT scheme://username:password@host:port/path?query_string#fragment_id http ftp https file chrome https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
LOGIN I HASŁO scheme://username:password@host:port/path?query_string#fragment_id git clone https://michalkopacz:mktest123@github.com/michalkopacz/zf-apigility.git https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
ADRES SERWERA scheme://username:password@host:port/path?query_string#fragment_id api.github.com 173.194.34.5 [db8:0cec::99:123a] www.facebook.com subdomena https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
PORT scheme://username:password@host:port/path?query_string#fragment_id http: 80 https: 443 8080 https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
ŚCIEŻKA DO ZASOBU scheme://username:password@host:port/path?query_string#fragment_id file:///c:/books/http%20the%20definitive%20guide.pdf https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
ŁADNE URL http://mojastrona.pl/regulamin RewriteEngine On RewriteRule ^regulamin$ index.php?page=regulamin http://mojastrona.pl/index.php?page=regulamin
ŚCIEŻKA WYSZUKIWANIA scheme://username:password@host:port/path?query_string#fragment_id http://allegro.pl/listing/listing.php?order=qd&string=http&search_scope=category-7 https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
FRAGMENT scheme://username:password@host:port/path?query_string#fragment_id przeglądarki nie wysyłają go do serwera może być używany przez JavaScript, np. https://www.youtube.com/watch?v=tl4bj1s66ga#t=95 https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content
https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content github.com DNS 192.30.252.131
https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content github.com DNS 192.30.252.131 192.30.252.131:443 TCP
TCP Transmission Control Protocol wszystkie bity otrzymane są identyczne jak bity wysłane wszystkie bity otrzymane są w kolejności ich wysłania
Hypertext Transfer Protocol (protokół przesyłania dokumentów hipertekstowych)
REQUEST-RESPONSE REQUEST TCP RESPONSE
HTTPbis
MODEL OSI Open Systems Interconnection aplikacji prezentacji HTTP, DNS HTTPS TLS (SSL) sesji transportowa TCP sieciowa IPv4 łącza danych fizyczna
REQUEST https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content TCP
REQUEST <metoda> <cel żądania> <wersja HTTP> <nagłówek> <nagłówek> <ciało żądania>
REQUEST GET /michalkopacz/zf-apigility/commits?page=4 HTTP/1.1 Host: github.com User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9, image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: pl-pl,pl;q=0.8,en-us;q=0.6,en;q=0.4 Connection: keep-alive Cookie: user_session=61tko8wcdukce;
METODY HTTP GET HEAD POST PUT DELETE CONNECT OPTIONS TRACE
METODY BEZPIECZNE używane tylko dla pobrania informacji o zasobie nie powinny zmieniać stanu danych na serwerze mogą powodować m.in. efekty takie jak logowanie, keszowanie lub podbijanie statystyk
METODY IDEMPOTENTNE wykonanie tego samego żądania wiele razy, ma taki sam efekt po stronie serwera, jak wykonanie pojedynczego żądania
GET żądanie używające GET powinno pobierać tylko dane zasobu i nie powinno powodować zmiany jego stanu
GET bezpieczna idempotentna
POST POST jest używany do wysyłania danych na serwer URL w żądaniu typu POST oznacza zasób, który przetworzy ciało żądania
POST <form action="/zfcampus/zf-apigility/issue_comments" method="post"> <input type="hidden" name="issue" value="74"> <textarea name="comment[body]" id="new_comment_field"> </textarea> <button type="submit">comment</button> </form>
POST nie jest bezpieczna nie jest idempotentna
PUT tworzy nowy zasób określony przez wysłane żądanie jeśli zasób pod URL już istnieje, to modyfikuje jego stan, używając ciała żądania
POST vs PUT POST /blog/1124234/entry/43/comments GET /blog/1124234/entry/43/comments/1 vs PUT /blog/1124234/entry/43/comments/2 GET /blog/1124234/entry/43/comments/2
PUT nie jest bezpieczna idempotentna
DELETE usuwa zasób identyfikowany przez URL
DELETE nie jest bezpieczna idempotentna
POZA RFC 7231 LINK (draft-snell-link-method-11) UNLINK (draft-snell-link-method-11) PATCH (rfc5789) COPY (rfc2518) MOVE (rfc2518)
RESPONSE https://github.com/michalkopacz/zf-apigility/commits?page=4#start-of-content TCP
RESPONSE <wersja HTTP> <status> <uzasadnienie> <nagłówek> <nagłówek> <ciało odpowiedzi>
RESPONSE HTTP/1.1 200 OK Date: Mon, 19 Jan 2015 20:35:12 GMT Server: GitHub.com Cache-Control: no-cache, private Content-Type: text/html; charset=utf-8 Content-Encoding: gzip Transfer-Encoding: chunked <!DOCTYPE html> <html lang="en" class="">...
KODY ODPOWIEDZI 1xx Informacyjne 2xx Sukces 3xx Przekierowanie 4xx Błąd klienta 5xx Błąd serwera
NAJBARDZIEJ ZNANE KODY 200 OK 302 Found 400 Bad Request 404 Not Found 500 Internal Server Error 504 Gateway Timeout
2 Jak działają sesje?
LOGOWANIE
BEZSTANOWOŚĆ HTTP nie przechowuje żadnych informacji o poprzednich transakcjach klienta z serwerem
POST REQUEST POST /session HTTP/1.1 Host: github.com Content-Type: application/x-www-form-urlencoded login=michalkopacz.mk%40gmail.com&password=pass
SESJA W PHP $userid = authenticateuser($_post['login'], $_POST['password']); if ($userid!== null) { session_name('user_session'); session_set_cookie_params(1209600, '/', 'github.com', true, true); session_start(); $_SESSION['userId'] = $userid; header("location: https://github.com/", true, 302); exit; }
DANE SESJI SET UB90l88D5haE {"user_id":"12345"}
PRZEKIEROWANIE HTTP/1.1 302 Found Location: https://github.com/ Set-Cookie: user_session=ub90l88d5hae; path=/; domain=github.com; expires=sun, 08-Feb-2015 13:38:31 GMT; secure; HttpOnly
CIASTECZKA dane trzymane po stronie przeglądarki przeglądarka wysyła ciasteczka w każdym żądaniu HTTP tylko dla domeny na której zostały utworzone github.com lub domen niższego poziomu *.github.com
PO PRZEKIEROWANIU POST / HTTP/1.1 Host: github.com Cookie: user_session=61tko8wcdukce;
3 Jak nie wygenerować tej samej odpowiedzi dwa razy?
STAŁE ZASOBY
BUFOROWANIE ODPOWIEDZI unieważnianie walidacja
UNIEWAŻNIANIE Expires: Sun, 25 Jan 2016 16:56:27 GMT Cache-Control: max-age=3600
NAGŁÓWEK EXPIRES czas na serwerze i czas w przeglądarce musi być zsynchronizowany
PIERWSZY REQUEST GET u/194026?v=3 Host: https://avatars0. githubusercontent.com P R Z E G L Ą D A R K A HTTP/1.1 200 OK Cache-Control: max-age=3600 B U F O R P R Z E G L Ą D A R K I GET u/194026?v=3 Host: https://avatars0. githubusercontent.com S E R W E R HTTP/1.1 200 OK Cache-Control: max-age=3600
PRZED WYGAŚNIĘCIEM GET u/194026?v=3 Host: https://avatars0. githubusercontent.com P R Z E G L Ą D A R K A HTTP/1.1 200 OK Cache-Control: max-age=3600 B U F O R P R Z E G L Ą D A R K I S E R W E R
PO WYGAŚNIĘCIU GET u/194026?v=3 Host: https://avatars0. githubusercontent.com P R Z E G L Ą D A R K A HTTP/1.1 200 OK Cache-Control: max-age=3600 B U F O R P R Z E G L Ą D A R K I GET u/194026?v=3 Host: https://avatars0. githubusercontent.com S E R W E R HTTP/1.1 200 OK Cache-Control: max-age=3600
WYMUSZENIE CZYSZCZENIA Co jeśli użytkownik zmieni avatar? Jak wtedy wymusić aby przeglądarka nie brała avatara z bufora?
WYMUSZENIE CZYSZCZENIA Zmieńmy url avatara. https://avatars0.githubusercontent.com/u/194026?v=4
UNIEWAŻNIANIE unieważnianie pozwala nam na skalowanie aplikacji, dzięki temu, że mniej żądań dochodzi do serwera
WALIDACJA Last-Modified / If-Modified-Since 1.0 Etag / If-None-Match 1.1
PIERWSZY REQUEST GET u/194026 Host: https://avatars0. githubusercontent.com P R Z E G L Ą D A R K A HTTP/1.1 200 OK Etag: abcdefg B U F O R P R Z E G L Ą D A R K I GET u/194026 Host: https://avatars0. githubusercontent.com S E R W E R HTTP/1.1 200 OK Etag: abcdefg
ZASÓB SIĘ NIE ZMIENIŁ GET u/194026 Host: https://avatars0. githubusercontent.com P R Z E G L Ą D A R K A HTTP/1.1 200 OK Etag: abcdefg B U F O R P R Z E G L Ą D A R K I GET u/194026 Host: https://avatars0. githubusercontent.com If-None-Match: abcdefg S E R W E R HTTP/1.1 304 Not Modified
ZASÓB ZOSTAŁ ZMIENIONY GET u/194026 Host: https://avatars0. githubusercontent.com P R Z E G L Ą D A R K A HTTP/1.1 200 OK Etag: 1234567 B U F O R P R Z E G L Ą D A R K I GET u/194026 Host: https://avatars0. githubusercontent.com If-None-Match: abcdefg S E R W E R HTTP/1.1 200 OK Etag: 1234567
WALIDACJA oszczędza łącze danych
KIEDY NIE DA SIĘ BUFOROWAĆ? metody inne niż GET i HEAD niektóre nagłówki, m.in. Set-Cookie i Cookie kody odpowiedzi inne niż 200, 300, 301, 410
4 Jak wysłać żądanie HTTP z przeglądarki bez przeładowania strony?
PISZEMY KOMUNIKATOR
XMLHttpRequest obiekt w JavaScript, wystawiony przez przeglądarki, umożliwiający wysyłanie żądań HTTP(S)
POBIERANIE WIADOMOŚCI function checkmessages() { var xhr = new XMLHttpRequest(); xhr.open( 'GET', 'https://mysite.pl/chat/pull?viewer_uid=6237374' ); xhr.onload = function(e) {... }; xhr.send(); } checkmessages();
REQUEST GET chat/pull?viewer_uid=6237374 HTTP/1.1 Host: mysite.pl Accept: */* Accept-Encoding: gzip, deflate, sdch Cookie: session_id=61tko8wcdukce; X-Requested-With: XMLHttpRequest Większość bibliotek do JavaScript-u dodaje ten nagłówek, gdy wysyłane jest żądanie HTTP, ale nie jest to natywny mechanizm XMLHttpRequest.
Xnagłówek nie opisany w żądnym standardzie "experimental" lub "extension" uznany za przestarzały w rfc6648
X-Requested-With function checkmessages() { var xhr = new XMLHttpRequest(); xhr.setrequestheader('x-requested-with', 'XMLHttpRequest'); xhr.open( 'GET', 'https://mysite.pl/chat/pull?viewer_uid=6237374' ); xhr.onload = function(e) {... }; xhr.send(); } checkmessages();
RESPONSE HTTP/1.1 200 OK Server: mysite.pl Content-Type: application/json; charset=utf-8 [ {"message": "Jak się masz?", "user_id": 2323}, {"message": "Co to jest HTTP?", "user_id": 322322} ]
JSON tekstowy format wymiany danych składania oparta jest na języku JavaScript istnieje wiele parserów formatu JSON w różnych językach
TYPY null Number 12.44 String "Co to jest HTTP?" Boolean true false Array [1, false, "hi"] Object {"foo": "bar"}
parsowanie JSON a function checkmessages() { var xhr = new XMLHttpRequest(); xhr.setrequestheader('x-requested-with', 'XMLHttpRequest'); xhr.open( 'GET', 'https://mysite.pl/chat/pull?viewer_uid=6237374' ); xhr.onload = function(e) { var messages = JSON.parse(e.target.response);... }; xhr.send(); } checkmessages();
Negocjacja kontentu (Content negotiation)
TYP MIME text/css text/html text/plain image/png image/jpeg audio/mpeg video/quicktime application/xml application/json application/javascript
NAGŁÓWKI Accept headers: Accept Accept-Language Accept-Charset Accept-Encoding
REQUEST GET /michalkopacz/zf-apigility/commits?page=4 HTTP/1.1 Host: github.com Accept: text/html,application/xhtml+xml,application/xml;q=0.9, image/webp,*/*;q=0.8 Accept-Encoding: gzip, deflate, sdch Accept-Language: pl-pl,pl;q=0.8,en-us;q=0.6,en;q=0.4 Accept-Charset: utf-8
NAGŁÓWKI Content headers: Content-Type Content-Language Content-Type Content-Encoding
REQUEST POST /chat/push HTTP/1.1 Host: mysite.pl Content-Type: application/json {"message": "Dobrze, a ty?", "user_id": 2323}
REQUEST POST /session HTTP/1.1 Host: github.com Content-Type: application/x-www-form-urlencoded login=michalkopacz.mk%40gmail.com&password=pass
ODCZYT ŻĄDANIA W PHP //application/json $message = json_decode(file_get_contents('php://input')); //application/x-www-form-urlencoded $credentials = urldecode(file_get_contents('php://input')); list($login, $password) = explode('&', $credentials); $login = $_POST['login']; $password = $_POST['password'];
RESPONSE HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Content-Encoding: gzip HTTP/1.1 200 OK Content-Type: text/css Content-Encoding: gzip
POOLING function checkmessages() { var xhr = new XMLHttpRequest(); xhr.setrequestheader('x-requested-with', 'XMLHttpRequest'); xhr.open( 'GET', 'https://mysite.pl/chat/pull?viewer_uid=6237374' ); xhr.onload = function(e) { var messages = JSON.parse(e.target.response);... }; xhr.send(); } setinterval(function() { checkmessages() }, 60000);
LONG POOLING function checkmessages() { var xhr = new XMLHttpRequest(); xhr.setrequestheader('x-requested-with', 'XMLHttpRequest'); xhr.timeout = 60000; xhr.open( 'GET', 'https://mysite.pl/chat/pull?viewer_uid=6237374' ); xhr.onload = function(e) { var messages = JSON.parse(e.target.response);... checkmessages(); }; xhr.send(); } checkmessages();
WEBSOCKET umożliwia dwukierunkową transmisję danych używa schematu ws: i wss:
5 Jak wysyłać żądania i odbierać odpowiedzi HTTP?
Chrome DevTools
PHP fsockopen file_get_contents curl Zend\Http Guzzle
DZIĘKUJE