PRZYGOTOWANIE
Czego potrzebujesz
- Zainstalowane curl
- Adres publicznej strony do odczytu; w przykładach example.com
- Terminal; bez tokenów, cookies i danych logowania w poleceniach ćwiczebnych
KROK 01
Najpierw odczytaj nagłówki
Zacznij od sprawdzenia nagłówków odpowiedzi bez pobierania treści strony. Parametr -I wysyła żądanie HEAD, które zwraca tylko nagłówki. To bezpieczny sposób na sprawdzenie kodu statusu, serwera, typu treści i ciasteczek bez obciążania łącza.
Parametr -sS wycisza pasek postępu (-s), ale pokazuje błędy (-S), a --max-time 30 ogranicza czas oczekiwania na odpowiedź do 30 sekund. Dzięki temu polecenie nie wisi bez końca, jeśli serwer nie odpowiada. Wartość 30 sekund to rozsądny limit dla większości zapytań.
Uwaga: nie wszystkie serwery obsługują HEAD w taki sam sposób. Niektóre backendy mogą zwrócić inny kod statusu dla HEAD niż dla GET. Jeśli podejrzewasz rozbieżność, wykonaj GET z -D - -o /dev/null, co też pokaże nagłówki, ale z pełnym przetworzeniem żądania.
curl -sS -I --max-time 30 https://example.com/Wynik zawiera nagłówki odpowiedzi: HTTP/1.1 lub HTTP/2 z kodem statusu, Content-Type, Server, Date, ewentualne ciasteczka i nagłówki cache. Kod 200 oznacza sukces, 301/302 to przekierowanie, 403/404 to błędy dostępu lub brak zasobu.
KROK 02
Sprawdź odpowiedź na zwykłe żądanie GET
Żądanie GET pobiera pełną treść strony, ale w diagnostyce często interesują cię tylko nagłówki i kod statusu. Użyj -D - aby wypisać nagłówki na stdout, -o /dev/null, aby odrzucić treść, oraz -w z formatowaniem, aby wyświetlić końcowy kod statusu HTTP.
Parametr -w pozwala na dodanie własnego tekstu po zakończeniu transferu. W przykładzie wyświetlamy Status HTTP: %{http_code}. Możesz dodać inne zmienne, takie jak %{size_download}, %{speed_download} czy %{content_type}.
Kod zakończenia curl nie jest kodem HTTP. Bez dodatkowych opcji udany transfer odpowiedzi 404 może zakończyć się kodem 0, ponieważ transport zadziałał. Do diagnozy zapisuj osobno wynik polecenia i status HTTP. Opcja --fail może zmienić obsługę błędów HTTP, ale nie stosujemy jej tutaj; nie oznacza ona zakazu odczytania kodu przez -w.
curl -sS --max-time 30 -D - -o /dev/null -w "\nStatus HTTP: %{http_code}\n" https://example.com/Wynik pokazuje nagłówki odpowiedzi, a na końcu wiersz Status HTTP: 200 (lub inny kod). Jeśli widzisz 301, 302 lub 307, strona stosuje przekierowanie. Kod 5xx oznacza błąd serwera.
KROK 03
Prześledź przekierowania
Wiele stron używa przekierowań, np. z HTTP na HTTPS lub z example.com na www.example.com. Aby curl automatycznie podążał za przekierowaniami, użyj parametru -L. Parametr --max-redirs 5 ogranicza liczbę skoków, zapobiegając pętlom przekierowań.
W przykładzie używamy -w do wyświetlenia końcowego adresu URL (%{url_effective}) i liczby wykonanych przekierowań (%{num_redirects}). To pozwala sprawdzić, czy łańcuch przekierowań kończy się na oczekiwanej stronie, czy gdzieś się urywa.
Uwaga: przekierowania mogą prowadzić do zewnętrznych domen. Jeśli testujesz własną stronę, upewnij się, że końcowy adres jest zgodny z oczekiwaniami. Łańcuch przekierowań nie powinien zawierać zewnętrznych serwisów bez twojej wiedzy.
curl -sS -L --max-redirs 5 --max-time 30 -o /dev/null -w "Status: %{http_code}\nAdres: %{url_effective}\nPrzekierowania: %{num_redirects}\n" https://example.com/Wynik pokazuje końcowy kod statusu po przejściu wszystkich przekierowań, ostateczny adres URL oraz liczbę wykonanych skoków. Jeśli liczba przekierowań jest większa niż oczekiwana, sprawdź konfigurację serwera.
KROK 04
Rozdziel pomiary czasu
Aby zmierzyć, ile czasu zajmują poszczególne etapy połączenia, użyj parametru -w z odpowiednimi zmiennymi. time_namelookup to czas rozwiązywania DNS, time_connect to czas nawiązania połączenia TCP, time_starttransfer to czas do pierwszego bajta odpowiedzi, a time_total to całkowity czas transferu.
Pomiary są skumulowane od początku operacji. Time_connect zawiera już wcześniejsze rozwiązywanie nazwy, a time_starttransfer obejmuje więcej niż pracę samej aplikacji. Różnica między tymi wartościami może zawierać TLS, wysłanie żądania, opóźnienia sieci i oczekiwanie na serwer. Nie przedstawiaj jej jako czasu samego szyfrowania. Do tego służą inne dane pomiarowe, niewypisywane w tym przykładzie.
Pojedynczy pomiar to tylko próbka – na czas odpowiedzi wpływa cache DNS, obciążenie sieci i serwera. Nie wyciągaj wniosków o wydajności na podstawie jednego testu. Wykonaj kilka pomiarów w odstępie czasu, aby zobaczyć trend.
curl -sS --max-time 30 -o /dev/null -w "DNS: %{time_namelookup} s\nPołączenie: %{time_connect} s\nPierwszy bajt: %{time_starttransfer} s\nCałość: %{time_total} s\n" https://example.com/Wynik pokazuje wartości w sekundach. Porównuj powtarzane pomiary tej samej strony w podobnych warunkach. Nie ma jednej poprawnej granicy dla każdej lokalizacji i każdego zasobu: plik statyczny, duży transfer i dynamiczna odpowiedź mogą mieć różne czasy. Pojedynczy wolny wynik jest tropem do dalszego sprawdzenia.
KROK 05
Zdiagnozuj TLS bez wyłączania zabezpieczeń
Parametr -v (verbose) włącza szczegółowe logowanie. Zobaczysz wtedy cały proces TLS: negocjację wersji protokołu, wymianę certyfikatów, weryfikację łańcucha zaufania. To kluczowe, gdy certyfikat jest odrzucany przez przeglądarkę, a nie wiesz dlaczego.
Nie dodawaj -k jako rozwiązania problemu z certyfikatem: wyłączenie weryfikacji uniemożliwia sprawdzenie normalnego zachowania klienta. Błąd 60 wskazuje nieudaną weryfikację certyfikatu; przyczyną może być łańcuch zaufania, nazwa hosta, ważność lub lokalna konfiguracja certyfikatów. Błąd 6 oznacza problem rozwiązania nazwy, a 7 nieudane połączenie z hostem lub pośrednikiem.
Szczegółowy wynik może ujawniać wysłane i odebrane nagłówki, adresy oraz wartości ciasteczek, także przy publicznej stronie. Nie publikuj go bez przejrzenia. Zakres informacji o TLS zależy od wersji curl i używanego zaplecza kryptograficznego, dlatego brak jednego konkretnego sformułowania nie wystarcza do stwierdzenia awarii.
curl -v --max-time 30 -o /dev/null https://example.com/Wynik verbose pokazuje szczegóły połączenia: DNS resolution, TCP handshake, TLS handshake z wersją protokołu i certyfikatem, wysłane i odebrane nagłówki. Szukaj fraz SSL connection using, certificate verify ok, Server certificate.
KROK 06
Zapisz wynik i unikaj błędnych wniosków
Kod statusu 2xx nie gwarantuje, że strona działa poprawnie – serwer może zwrócić pustą treść lub stronę błędu w treści, mimo kodu 200. Dlatego warto czasem sprawdzić też rozmiar odpowiedzi (%{size_download}). Jeśli jest zerowy lub bardzo mały, coś może być nie tak.
Przekierowania (3xx) nie są same w sobie błędem. Strona może celowo przekierowywać z HTTP na HTTPS lub z domeny bez www na z www. Problem pojawia się, gdy łańcuch przekierowań prowadzi do błędu 4xx/5xx lub tworzy nieskończoną pętlę.
W automatyzacji używaj kombinacji kodu wyjścia curl i kodu statusu HTTP. Sprawdzaj tylko to, co faktycznie potrzebujesz – nie dodawaj dodatkowych testów, które mogą generować fałszywe alarmy. Pamiętaj, że wyniki mogą się różnić w zależności od lokalizacji geograficznej, pory dnia i obciążenia sieci.
Diagnostyka HTTP wymaga spojrzenia na całość: kod statusu, nagłówki, czas odpowiedzi i treść. Pojedynczy test to tylko punkt wyjścia. W przypadku błędów sprawdź logi serwera i konfigurację firewalla.
Pytania i odpowiedzi
Dlaczego curl z -I zwraca inny kod statusu niż GET?
Niektóre serwery i frameworki traktują HEAD inaczej niż GET. Backend może zwrócić 200 dla HEAD, ale 403 dla GET, jeśli wymagane są dodatkowe nagłówki lub parametry. Aby sprawdzić rzeczywisty kod dla GET, użyj -D - -o /dev/null bez -I.
Co oznacza błąd curl: (60) SSL certificate problem?
To błąd weryfikacji certyfikatu TLS. Przyczyną może być nieaktualna data w systemie, brakujący certyfikat pośredni, certyfikat self-signed lub wygasły certyfikat. Sprawdź datę poleceniem date, a certyfikat przez openssl s_client. Nie używaj -k, bo maskujesz problem.
Czy --max-time obejmuje także nawiązywanie połączenia?
Tak, ogranicza całkowity czas operacji, także etap połączenia. Oddzielny --connect-timeout pozwala wyznaczyć krótszy limit dla samego nawiązywania połączenia. W pewnych kompilacjach szczegóły przerywania rozwiązywania DNS zależą od resolvera, ale nie zmienia to znaczenia --max-time na limit obejmujący wyłącznie pobieranie treści.