Narzędzia użytkownika

Narzędzia witryny


Pasek boczny


O mnie


Dydaktyka:

Feedback


sk2:http

To jest stara wersja strony!


Hypertext Transfer Protocol

Zanim zaczniesz...

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.

"Hello World"

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

Zmiana <LF> na <CR><LF>, HTTPS, percent encoding

Narzędzie nc / netcat1) 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:

Conceptually, HTTP/TLS is very simple. Simply use HTTP over TLS precisely as you would use HTTP over TCP.

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";'

Nagłówki HTTP (1/2)

Nagłówek "Host"

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?

Ciastеczka

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

[ekstra] Nagłówki "Accept..."

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

Nagłówki opisujące treść

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

[ekstra] Cache

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

Metody HTTP

GET i HEAD

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

POST

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

[ekstra] Inne metody

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).

Kody odpowiedzi

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.

Przeglądarka + zbadaj/inspect

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.

Narzędzia curl i wget

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.

[ekstra] Nagłówki HTTP (2/2)

User-Agent

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.

Referer

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.

HTTP Authentication

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.

Range i Content-Range

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

X-…

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/.

Nowsze wersje HTTP

[ekstra] Przypomienie z wykładu

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.

HTTP/2

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/

HTTP/3

Zadanie 8.3 Poniższe polecenia ściągną trzy strony po HTTP/2 i HTTP/3, zapiszą komunikaty diagnostyczne curla 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.

Misc

Sensowne, dużo obszerniejsze materiały o HTTP znajdziesz tutaj: https://developer.mozilla.org/en-US/docs/Web/HTTP

1) A przynajmniej popularniejsze z jego implementacji.
2) , 3) W potoku 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.
4) Nazwa nagłówka jest zapisanym z błędem angielskim słowem referrer. Zauważ że nagłówek który mówi czy i kiedy klient ma podawać nagłówek Referer nazywa się (już bez literówki) Referrer-Policy.
5) Z nielicznymi wyjątkami wynikającymi z różnić w działaniu tych protokołów, np. Transfer-Encoding: chunked ma zastosowanie tylko w HTTP/1.1.
sk2/http.1735992916.txt.gz · ostatnio zmienione: 2025/01/04 13:15 (edycja zewnętrzna)