10 trików cURL, które warto znać

Jak skopiować curl request z przeglądarki

Kontrynuując poprzedni wpis, który wprowadzał podstawy curl czas na bardziej zaawansowane techniki i triki, które warto dodać do naszych umiejętności.

Czy jesteś programistą, testerem czy po prostu użytkownikiem curl’a, który ułatwia sobie pracę z API – ten wpis może Ci się przydać!

Przy okazji muszę Wam wspomnieć: Julia Evans tworzy cudowne, rysowane cheatsheets dla różnych narzędzi sieciowych, komend terminala (linux/unix), jakiś czas temu zrobiła taką ściągę dla curl:

Jeśli jeszcze jej nie znacie koniecznie zajrzyjcie na wizardzines.com

Spis trików:

  1. Odpowiedź z nagłówkami serwera
  2. Dokumentacja curl zawsze pod ręką
  3. Wysyłanie formularzy z poziomu terminala
  4. Przesyłanie plików przez curl
  5. Pobieranie pliku przez curl
  6. Wznowienie pobierania pliku
  7. Pobieranie wielu plików na raz
  8. Pobieranie wielu plików na podstawie listy linków
  9. Wyświetlenie paska postępu pobierania
  10. Generowanie i automatyzacja adresów URL
  11. Bonus trik – skopiuj curl prosto z przeglądarki

1. Odpowiedź z nagłówkami serwera

Jeżeli wyślemy zapytanie GET do API za pomocą curl w podstawowy sposób otrzymamy coś takiego:

curl example.com

i w odpowiedzi kod HTML tej strony

<!doctype html>
<html>
<head>
    <title>Example Domain</title>

    <meta charset="utf-8" />
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style type="text/css">
    body {
...

Jednak możemy skorzystać z opcji -i albo --include, aby otrzymać również nagłówki odpowiedzi serwera

curl -i example.com

wynik:

HTTP/1.1 200 OK
Age: 557583
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Thu, 16 Feb 2023 15:18:07 GMT
Etag: "3147526947+ident"
Expires: Thu, 23 Feb 2023 15:18:07 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (nyb/1D18)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256

<!doctype html>
<html>

Może też być tak, że interesują nas tylko nagłówki, a treść odpowiedzi chcemy pominąć, wówczas powinniśmy użyć opcji -I (--head) czyli tryb „info only”.

curl -I example.com

2. Dokumentacja curl zawsze pod ręką

Dokumentacja online curl’a nie jest moją ulubioną. Uczciwie powiem, że źle mi się ją przegląda, na szczęście wersja konsolowa jest znacznie przyjemniejsza i na wyciągnięcie jednej opcji

  • curl -h – aby otrzymać skrócone podpowiedzi najpopularniejszych opcji curl
  • curl -h all – aby sprawdzić wszystkie opcje z krótkimi opisami
~$ curl -h

Usage: curl [options...] <url>
 -d, --data <data>            HTTP POST data
 -f, --fail                   Fail silently (no output at all) on HTTP errors
 -h, --help <category>        Get help for commands
 -i, --include                Include protocol response headers in the output
 -o, --output <file>          Write to file instead of stdout
 -O, --remote-name            Write output to a file named as the remote file
 -s, --silent                 Silent mode
 -T, --upload-file <file>     Transfer local FILE to destination
 -u, --user <user:password>   Server user and password
 -A, --user-agent <name>      Send User-Agent <name> to server
 -v, --verbose                Make the operation more talkative
 -V, --version                Show version number and quit

This is not the full help, this menu is stripped into categories.
Use "--help category" to get an overview of all categories.
For all options use the manual or "--help all".

3. Wysyłanie formularzy z poziomu terminala curlem

Jeśli wylistujecie wszystkie opcje na pewno zauważycie opcję -F, --form – to opcja, która pozwala wypełnić formularz by przesłać wiadomość.

Załóżmy, że mamy taki prosty formularz rejestracji:

<form action="/register" method="POST">
  <input type="text" name="username">
  <input type="email" name="email">
  <input type="submit" value="Submit">
</form>

Zapewne aby go przetestować wykonamy następujące zapytanie, które ma zasymulować zachowanie przycisku wyślij (submit):

curl -X POST example.com/register \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "username=testUser&[email protected]"

Nie musimy dodawać -H "Content-Type: application/x-www-form-urlencoded", bo to nagłówek domyślny.

Podany typ application/x-www-form-urlencoded oznacza, że treść żądania HTTP wysłana do serwera będzie jednym długim query stringiem czyli parami klucz=wartość odzielonymi ampersandem (&).
Co zresztą widzimy w zapytaniu jako: "username=testUser&[email protected]"

Ok, ale co jeśli mam naprawdę długi query string, albo chcę wysłać plik w załączniku za pomocą curl?

Wówczas wracamy do opcji -F.

→ wysłanie formularza metodą POST za pomocą flagi -d curl

curl -X POST example.com/register \
     -d "username=testUser&[email protected]"

→ wysłanie formularza metodą POST za pomocą flagi -F curl,
wówczas metoda -X POST jest opcjonalna:

curl example.com/register \
   -F "username=testUser" \
   -F "[email protected]"

Zgodnie z dokumentacją form typ application/x-www-form-urlencoded nie jest odpowiedni kiedy chcemy przesłać dane binarne (nie alfanumeryczne np. plik) lub po prostu duży payload. Wówczas należy skorzystać z typu multipart/form-data

curl przesyłanie danych do znacznika form

Tu przykład przesłania formularza od razu z wgraniem obrazka:

curl example.com/register \
   -F "username=testUser" \
   -F "[email protected]" \
   -F "[email protected]"

a to prowadzi nas do kolejnego punktu …

4. Przesyłanie plików przez curl

Możemy wgrać / przesłać plik lokalny przez komendę curl. Możemy dodać plik, który znajduje się u nas w tej samej lokalizacji co wykonujemy komendę curl, nazwa pliku musi być poprzedzona znakiem @.

Posłużę się podobnym przykładem:

curl example.com/upload \
     -F "[email protected]"

ale można też wprost dodać wszystkie opcje (metodę POST i content type):

curl -X POST example.com/upload \
     -H "Content-Type: multipart/form-data" \
     -F "[email protected]"

5. Pobieranie pliku przez curl

Możemy pobrać plik z tą samą nazwą, co oryginalny plik znajdujący się na serwerze.
Parametr -O / --remote-name wskazuje (binarny) plik źródłowy, więc jeśli go nie przekażesz, curl nie będzie mógł go pobrać i zwróci błąd (a w najlepszym wypadku uda mu się wykonać podstawowego GETa).

curl -O example.com/file.pdf

Na przykład pobierzmy ściągę z narzędziami konsolowymi:

curl -O https://wizardzines.com/networking-tools-poster.pdf

vs gdy zapomnisz -O:

curl https://wizardzines.com/networking-tools-poster.pdf

Przykład, który pobierze wam plik o nazwie 000-adr-template.md:

~$ curl -O https://gist.githubusercontent.com/ritaly/1d15b6c96c6bae86597684864ba85e6e/raw/96bfc801ec386de1ae9b331f9e87d97f0e452384/000-adr-template.md

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   379  100   379    0     0   3131      0 --:--:-- --:--:-- --:--:--  3828

% — pokazuje stan pobierania w procentach;
Total — pokazuje stan pobierania w bajtach (dodatkowe M będzie oznaczało w megabajtach);

Pobieranie pliku przez curl z nadaniem nowej nazwy

Drobny myk z opcją -o czyli pobranie pliku pod inną nazwę niż ta, pod którą plik jest na serwerze:

curl example.com/file.pdf -o new_file.pdf

6. Wznowienie pobierania pliku

Jeżeli z jakiegoś powodu zaczęliśmy pobierać plik i nastąpiła przerwa, możemy kontynuuować

curl -C - -O  example.com/file.pdf

7. Pobieranie wielu plików na raz

curl -O example.com/file1.pdf \
     -O example.com/file2.pdf \
     -O example.com/fileX.txt

8. Pobieranie wielu plików na podstawie listy linków

Przy wielu plikach, które chcemy pobrać, możemy stworzyć przykładowy plik z linkami i pobrać wszystko jedną komendą.

Załóżmy, że mamy plik myurls.txt, który zawiera link każdy od nowej linii

example.com/file1.pdf
example.com/file2.pdf
example.com/fileX.txt

Możemy w terminalu wykonać następującą operację:

xargs -n 1 curl -O < myurls.txt

9. Wyświetlenie paska postępu pobierania

Masz setkę plików do pobrania i chcesz wiedzieć jaki % udało się pobrać? Albo twój plik jest naprawdę duży?
Nie ma sprawy! Opcja -# dodaje pasek postępu

curl -# -O example.com/hugefile.pdf

np.

curl -# -O https://jvns.ca/wizard-zine.pdf

A w gratisie macie super zin od Julii Evans do poczytania 😉

URL globbing czyli generowanie i automatyzacja odpytywania adresów URL curl’em

Curl posiada pewną opcję, która może być zastosowana do najprostrzych sanity testów i innych ciekawych automatyzacji, a o której sama dowiedziałam się dość późno czyli właśnie URL globbing.

Potrzebujemy zakresu adresów URL, które są w większości takie same – tylko niewielka ich część zmienia się między żądaniami. Przykładem może być np. sprawdzenie czy wszystkie url danego zakresu (zakres liczbowy, zestaw nazw) na stronie odpowiadają 200, wiemy, że adresy są stałe i mają format example.com/[rok]/[miesiac]/posts

Aby przekazać zakres liczbowy musimy użyć nawiasów kwadratowychPrzetestujcie ten przykład:

curl https://jsonplaceholder.typicode.com/posts/[1-5]

(w zależności od używanej konsoli może dodatkowo wymagać eskapowania nawiasów [], na macu nie mam tego problemu, ale na windowsie konsola może się upomnieć o backslash lub należy użyć cudzysłów)

curl https://jsonplaceholder.typicode.com/posts/\[1-5\]
curl "https://jsonplaceholder.typicode.com/posts/[1-5]"

curl automatycznie odpyta endpointy dla postów od 1 do 5.

Zamiast odpytywać co 1 id, nic nie stoi na przeszkodzie, by dodać parametr „co krok” po dwukropku :. Np. chcemy sprawdzić co trzeci post:

curl "https://jsonplaceholder.typicode.com/posts/[1-20:3]"

Możemy przekazać konkretny zakres np. id = 3, 10, 25, 8, do tego użyjemy nawiasów klamrowych do przekazania listy parametrów.
Terminal zaznaczy wam klamry jako znak specjalny, więc należy je wyeskapować lub użyć cudzysłów

curl https://jsonplaceholder.typicode.com/posts/\{3,10,25,8\}
curl "https://jsonplaceholder.typicode.com/posts/{3,10,25,8}"

Wynik tego zapytania możemy zapisać do pliku zapomocą opcji -o, co więcej możemy zautomatyzować to zapisywanie tak by każdy wynik otrzymał własny plik wynikowy wystarczy, że stworzymy wzorzec wykorzystując znak #1, to miejsce zostanie zastąpione kolejnymi wartościami z naszego zakresu

curl https://jsonplaceholder.typicode.com/posts/\{3,10,25,8\} -o output#1.txt
curl "https://jsonplaceholder.typicode.com/posts/{3,10,25,8}" -o output#1.txt

curl automatyzacja odpytywania adresów url

Jeśli dodatkowo połączymy to z paskiem progresu -#, to widzimy jak kolejne zapytania się ładują:

curl https://jsonplaceholder.typicode.com/posts/\{3,10,25,8\}/ -o output#1.txt -#

Możemy też w ten sposób pobierać pliki

curl -O "http://example.com/img/[001-100].png"

czy łączyć zakresy liczbowe, z zakresem alfabetycznym czy listą parametrów:

curl -O "http://example.com/{alfa,beta,gamma,delta}/[100-600:50]x[100-600:50].jpg"

Wracając do pierwszego przykładu: example.com/[rok]/[miesiac]/posts

jeśli rok byłby w formacie YYYY w zakresie od 2013-2023 i miesiące w formacie MM, wystarczy:

curl -O "http://example.com/[2013-2023]/[01-12]"

BONUS: Jak skopiować zapytanie HTTP z przeglądarki jako curl?

Zupełnie o tym zapomniałam, ale wstawiając na początku posta tweeta Julii uznałam, że to na pewno warty polecenia trick.

Możemy skopiować jako komendę curl, dowolne żądanie HTTP, które wykonuje się w naszej przeglądarce – Chrome / Firefox czy Safarii, choć przypuszczam, że też inne przeglądarki też umożliwają taką opcję.

  1. Otwórz DevTools zakładkę Network („Sieć” jeśli używasz wersji polskiej) .
  2. Prawym przyciskiem myszy (lub kliknij z wciśniętym klawiszem Ctrl) na request.
  3. Kliknij „Kopiuj” → Kopiuj jako cURL

jako skopiować request http jako curl z przeglądarki