Dydaktyka:
FeedbackTo jest stara wersja strony!
Uwaga: Dla ułatwienia zajęć w tych materiałach kliknięcie na przykładowe
polecenia, tekst pisany czcionką stałej szerokości
i taki
tekst zaznaczy cały ich tekst. Przypominam że w Linuksie ostatni
zaznaczony tekst można wkleić naciskając środkowy przycisk myszy.
Uwaga: jeżeli chcesz wykonywać te polecenia spoza PP, zaloguj się i wykonuj je z serwera polluks lub pytaj o adres inny niż lindev.cs.put.poznan.pl (z którego treść stron jest dostępna tylko z PP).
Uwaga: wbudowana w bash komenda fc
tworzy tymczasowy plik i otwiera
go w domyślnym edytorze tekstu (wskazany przez zmienną EDITOR
). Po
zakończeniu edycji pliku bash wstawia treść pliku do linii poleceń i wykonuje
tę linię.
Zadanie 0.1 Skopiuj i wklej w konsolę i wykonaj poniższe polecenie:
tr 'a-z' 'd-za-c' << EOF kilka przykladowych linii tekstu EOF
Następnie wpisz fc
, zmień treść tekstu przekazanego do komendy tr
,
zapisz plik i wyjdź z niego.
Domyślny edytor możesz zmienić np. na nano
bądź mousepad
wpisując
export EDITOR=nano
bądź export EDITOR=mousepad
.
Zadanie 1.1 Wyślij zapytanie HTTP GET w wersji 1.0 bez podawania nazwy domenowej:
nc lindev.cs.put.poznan.pl 80 << KONIEC GET / HTTP/1.0 KONIEC
Zadanie 1.2 Wyślij zapytanie HTTP GET w wersji 1.1 bez podawania nazwy domenowej:
nc lindev.cs.put.poznan.pl 80 << KONIEC GET / HTTP/1.1 KONIEC
Dlaczego dostajesz taką a nie inną odpowiedź?
Zadanie 1.3 Wyślij zapytanie HTTP GET w wersji 1.1 podając nazwę domenową:
nc lindev.cs.put.poznan.pl 80 << KONIEC GET / HTTP/1.1 Host: lindev.cs.put.poznan.pl KONIEC
Dlaczego połączenie się nie zamknęło?
Zadanie 1.4 Wyślij dwa zapytania HTTP GET w wersji 1.1 prosząc o zakończenie połączenia po odpowiedzi na ostatnie z nich:
nc lindev.cs.put.poznan.pl 80 << KONIEC GET /var/ HTTP/1.1 Host: lindev.cs.put.poznan.pl GET /SK/ HTTP/1.1 Host: lindev.cs.put.poznan.pl Connection: close KONIEC
Zadanie 1.5 Wyślij zapytanie HTTP GET do innego serwera:
nc nghttp2.org 80 << KONIEC GET / HTTP/1.0 KONIEC
Dlaczego dostajesz odpowiedź Bad Request?
Zadanie 1.6
Zmień (w ten czy inny sposób) znak \n
na \r\n
i wyślij tę samą treść
jak w poprzednim zadaniu:
unix2dos << KONIEC | nc nghttp2.org 80 GET / HTTP/1.0 KONIEC
sed 's/$/\r/' << KONIEC | nc nghttp2.org 80 GET / HTTP/1.0 KONIEC
Jakie znasz sposoby zapisywania końca linii?
Zadanie 1.7 Zapytaj kolejno o http://www.cs.put.poznan.pl/, http://www.cs.put.poznan.pl/jkonczak/ oraz http://www.cs.put.poznan.pl/jkonczak/sk2:
nc www.cs.put.poznan.pl 80 << KONIEC | head -n 20 GET / HTTP/1.1 Host: www.cs.put.poznan.pl Connection: close KONIEC
nc www.cs.put.poznan.pl 80 << KONIEC | head -n 20 GET /jkonczak/ HTTP/1.1 Host: www.cs.put.poznan.pl Connection: close KONIEC
nc www.cs.put.poznan.pl 80 << KONIEC | head -n 20 GET /jkonczak/sk2 HTTP/1.1 Host: www.cs.put.poznan.pl Connection:close KONIEC
Narzędzie nc
/ netcat
1)
nie umie zamieniać końców linii na \r\n
.
Narzędzie socat
potrafi to zrobić po podaniu odpowiedniej opcji.
Narzędzie nc
/ netcat
zamyka połączenie jeśli z obu stron pojawi się
koniec pliku (tzn. odczyt i na stdin i na gnieździe zwróci 0).
Domyślnie socat
zamyka połączenie kiedy z którejkolwiek strony pojawi się
koniec pliku.
Zadanie 2.1
Zobacz jak wskazuje się programowi socat
zmianę wspomnianych wyżej zachowań:
unix2dos << KONIEC | nc nghttp2.org 80 GET / HTTP/1.0 KONIEC
socat tcp:nghttp2.org:80,crlf stdio,ignoreeof << KONIEC GET / HTTP/1.0 KONIEC
HTTPS (oficjalnie HTTP Over TLS) jest w podsumowującym go standardzie krótko scharakteryzowany następująco:
Dla przypomnienia: socat
pozwala używać połączeń szyfrowanych, podając
ssl
bądź openssl
jako protokół. openssl s_client
służy do testowania
połączeń szyfrowanych. Oba te narzędzia pozwalają testować szyfrowany transport
wiadomości HTTP.
Zadanie 2.2
Porównaj wysłanie zapytania HTTP używając szyfrowanego transportu używając
narzędzia socat
i openssl
.
socat ssl:cat.put.poznan.pl:443,crlf stdio,ignoreeof << KONIEC | head -n 40 GET / HTTP/1.1 Host: cat.put.poznan.pl Connection: close KONIEC
openssl s_client -quiet -verify_quiet -crlf cat.put.poznan.pl:443 << KONIEC | head -n 40 GET / HTTP/1.1 Host: cat.put.poznan.pl Connection: close KONIEC
Uwaga: Jeśli poda się programowi socat
opcję ,ignoreeof
dla któregoś
strumienia, zamienia \r\n
zarówno w wysyłanych jak i odbieranych przez ten
strumień danych. Z kolei openssl s_client
z opcją -crlf
poprawia jedynie
wysyłane znaki nowej linii. Możesz to sprawdzić porównując wynik komend:
printf 'GET / HTTP/1.0\nHost:sirius.cs.put.poznan.pl\n\n' | socat ssl:sirius.cs.put.poznan.pl:443,crlf -,ignoreeof | cat -v
printf 'GET / HTTP/1.0\nHost:sirius.cs.put.poznan.pl\n\n' | openssl s_client -quiet -verify_quiet -crlf sirius.cs.put.poznan.pl:443 | cat -v
Jeżeli w odpowiedzi będą dane binarne, socat
może je "zepsuć" zmieniając
\r\n
na \n
.
W żądaniu HTTP powinien być używany tylko zestaw znaków ASCII. Dodatkowo w linii żądania, w adresie żądanego zasobu nie może znajdować się spacja. Do zakodowania znaków spoza ASCII i białych znaków w linii żądania używa się tzw. Percent-Encoding.
Zadanie 2.3 Sprawdź jak zostanie zrozumiana nazwa zasobu %C5%BB%C3%B3%C5%82%C4%87 i d%C4%85%C4%87+w+r%C3%B3g:
openssl s_client -crlf -quiet -verify_quiet pl.wikipedia.org:https << EOF | grep 'title>' GET /wiki/%C5%BB%C3%B3%C5%82%C4%87 HTTP/1.0 Host: pl.wikipedia.org EOF
openssl s_client -crlf -quiet -verify_quiet www.google.pl:https << EOF | grep -o '<title>.*</title>' GET /search?q=d%C4%85%C4%87+w+r%C3%B3g HTTP/1.0 Host: www.google.pl User-Agent: Mozilla/5.0 Firefox/100 EOF
Do zmiany ze zwykłego utf-8 na urlencode i z powrotem możesz użyć np. gotowej komendy w perlu czy php:
openssl s_client -crlf -quiet -verify_quiet www.google.pl:https << EOF | grep -o '<title>.*</title>' GET /search?q=$(perl -Mutf8 -MURI::Escape -e 'print uri_escape_utf8 "żółta żaba żarła żur"') HTTP/1.0 Host: www.google.pl User-Agent: Mozilla/5.0 Firefox/100 EOF
openssl s_client -crlf -quiet -verify_quiet www.google.pl:https << EOF | grep -o '<title>.*</title>' GET /search?q=$(php -r 'echo urlencode("żółta żaba żarła żur");') HTTP/1.0 Host: www.google.pl User-Agent: Mozilla/5.0 Firefox/100 EOF
perl -Mutf8 -MURI::Escape -e 'print uri_unescape("%C5%B9d%C5%BAb%C5%82o") . "\n"'
php -r 'echo urldecode("%C5%B9d%C5%BAb%C5%82o") . "\n";'
Ten sam serwer HTTP może obsługiwać strony dla wielu nazw domenowych. Żeby to umożliwić, wprowadzono do HTTP wymaganie podania nagłówka Host wskazującego dla jakiej nazwy hosta podany zasób ma zostać zwrócony.
Zadanie 3.1 Używając poniższych komend2) połącz się na port 443 adresu IP 150.254.186.176 i podaj różne wartości nagłówka Host: raz www.mpu.pl, raz www.mpk.poznan.pl. Porównaj odpowiedzi.
openssl s_client -quiet -verify_quiet -crlf 150.254.186.176:https << EOF \ | awk '{if(p)print;else print>"/dev/stderr"};/^\r$/{p=1}' | w3m -T text/html -dump - GET / HTTP/1.0 Host: www.mpu.pl EOF
openssl s_client -quiet -verify_quiet -crlf 150.254.186.176:https << EOF \ | awk '{if(p)print;else print>"/dev/stderr"};/^\r$/{p=1}' | w3m -T text/html -dump - GET / HTTP/1.0 Host: www.mpk.poznan.pl EOF
Zadanie 3.2 Przy użyciu szyfrowanego transport komunikatów HTTP – tzn. HTTPS – treść żądania, w tym nagłówek Host jest wysyłany po nawiązaniu połączenia. Jednak już w trakcie nawiązywania połączenia TLS serwer musi przedstawić certyfikat dla właściwej domeny. A co jeśli serwer HTTPS obsługuje strony dla różnych domen? Dowiedz się skąd serwer wie który certyfikat przedstawić klientowi. Jak takie rozwiązanie wpływa na prywatność komunikacji HTTPS? Czy zaproponowano rozwiązania tej kwestii?
W protokole HTTP serwer może poprosić klienta o zapamiętanie wskazanych danych
i przesłanie ich z powrotem przy każdym kolejnym żądaniu.
Szczegóły składni odpowiednich nagłówków znajdziesz np.
tutaj.
Zadanie 3.3 Ściągnij treść strony http://www2.cs.put.poznan.pl/ i znajdź w nagłówkach odpowiedzi ten proszący o zapamiętanie ciasteczka:
unix2dos << EOF | nc www2.cs.put.poznan.pl 80 | head -n18 GET / HTTP/1.0 Host: www2.cs.put.poznan.pl EOF
Zadanie 3.4 Ponownie ściągnij treść strony http://www2.cs.put.poznan.pl/, ale tym razem podaj w nagłówkach ciasteczko o treści qtrans_front_language=en. Czy różni się odpowiedź jeśli w żądaniu znalazło się wskazane ciasteczko?
unix2dos << EOF | nc www2.cs.put.poznan.pl 80 | head -n18 GET / HTTP/1.0 Host: www2.cs.put.poznan.pl Cookie: qtrans_front_language=en EOF
Zadanie 3.5 Nagłówek Accept-Language jest często wykorzystywany (i respektowany) do wskazywania przez przeglądarkę preferowanego języka. Porównaj wynik zapytań najpierw zostawiając, potem usuwając ten nagłówek z poniższego zapytania:
socat ssl:duckduckgo.com:443 stdio,ignoreeof << EOF GET / HTTP/1.0 Host: duckduckgo.com Accept-Language: pl EOF
Zadanie 3.6 Nagłówek Accept-Encoding jest powszechnie używany do określania przez klienta jakie sposoby kompresowania treści odpowiedzi rozumie. Jeśli taki nagłówek zostanie podany i serwer zna którąś ze wskazanych metod kompresji, to dla zaoszczędzenia transferu wyśle odpowiedź skompresowaną najkorzystniejszym dla siebie sposobem. Porównaj wynik poniższych zapytań bez oraz z tym nagłówkiem:
openssl s_client -quiet -verify_quiet -crlf dcs.cs.put.poznan.pl:443 << EOF GET / HTTP/1.0 Host: dcs.cs.put.poznan.pl Accept-Encoding: gzip EOF
Dodając na koniec linii polecenia openssl
potok | sed '1,/^\r$/d' | gunzip
możesz zdekompresować odpowiedź.
Zadanie 3.7 Porównaj ile przepustowości pozwalają zaoszczędzić różne sposoby kompresowania danych.
M=; for ENC in identity gzip zstd br; do S=$(openssl s_client -quiet -verify_quiet -crlf www.facebook.com:443 << EOF 2>/dev/null | wc -c GET /Politechnika.Poznanska HTTP/1.0 Host: www.facebook.com Accept-Encoding: $ENC User-Agent: czlowiek EOF ); M=${M:-$S}; printf "%s %d'%03d %d.%03d%%\n" $ENC $((S/1000)) $((S%1000)) $((100*S/M)) $(((100000*S/M)%1000)); done | column -tR1-3
Jak duża jest różnica między metodą gzip a specjalnie napisaną w firmie Facebook dla oszczędzenia transferu i czasu kompresji metodą zstd i specjalnie napisaną w firmie Google dla oszczędzenia transferu i czasu kompresji metodą brotli? Zauważ też że w HTTP/1.x nagłówki nie są kompresowane.
Zadanie 3.8 Nagłówek Accept pozwala w żądaniu wskazać jaki typ MIME klient chce otrzymać. Zwykle serwer ma dany zasób tylko w jednym formacie i niezależnie co chciał klient, zwraca zawsze to samo. Zdarzają się scenariusze w których ten nagłówek jest jednak używany; np. przy ściąganiu obrazów przeglądarki ustawiają w Accept preferowane formaty, z których serwer może wybrać najkorzystniejszy. Porównaj:
socat ssl:img.onet.pl:443,crlf -,ignoreeof << EOF | head -n 5 GET /1/NOek9lBaHR0cHM6Ly9vY2RuLmV1L3B1bHNjbXMvTURBXy8yYzYzMWQ4NWZlZDExMmFjNmU1YjRmZjMyYmRiMmMwNi5qcGeSlQMAzQHJzQIvzQE6kwXMvnbeAAKhMAehMQQ HTTP/1.0 Host: img.onet.pl Accept: image/avif,image/webp,image/png,image/jpeg,image/* EOF
socat ssl:img.onet.pl:443,crlf -,ignoreeof << EOF | head -n 5 GET /1/NOek9lBaHR0cHM6Ly9vY2RuLmV1L3B1bHNjbXMvTURBXy8yYzYzMWQ4NWZlZDExMmFjNmU1YjRmZjMyYmRiMmMwNi5qcGeSlQMAzQHJzQIvzQE6kwXMvnbeAAKhMAehMQQ HTTP/1.0 Host: img.onet.pl Accept: image/png,image/jpeg,image/* EOF
Jeżeli żądanie bądź odpowiedź zawierają treść, wśród nagłówków musi znaleźć się informacja o tym jakiego rodzaju jest to treść i kiedy odbiorca ma uznać że cała treść już do niego dotarła.
Zadanie 3.9 Porównaj użycie nagłówka Content-Length i Transfer-Encoding: chunked w HTTP/1.1:
nc lindev.cs.put.poznan.pl 80 << KONIEC GET /ZSK/Win7_Samba3DomainMember.reg HTTP/1.1 Host: lindev.cs.put.poznan.pl Connection: close KONIEC
nc lindev.cs.put.poznan.pl 80 << KONIEC GET /Windows/Photo/ HTTP/1.1 Host: lindev.cs.put.poznan.pl Connection: close KONIEC
Praktycznie każda wersja HTTP ma inny pomysł na przesyłanie danych o nieokreślonym rozmiarze: HTTP/1.0 nie podawał długości danych i zamykał połączenie, HTTP/2 i HTTP/3 wprowadzają własne nagłówki transportujące wiele równoległych żądań (strumienie) i w nich jest zaznaczone czy to ostatni fragment treści.
Zadanie 3.10 Nagłówek Content-Type informuje o typie MIME danych stanowiących treść. Porównaj typy i zwracaną treść odpowiedzi na następujące zapytania:
socat ssl:danepubliczne.imgw.pl:443 stdio,ignoreeof << EOF | grep -iC99 'content-.*:' GET /api/data/synop/id/12330/format/xml HTTP/1.0 Host: danepubliczne.imgw.pl EOF
socat ssl:danepubliczne.imgw.pl:443 stdio,ignoreeof << EOF | grep -iC99 'content-.*:' GET /api/data/synop/id/12330/format/json HTTP/1.0 Host: danepubliczne.imgw.pl EOF
socat ssl:danepubliczne.imgw.pl:443 stdio,ignoreeof << EOF | grep -iC99 'content-.*:' GET /api/data/synop/id/12330/format/html HTTP/1.0 Host: danepubliczne.imgw.pl EOF
Dla HTTP opracowano kilka mechanizmów pozwalających klientowi sprawdzić czy podany zasób zmienił się od poprzedniego pobrania go. Pozwala to używać wcześniej zapamiętanych wyników zapytań HTTP będąc pewnym, że zapamiętana wersja jest dalej aktualna. Klient może też podług własnego widzimisię użyć wcześniej zapamiętanej odpowiedzi bez sprawdzania czy zasób na serwerze się zmienił. Prawidłowe cache'owanie odpowiedzi HTTP jest dość złożone, patrz odpowiednie RFC.
Zadanie 3.11 Odpowiedź HTTP może wskazywać w nagłówku Cache-Control czy należy ją w ogóle cache'ować, czy i jak długo można ją używać bez sprawdzania czy dalej jest aktualna, jak również czy może być używana też przez innych użytkowników. Porównaj treść tego nagłówka w wynikach zapytań:
openssl s_client -quiet -verify_quiet put.poznan.pl:443 << EOF | grep -iC25 cache-control: GET / HTTP/1.0 Host: put.poznan.pl EOF
openssl s_client -crlf -quiet -verify_quiet www.pap.pl:443 << EOF | grep -iC25 cache-control: GET / HTTP/1.1 Host: www.pap.pl Connection: close EOF
Zadanie 3.12 Pobierz stronę www.wikipedia.org i znajdź nagłówek Last-Modified:
openssl s_client -quiet -verify_quiet www.wikipedia.org:https << EOF GET / HTTP/1.0 Host: www.wikipedia.org EOF
Następnie ponów zapytanie ustawiając nagłówek If-Modified-Since na datę z poprzedniej odpowiedzi, np:
openssl s_client -quiet -verify_quiet www.wikipedia.org:https << EOF GET / HTTP/1.0 Host: www.wikipedia.org If-Modified-Since: Mon, 16 Dec 2024 16:34:16 GMT EOF
Zadanie 3.13 Poza nagłówkiem Last-Modified, odpowiedź na pierwsze zapytanie z poprzedniego zadania zawierała też nagłówek ETag. Ustawiając w żądaniu nagłówek If-None-Match na poprzednio widziany etag można określić jaką wersją odpowiedzi dysponuje klient:
openssl s_client -quiet -verify_quiet www.wikipedia.org:https << EOF GET / HTTP/1.0 Host: www.wikipedia.org If-None-Match: W/"189ef-62965c05cb200" EOF
Metoda HEAD powinna zwracać wynik identyczny jak GET dla podanego zasobu, w tym, nagłówek Content-Type, ale bez treści (i nagłówków mówiących jak odebrać treść, takich jak Content-Length, Transfer-Encoding czy Content-Encoding).
Zadanie 4.1 Porównaj wynik żądania HEAD i GET o tą samą stonę:
printf "HEAD /jkonczak/ HTTP/1.0\r\nHost: www.cs.put.poznan.pl\r\n\r\n" | socat ssl:www.cs.put.poznan.pl:https -,ignoreeof
printf "GET /jkonczak/ HTTP/1.0\r\nHost: www.cs.put.poznan.pl\r\n\r\n" | socat ssl:www.cs.put.poznan.pl:https -,ignoreeof
Metoda POST powinna być używana do zmiany stanu zasobu, w przeglądarkach
jest używana jako metoda ogólnego przeznaczenia w której klient wysyła dane
do serwera.
Powszechnie używana do przesyłania formularzy (zbudowanych w oparciu o tag HTML
<form>
), jak i np. w formularzach wyszukiwania jeśli informacje o tym co
jest wyszukiwane mogłyby nie zmieścić się w URI (linia żądania ma limit długości,
treść żądania nie ma).
Zadanie 4.2 Porównaj odpowiedź na żądanie o ten sam zasób metodą GET i metodą POST z treścią searchquery=sieci typu application/x-www-form-urlencoded używając przykładowych komend3):
openssl s_client -verify_quiet -quiet pomoc.put.poznan.pl:https << EOF | awk '{if(p)print;else print>"/dev/stderr"};/^\r$/{p=1}' | w3m -T text/html -dump - GET /index.php?/Base/Search/Index HTTP/1.0 Host: pomoc.put.poznan.pl EOF
openssl s_client -verify_quiet -quiet pomoc.put.poznan.pl:https << EOF | awk '{if(p)print;else print>"/dev/stderr"};/^\r$/{p=1}' | w3m -T text/html -dump - POST /index.php?/Base/Search/Index HTTP/1.0 Host: pomoc.put.poznan.pl Content-Type: application/x-www-form-urlencoded Content-Length: 17 searchquery=sieci EOF
Poza używanymi przez przeglądarki GET i POST, standard HTTP definiuje też inne metody, np. PUT, DELETE, PATCH, OPTIONS. Te metody są wykorzystywane w powszechnie stosowanych w usługach internetowych z REST API (więcej o REST znajdziesz np. tutaj).
WebDAV jest rozszerzeniem HTTP o dodatkowe metody pozwalające na zarządzanie plikami, w tym zakładanie blokad. Pozwala to np. podłączyć katalog znajdujący się na zdalnym serwerze jako udział sieciowy (i jest to natywnie wspierane w systemach Windows i MacOS), oczywiście pod warunkiem podłączenia do przygotowanego na to serwera (webdav jest wspierany m. inn. przez ownCloud, Nextcloud i Seafile).
Przypomnienie z wykładu: w odpowiedzi znajduje się numeryczny kod
informujący o stanie wykonania żądania – np. czy się powiodło (2xx), czy
nastąpiło przekierowanie (3xx), bądź czy żądanie nie może zostać obsłużone (4xx)
lub wystąpił błąd po stronie serwera (5xx).
Listę oficjalnych kodów znajdziesz
na stronie organizacji IANA.
Część programów używa też dodatkowych kodów, częściowo zebranych na
wikipedii.
W tej chwili praktycznie wszystkie przeglądarki internetowe mają wbudowane
narzędzia deweloperskie (zwykle dostępne pod skrótem Ctrl+Shift+I
lub z menu kontekstowego każdej strony – ppm/[Narzędzia deweloperskie/]Zbadaj).
Wśród tych narzędzi jest narzędzie Sieć które pokazuje wszystkie żądania
HTTP wraz z odpowiedziami.
Zadanie 5.1 Znajdź w przeglądarce narzędzie wyświetlające wykonane żądania HTTP. Odśwież stronę, żeby zobaczyć listę wykonanych żądań.
Zadanie 5.2 Znajdź żądanie typu GET na które przyszła odpowiedź z treścią. Znajdź nagłówki odpowiedzi i treść odpowiedzi.
Zadanie 5.3 Znajdź żądanie typu POST na liście (jeśli nie widzisz żadnego, odwiedź inne strony). Znajdź nagłówki tego żądania i jego treść, zarówno w przetworzonej i surowej formie.
Zadanie 5.4 Domyślnie otwarcie nowej strony czyści dziennik/log żądań. Odpowiedzią na żądanie POST (np. wygenerowanego przez przycisk wyślij na formularzu) często jest przekierowanie, którego wykonanie czyści listę żądań. Znajdź jak ustawić żeby lista żądań była tylko czyszczona na żądanie użytkownika (opcja nazywa się np. trwałe dzienniki / persistent log).
Zadanie 5.5 Znajdź jak włączyć/wyłączyć działanie cache na czas korzystania z narzędzia deweloperskiego Sieć. Odśwież stronę i zobacz jaką część przeglądarka wzięła z pamięci podręcznej bądź wykonała zapytanie i dostała w odpowiedzi 304 Not Modified.
curl
i wget
to szeroko rozpowszechnione narzędzia pozwalające m. inn. wysyłać zapytania HTTP.
curl url
dla schematu URL http://, https:// lub bez podania
schematu wysyła zapytanie GET o wskazany URL i wypisuje treść na standardowe wyjście.
wget url
dla schematu URL http://, https:// lub bez podania
schematu wysyła zapytanie GET o wskazany URL i zapisuje odpowiedź do pliku.
ściągnij podany URL do pliku o nazwie nazwy ostatnim członem URLa, podążając za przekierowaniami | wget url... | curl -LO url... |
jak wyżej, ale nazwę pliku weź z nagłówka Content-Disposition odpowiedzi HTTP | wget --content-disposition url... | curl -LOJ url... |
ściągnij podany URL do pliku o nazwie nazwa_docelowa | wget -O nazwa_docelowa url | curl -o nazwa_docelowa1 url1 [-o nazwa_docelowa2 url2]... |
kontynuuj (wcześniej przerwane) ściąganie pliku | wget -c … | curl -C- … |
ściągnij podany URL i wypisz treść odpowiedzi na standardowe wyjście, (nie podążając za przekierowaniami) | wget -q -O- --max-redirect=0 url | curl url |
pokaż nagłówki odpowiedzi | wget -S … | curl -i … |
pokaż szczegóły (w tym nagłówki żądania i odpowiedzi) | wget -d … | curl -v … |
wybierz metodę METODA protokołu HTTP | wget --method=METODA … | curl --request METODA … |
ustaw nagłówek User-Agent na agent | wget -U agent … | curl -A agent … |
ustaw dowolny nagłówek Tresc: wartosc | wget --header "Tresc: wartosc" … | curl --header "Tresc: wartosc" … |
podaj treść zapytania nazwa=wartosc | wget --post-data=nazwa=wartosc … patrz też: --post-file / -body-data / -body-file | curl -d nazwa=wartosc … patrz też: --data-… / --form / --json |
wget
potrafi też ściągać rekurencyjnie strony, patrz: wget {-m|-r} [-np] [-k] [-E]
Zadanie 6.1
Pobierz kod HTML wybranej strony za pomocą narzędzia curl
i wget
do pliku.
Wyświetl za pomocą narzędzia curl
i wget
kod HTML strony
http://put.poznan.pl.
Zadanie 6.2
Wykonaj żądanie o stronę http://lindev.cs.put.poznan.pl/ narzędziem curl
lub wget
w taki sposób, żeby na ekranie pojawiły się również nagłówki.
Zadanie 6.3
Wykonaj żądanie POST na URLu https://httpbin.org/post podając w treści
przynajmniej dwie pary klucz-wartość zakodowane jako application/x-www-form-urlencoded
(zarówno wget
jak i curl
domyślnie ustawi ten typ MIME dla żądania POST).
Dla przykładowego kodu HTML: <form action="…"><input type="text" name="imie"><input type="text" name="nazwisko"></form>
przykładowa treść żądania to imie=Jan&nazwisko=Kowalski
.
Nagłówek User-Agent określa oprogramowanie użyte do wykonania zapytania. Przeglądarki (jak i wiele innych klientów HTTP) pozwalają zwykle ustawić własną wartość tego nagłówka. User-Agent bywa używany do wysyłania strony w wersji zoptymalizowanej pod przedstawiającą się przeglądarkę bądź do nieudolnego blokowania dostępu do strony z czegoś innego niż przeglądarka.
Zadanie 7.1
Sprawdź jaką wartość User-Agent mają twoje przeglądarki i jaką wartość
ustawia wget
i curl
. Następnie wykonaj zapytanie programem wget
lub
curl
przedstawiając się jako przeglądarka.
Klient HTTP wpisuje do nagłówka Referer4)
URL który polecił wykonać bieżące żądanie.
Przykładowo jeśli przeglądarka pobrała stronę HTML z adresu
http://example.com/my/site/html i na niej znalazł się znacznik <img>,
to pobierając obrazek ze wskazanego źródła przeglądarka w żądaniu o niego ustawi
Referer: http://example.com/my/site/html (lub URL obcięty wedle uznania
przeglądarki, np. Referer: http://example.com/).
Podobnie dzieje się jeśli będąc na tej stronie użytkownik kliknie na hiperłącze.
Poza zbieraniem informacji kto linkuje daną stronę, Referer bywa używany do
blokowania wykorzystania zasobów przez strony z innych domen (tzn. serwer odmówi
odpowiedzi jeśli Referer nie będzie miał oczekiwanej wartości).
Podobnie działa nagłówek Origin, ustawiany jeśli żądanie spełnia konkretne warunki, tylko z definicji zawiera URL bez nazwy zasobu.
Zadanie 7.2 W narzędziach deweloperskich sprawdź wartość nagłówka Referer np. przechodząc z wyników wyszukiwarki do znalezionej strony.
Strony korzystające z uwierzytelniania HTTP wykorzystują do tego odpowiednie nagłówki - WWW-Authenticate i Authorization.
Zadanie 7.3 Korzystając z narzędziach deweloperskich zobacz jak wygląda HTTP Auth na przykładzie strony z materiałami do wykładów z sieci.
Protokół HTTP pozwala na pobranie wskazanej części (zakresu bajtów) podanego zasobu. Pozwala to np. sensownie wznawiać wcześniej przerwane pobieranie plików.
Zadanie 7.4 Na poniższym przykładzie zobacz jak wygląda sprawdzanie czy dla podanego zasobu można zażądać jego części i jak wygląda żądanie jego części:
socat ssl:www.cs.put.poznan.pl:https,crlf stdio,ignoreeof << EOF | grep -C99 '.*Range.*' HEAD /jkonczak/_media/sk2:sockets.svg HTTP/1.1 Host: www.cs.put.poznan.pl GET /jkonczak/_media/sk2:sockets.svg HTTP/1.1 Host: www.cs.put.poznan.pl Range: bytes=291076-291131 Connection: close EOF
Przez dłuższy czas używano konwencji by nazwy nieustandaryzowanych nagłówków HTTP zaczynać od X-…. Chociaż nie jest do już zalecane, wciąż wiele (szczególnie od dłuższego czasu używających tej konwencji) aplikacji tak zaczyna własne nieustandaryzowane nagłówki.
Zadanie 7.5 Znajdź nagłówki zaczynające się od X-… na https://cat.put.poznan.pl/ lub https://put.poznan.pl/.
Zarówno HTTP/2 jak i HTTP/3 nie przesyłają bezpośrednio danych aplikacyjnych przez warstwę transportu (TCP lub TLS dla HTTP/2 czy UDP dla HTTP/3), tylko przesyłają na warstwie transportu własne ramki w których dopiero są dane.
HTTP/1.x ┃ HTTP/2 ┃ ┌┬────────────────────┬─────────────┬┐ HTTP/3 ┃ ┃ ││ :status: 200 │ tresc odpo ││ ┃ ┃ ││ Content-Length: 16 │ ││ ┃ ┃ │├────────────────────┼─────────────┤│ ┃ ┃ Ramka / ││ NAGŁÓWKI │ TREŚĆ ││ ┌┬───────────────┬┐ ┃ ┃ HTTP/3 \ ││ Długość: 6 │ Długość: 10 ││ ││ wiedzi ││ ┃ ┌────────────────────┬─────────────┐ ┃ (3B) │├────────────────────┴─────────────┤│ │├───────────────┤│ ┃ │ :status: 200 │ tresc odpo │ ┌───────────────┐ ┃ /││ Strumień: 3 ││ ││ Strumień: 3 ││ ┃ │ Content-Length: 16 │ │ │ wiedzi │ ┗━━━━━━━┓ | ││ Długość: 22 ││ ││ Długość: 9 ││ ┌────────────────────┐ ┃ ├────────────────────┼─────────────┤ ├───────────────┤ ┃ Q| ││ Offset: (nieobecne) ││ ││ Offset: 22 ││ │ HTTP/1.1 200 OK │ ┃ │ Strumień: 3 │ Strumień: 3 │ │ Strumień: 3 │ \ ramka ┃ U| ││ Koniec: nie ││ ││ Koniec: tak ││ │ Content-Length: 16 │ ┃ │ NAGŁÓWKI │ TREŚĆ │ │ TREŚĆ │ | HTTP/2 ┃ I| │└──────── TLS ─────────────────────┘│ │└──── TLS ──────┘│ │ │ ┌─────────┐ ┃ │ Długość: 6 │ Długość: 10 │ │ Długość: 6 │ | (ma 9 ┃ C| │ Flagi:… , Numer pakietu:… , │ │ Flagi:… ... │ │ tresc odpo │ │ wiedzi │ ┃ │ Flagi: koniec │ Flagi: 0 │ │ Flagi: koniec │ / bajtów) ┃ \│ Identyfikator połączenia:… , ... │ │ ... ... │ ├────────────────────┤ ├─────────┤ ┃ ├────────────────────┴─────────────┤ ├───────────────┤ ┃ ├────────────────────────────────────┤ ├─────────────────┤ │ TCP/TLS │ │ TCP/TLS │ ┃ │ TCP/TLS │ │ TCP/TLS │ ┃ │ UDP │ │ UDP │ └────────────────────┘ └─────────┘ ┃ └──────────────────────────────────┘ └───────────────┘ ┃ └────────────────────────────────────┘ └─────────────────┘
Każda ramka HTTP/2 wskazuje strumień którego dotyczy – dla uproszczenia można przyjąć że strumienie działają jak osobne połączenia.
HTTP/3 oficjalnie używa protokołu QUIC który używa
protokołu UDP, ale w praktyce QUIC powstał na potrzeby HTTP/3 i mimo lobbowania
za upowszechnieniem go trudno spotkać jego użycie poza HTTP/3.
W HTTP/3 szyfrowaniem komunikacji i dzieleniem na strumienie zajmuje się QUIC,
a ramki HTTP/3 wskazują tylko typ (nagłówki/dane/…) i długość ich PDU.
Nagłówki w HTTP/2 i HTTP/3 są wydajnie kompresowane w sposób skrojony pod HTTP, co istotnie zmniejsza ilość przesyłanych danych.
HTTP/2 i HTTP/3 używa tych samych nagłówków z tym samym znaczeniem co HTTP/1.15). To co wprowadzają nowe wersje HTTP to jedynie zmiana sposobu przesyłania żądań i odpowiedzi.
Zadanie 8.1 Używając wiresharka zobacz jak wyglądają dane wymieniane przez TCP między klientem i serwerem HTTP w wyniku poleceń:
curl -v --http1.1 --head -o/dev/null nghttp2.org
curl -v --http2 --head -o/dev/null nghttp2.org
curl -v --http2-prior-knowledge --head -o/dev/null nghttp2.org
Zadanie 8.2 Używając wiresharka zobacz jak wygląda sekwencyjne i równoległe wykonanie żądań w HTTP/2 spowodowane odpowiednio komendami:
curl -v --http2 nghttp2.org nghttp2.org/documentation/ nghttp2.org/blog/
curl -v --http2 --parallel nghttp2.org nghttp2.org/documentation/ nghttp2.org/blog/
Zadanie 8.3
Poniższe polecenia ściągną trzy strony po HTTP/2 i HTTP/3, zapiszą komunikaty
diagnostyczne curl
a do plików http_2
i http_3
i porównają te pliki.
Sprawdź czy nagłówki zapytań / odpowiedzi różnią się.
curl -sv --http2 --parallel https://nghttp2.org https://nghttp2.org/documentation/ https://nghttp2.org/blog/ >/dev/null 2> http_2 curl -sv --http3-only --parallel https://nghttp2.org https://nghttp2.org/documentation/ https://nghttp2.org/blog/ >/dev/null 2> http_3 git diff --color-words --no-index http_2 http_3
Zadanie 8.4
Stwórz pusty plik o nazwie sslkey.log
w katalogu /tmp
np. komendą:
touch /tmp/sslkey.log
Następnie w wiresharku wejdź, wybierając z menu Edycja pozycję Preferencje,
do ustawień wiresharka.
Tam kliknij na Protocols i znajdź na długiej liście pozycję TLS (możesz
wpisać pierwsze litery po ustawieniu tej części GUI jako aktywne).
W ustawieniach TLS w pole (Pre)-Master-Secret log filename wpisz /tmp/sslkey.log
.
Zmienna środowiskowa SSLKEYLOGFILE respektowana przez curl
(ale też
przeglądarki internetowe) wskazuje nazwę pliku do którego te narzędzia będą
wpisywać dane potrzebne do rozszyfrowania ruchu TLS.
Rozpocznij nasłuchiwanie w wiresharku i wykonaj komendy:
SSLKEYLOGFILE=/tmp/sslkey.log curl -v --http2 --parallel https://nghttp2.org/documentation/ https://nghttp2.org/blog/ SSLKEYLOGFILE=/tmp/sslkey.log curl -v --http3-only --parallel https://nghttp2.org/documentation/ https://nghttp2.org/blog/
Zastosuj kolejno filtry http2
i quic
i prześledź żądanie o podstronę
/blog/ w HTTP/2 i HTTP/3.
Użyj do tego Podążaj / Strumień HTTP/2 oraz Podążaj / Strumień QUIC z menu
kontekstowego odpowiednich pakietów.
Sensowne, dużo obszerniejsze materiały o HTTP znajdziesz tutaj: https://developer.mozilla.org/en-US/docs/Web/HTTP
awk
przerzuca nagłówki do strumienia standardowego błędu, a w3m
rysuje otrzymany kod HTML w konsoli. Zamiast | w3m …
możesz użyć też
| elinks -dump /dev/sdtin
lub | html2text
.