|
|
Treść niniejszego dokumentu zakłada że czytający jest obeznany z sieciami komputerowymi i HTML.
Możliwość pisania skryptów jest nieodzowna w dobrym systemie
operacyjnym. Unix, zawdzięcza swoją wysoką pozycję właśnie dzięki
możliwości stosowania skryptów powłoki i rozmaitych narzędzi do
wykonywania rożnych zautomatyzowanych poleceń i skryptów.
Rosnąca ilość aplikacji opartych na sieci uczyniła "Skryptowanie HTTP" coraz
częściej wymaganą i poszukiwaną umiejętnością. Zdolność do zupełnie automatycznego
pozyskiwania informacji z sieci, imitacja użytkownikow, wysyłanie żądań lub danych
do serwerów są ważnymi zadaniami w dzisiejszych czasach.
Curl jest narzędziem linii poleceń wykorzystywanym do wszelkich manipulacji URL i
transferów danych, lecz ten dokument skupia się jedynie na wykorzystywaniu żądań
HTTP dla zabawy i zysku. Zakładam ze wiesz jak korzystać z wywolań 'curl --help'
lub 'curl --manual' by uzyskać podstawowe informacje.
Curl nie zostało napisane by zrobić za ciebie wszystko. Curl wykonuje żądania,
pobiera i wysyła dane, wysyła dane, uzyskując w zamian informacje. Prawdopodobnie
musisz skleić te wszystkie czynności przy pomocy jakiegoś języka skryptowego lub
powtarzanymi wywołaniami z klawiatury.
1. Protokół HTTP
HTTP to protokół używany do przechwytywania danych z serwerów. Jest bardzo prostym protokołem
zbudowanym na podstawie TCP/IP. Protokół ten zezwala również na wysyłanie informacji do
serwera od klienta przy użyciu kilku różnych metod opisanych w tym dokumencie.
HTTP jest zwyczajnymi liniami tekstu kodowanego w ASCII, wysyłanymi przez klienta do serwera
by zażądać szczególnej akcji. W odpowiedzi serwer wysyła najpierw kilka linii
tekstu zanim rozpocznie wysyłanie właściwej zawartości żądania.
Użycie opcji curl -v spowoduje wyświetlenie wszystkich komend jakie curl wysyła
do serwera, jak również kilka innych tekstów informacyjnych. Opcja -v jest jedną
z bardziej użytecznych opcji przy odpluskwianiu, lub nawet zrozumieniu interakcji
curl <-> serwer.
2. URL
The Uniform Resource Locator, co w polskim tłumaczeniu oznacza ujednolicony format
adresowania zasobów, czyli adres jakiejś konkretnej informacji w internecie. Znasz je,
napewno widziałeś adresy URL takie jak http://curl.haxx.se lub https://twojbank.pl
milion razy.
3. Uzyskanie Strony (GET)
Najprostszym i najczęstszym żądaniem/operacją dokonywaną przy użyciu HTTP jest właśnie
pozyskiwanie URL. URL może odnosć się do strony internetowej, jak również obrazka lub
pliku. Klient wydaje polecenie GET do serwera i otrzymuje dokument uwzględniony w żądaniu.
Gdy wpiszemy w linii komend:
curl http://curl.haxx.se
Otrzymamy stronę internetową na terminalu. Cały dokument HTML znajdujący się pod
wskazanym URL.
Wszystkie odpowiedzi HTTP serwera zawierają zestaw nagłówków, które normalnie są
ukryte. Użyj opcji curl -i by wyświetlić je razem z resztą dokumentu. Możesz również
zażądać od serwera TYLKO nagłówków dzięki opcji -I (co pozwoli curl wydać żądanie HEAD).
4. Formularze
Formularze są głównym sposobem by umieścić w dokumencie HTML pola w które użytkownik może wpisać
dane, a następnie za pomocą przycisku 'OK' lub 'Submit' przesłać te dane do serwera. Następnie
serwer na podstawie otrzymanych danych podejmuje decyzję co robić dalej. Czyli na przykład użyć
wpisanych słów do przeszukiwania bazy danych, lub dodać jakąś informację do systemu śledzenia
pluskiew (bug track), czy też wyświetlić podany adres na mapie, albo użyć podane informacje jako dane
dla monitu logowania by zweryfikować czy użytkownik ma dostęp do danych które chce zobaczyć.
Oczywiście na serwerze musi działać odpowiedni program, który odpowiednio obsłuży dane które wysyłasz.
4.1 GET
Formularz korzystający z metody GET w dokumencie HTML może wyglądać tak:
<form method="GET" action="junk.cgi"> <input type=text name="birthyear"> <input type=submit name=press value="OK"> </form>
W twojej ulubionej przeglądarce ten formularz ukaże się jako pole tekstowe do wypełnienia i przycisku
z etykietą "OK". Jeżeli wpiszesz '1905' i nacisniesz przycisk OK, twoja przeglądarka utworzy z danych formularza nowy adres
URL. Adres: "junk.cgi?birthyear=1905&press=OK" zostanie dodany do poprzedniego URL.
Jeżeli formularz pochodził ze strony "www.hotmail.com/when/birth.html", to następna strona którą
pobierze twoja przeglądarka będzie miała adres "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK".
Tak działa większość mechanizmów wyszukiwania.
By za pomocą curl wypełnić formularz korzystający z metody GET, po prostu utwórz oczekiwany adres URL:
curl "www.hotmail.com/when/junk.cgi?birthyear=1905&press=OK"
4.2 POST
Podczas wysyłania formularza metodą GET, wszystkie dane wpisane w pola tekstowe są widoczne w pasku adresu
twojej przeglądarki. Jest to przydatne głównie w sytuacji gdy chcemy dodać do zakładek adres strony wraz
z przekazanymi zmiennymi z formularza, ale z oczywistych względów nieodpowiednie gdy w jednym z pól podajemy
poufne dane, a zaś formularz z dużą ilością pól wygeneruje bardzo długi i nieczytelny URL.
W tym przpadku protokół HTTP oferuje metodę POST. Przy użyciu tej metody dane wprowadzone przez klienta są
przesyłane poza adresem URL, co sprawia że nie są widoczne w polu adresu przeglądarki.
Formularz taki jest bardzo podobny do tego, który korzystał z poprzedniej metody:
<form method="POST" action="junk.cgi"> <input type=text name="birthyear"> <input type=submit name=press value=" OK "> </form>
Więc by użyć curl do wypełnienia takiego formularza tymi samymi danymi co poprzednio, mogli byśmy zrobić to tak:
curl -d "birthyear=1905&press=%20OK%20" www.hotmail.com/when/junk.cgi
Ten rodzaj POST użyje Content-Type application/x-www-form-urlencoded, co jest najczęściej używaną metodą POST.
Dane, które wysyłasz do serwera MUSZĄ być odpowiednio zakodowane, curl nie zrobi tego za ciebie. Na przykład, jeżeli chcesz
by wysyłane dane zawierały spacje, musisz zastąpić je %20 etc. Nie zastosowanie się do tej zasady naogół powoduje
pomieszanie i ogólnie mówiąc niepoprawny odbiór danych przez serwer.
Ostatnie wersje curl są w stanie zakodować dane POST do url:
curl --data-urlencode "name=I am Daniel" www.example.com
4.3 File Upload POST
Pod koniec 1995 roku zdefiniowano dodatkowy sposób by przesyłać dane przez HTTP.
Sposób ten udokumentowano w opisie standardu RFC 1867, toteż metodę tą nazywa się czasami RFC1867-posting.
Metodę tą zaprojektowano głównie w celu ulepszenia obsługi
przesyłania plików do serwera. Formularz, którry zezwala użytkownikowi
na wysyłanie plików może mieć taką postać w HTML:
<form method="POST" enctype='multipart/form-data' action="upload.cgi"> <input type=file name=upload> <input type=submit name=press value="OK"> </form>
Ten formularz wyraźnie określa że dane które mają zostać przesłane mają typ zawartości (Content-Type) multipart/form-data.
By wwysłać powyższy formularz z poziomu curl wpisz następujące polecenie:
curl -F upload=@localfilename -F press=OK [URL]
4.4 Ukryte Pola
Aplikacje oparte o HTML by przekazywać informacje między
stronami korzystają w większości przypadków z ukrytych pól formularza.
Ukryte pola są wypełnionymi, nie widocznymi dla użytkownika polami
formularza i przesyłane w taki sam sposób jak wszystkie pozostałe pola.
Przykładowy formularz z jednym polem widocznym, jednym ukrytym i przyciskiem submit może wyglądać tak:
<form method="POST" action="foobar.cgi"> <input type=text name="birthyear"> <input type=hidden name="person" value="daniel"> <input type=submit name=press value="OK"> </form>
By wysłać to przez curl, nie musisz się zastanawiać czy pola są ukryte czy nie. Dla curl wszystkie są takie same:
curl -d "birthyear=1905&press=OK&person=daniel" [URL]
4.5 Jak Sprawdzić Zawartość Danych POST
Gdy masz zamiar użyć curl zamiast przeglądarki do wypełnienia formularza, konieczne jest wysyłanie danych POST dokładnie w
taki sam sposób w jaki robi to twoja przeglądarka.
Prostym sposobem by zobaczyć te dane jest zapisanie na twardy
dysk dokumentu HTML z formularzem, zamiana parametru 'method' na GET, i
wciśnięcie przycisku wysyłania (można także zmienić URL parametru
'action').
Otrzymasz wtedy dane dołączone do URL, oddzielone znakiem '?' tak samo jak w przypadku formularzy GET.
5. PUT
Prawdopodobnie najlepszym sposobem na wysyłanie danych do serwera HTTP jest użycie PUT. Również w tym przypadku na serwerze
konieczna jest obecność programu lub skryptu który potrafi odebrać strumień danych HTTP PUT.
Umieszczenie pliku na serwerze HTTP za pomocą curl:
curl -T uploadfile www.uploadhttp.com/receive.cgi
6. Uwierzytelnianie HTTP
Uwierzytelnianie HTTP to możliwość przekazania do serwera swojej nazwy użytkownika i hasła by mógł zweryfikować
czy dany użytkownik ma uprawnienia wymagane do spełnienia żądania. Standardowa autentykacja używana w HTTP
(która jest również domyślną w curl) jest oparta o *plain* *text*, co oznacza że przekazuje nazwę użytkownika
i hasło odrobinę zamaskowane, więc nadal w pełni czytelne dla każdego kto przechwyci pakiety na trasie
między tobą a serwerem.
By kazać curl użyć nazwy użytkownika i hasła do autentykacji:
curl -u name:password www.secrets.com
Strona może wymagać innej metody autentyfikacji (sprawdź nagłówki zwrócone przez serwer)i następnie wybierz
z opcji: --ntlm, --digest, --negotiate lub nawet --anyauth odpowiednią dla ciebie.
Czasami twój dostęp do HTTP jest możliwy jedynie przez użycie HTTP proxy. Co zdaje się być szczególnie
powszechne w różnych firmach. HTTP proxy może wymagać swojej własnej nazwy użytkownika i hasła by
zezwolić użytkownikowi na dostęp do internetu. By określić to za pomocą curl, zastosuj coś takiego:
curl -U proxyuser:proxypassword curl.haxx.se
Jeżeli twój proxy wymaga by autentykacja odbyła się przy użyciu metody NTLM, użyj opcji --proxy-ntlm,
w przypadku Digest zastosuj --proxy-digest.
Jeżeli użyjesz jednej z opcji operującej na nazwie użytkownika+haśle bez podania hasła, curl zarząda
hasła interaktywnie.
Zauważ że gdy program jest uruchomiony, jego parametry są możliwe do odczytania z listy aktywnych
procesów systemu. Toteż inni użytkownicy mają możliwość podejrzenia twoich haseł jeżeli przekażesz
je jako opcje w formie zwykłego tekstu. Są jednak sposoby by to obejść.
Wiedza o tym jak działa autentykacja HTTP jest nic nie warta, gdyż bardzo wiele stron nie stosuje
tego rozwiązania gdy zapewniają loginy etc. Zobacz zamieszczony poniżej rozdział Web Login by
poznać więcej szczegółów.
7. Polecający (Referer)
Żądanie HTTP może zawierać pole 'referer', które może być użyte by określić z jakiego URL klient
został pokierowany by uzyskać dany zasób. Niektóre programy/skrypty sprawdzają wartość pola
'referer' zawartego w żądaniu by określić czy nadeszło z zewnętrznej strony, czy też z nieznanej
strony. Chociaż głupotą jest sprawdzanie czegoś tak łatwo podrabialnego, wiele skryptów wciąż
to robi. Używając curl możesz wstawić co tylko zechcesz w pole 'referer', czyli ułatwić sobie
możliwość by oszukać serwer i nakłonić do obsługi twojego żądania.
W ten sposób curl wypełnia pole 'referer':
curl -e http://curl.haxx.se daniel.haxx.se
8. User Agent
Wszystkie żądania HTTP mogą ustawiać bardzo podobne do pola referer, pole User-Agent. Pole to
określa jaki przedstawiciel użytkownika (ang. user agent) (klient) został użyty. Wiele aplikacji
korzysta z tej informacji by zadecydować w jaki sposób wyświetlać strony. Głupi programiści
sieciowi próbują tworzyć różne wersje stron dla użytkowników różnych przeglądarek by wyglądały
możliwie jak najlepiej w poszczególnych przeglądarkach. Używają też zazwyczaj różnych rodzajów
javascript, vbscript etc.
Z czasem przekonasz się że uzyskiwanie strony przez curl nie zwraca takiej samej strony, jak
w przypadku otwarcia jej przeglądarką. Bedzie to odpowiedni moment na ustawienie pola User Agent
by serwer myślał że jesteś jedną z tych przeglądarek.
Aby curl udawało Internet Explorer pod kontrolą Windows 2000:
curl -A "Mozilla/4.0 (compatible;MSIE 5.01; Windows NT 5.0)" [URL]
Albo czemu by nie zaimitować Netscape 4.73 pod kontrolą Linux (P III):
curl -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" [URL]
9. Przekierowania
Gdy żądamy od serwera jakiegoś zasobu, odpowiedź serwera może zawierać wskazówkę określającą
gdie przeklądarka powinna się udać by odnaleźć tą stronę, lub nową stronę z nowo wygenerowaną
zawartością. Nagłówek, który przekierowuje przeglądarke to Location:.
Curl domyślnie nie podąża za nagłówkami Location:, więc po prostu wyświetli takie strony
w taki sam sposób jak wszystkie inne odpowiedzi HTTP. Oczywiście istnieje opcja umożliwiająca
podążanie za odnośnikami z nagłówków Location:.
W tym przypadku curl będzie podążało za Location:
curl -L www.sitethatredirects.com
Jeśli masz zamiar użyć curl do wysłania danych POST na stronę, która niezwłocznie przekierowuje
cię na następną stronę, możesz bez obaw użyć jednocześnie opcji -L i -d/-F. Curl zastosuje metodę
POST tylko dla pierwszego żądania, a następnie powróci do GET w następnych operacjach.
10. Cookies
Sposobem w jaki przeglądarki kontrolują status i preferencje użytkownika jest użycie cookies (ciasteczka).
Cookies to po prostu nazwy z przypisaną im treścią. Cookies są wysyłane przez serwer do klienta. Serwer
informuje klienta pod jaką ścieżkę (path) i nazwę hosta, mają zostać odesłane cookies. Serwer wysyła
również datę wygaśnięcia cookies i kilka innych właściwości.
Gdy klient komunikuje się z serwerem korzystając z nazwy hosta i ścieżki zachowanej w uprzednio odebranym
cookie, klient odsyła cookies i ich treść do serwera, o ile oczywiście ich ważność nie wygasła.
Wiele aplikacji i serwerów używa tej metody by połączyć serię żądań w jedną logiczną sesję. By wykorzystać
curl w takich przypadkach, musimy mieć możliwość zapisywania i wysyłania cookies w sposób w jaki oczekuje
tego aplikacja. Czyli dokładnie w taki sam sposób w jaki robi to przeglądarka.
Najprostszym sposobem na wysłanie kilku cookies do serwera podczas "otwierania" strony przez curl jest
dodanie ich do linii poleceń np. tak:
curl -b "name=Daniel" www.cookiesite.com
Cookies są przesyłane jako zwyczajne nagłówki HTTP. Jest to korzystne, gdyż pozwala curl zapisywać cookies, zapisując po prostu nagłówki. By curl zapisało cookies użyj opcji -D, na przykład tak:
curl -D headers_and_cookies www.cookiesite.com
(Zwróć uwagę że opcja -c opisana poniżej jest lepszym sposobem by przechowywać cookies.)
Curl posiada wbudowany, w pełni funkcjonalny silnik parsowania cookies, który przydaje się gdy chcesz ponownie
połączyć się z serwerem i użyć cookies zachowane z poprzedniego połączenia (bądź też wykonane własnoręcznie
by ogłupić serwer by uwiezrył że miałeś poprzednie połączenie). By wykorzystać uprzednio zachowane cookies,
uruchom curl w ten sposób:
curl -b stored_cookies_in_file www.cookiesite.com
Działanie "ciasteczkowego silnika" następuje gdy używasz curl z opcją -b. Jeżeli chcesz by curl jedynie zrozumiało otrzymane cookies, użyj -b z nazwą nie istniejącego pliku. Przykładowo, gdy chcesz by curl jedynie przechwyciło cookies ze strony, a następnie podążyło za przekierowaniem (i ewentualnie odesłało otrzymane cookies), zrób to tak:
curl -b nada -L www.cookiesite.com
Curl jest zdolne by odczytywać i zapisywać pliki cookie które używają pliku w formacie, w jakim obsługują je Netscape i Mozilla. Jest to wygodne rozwiązanie w przypadku gdy chcemy dzielić cookies między przeglądarkami a automatycznymi skryptami. Przełącznik -b automatycznie wykrywa czy podany plik z cookies jest właśnie takim plikiem i przetwarza go, zaś w przypadku gdy użyjemy opcji -c/--cookie-jar, curl utworzy nowy plik podczas kończenia operacji:
curl -b cookies.txt -c newcookies.txt www.cookiesite.com
11. HTTPS
Jest kilka sposobów na zabezpieczenie transferu HTTP. Najczęściej używanym protokołem do tego celu jest HTTPS,
czyli HTTP oparte o SSL. SSL szyfruje dane wysyłane i odbierane przez sieć, co zmniejsza szanse atakujących
sieć, na przechwycenie poufnych informacji.
SSL (bądź też TLS, jak nazwano najnowszą wersję tego standardu) oferuje masę zaawansowanych funkcji koniecznych
do tych wszystkich szyfrowań i infrastruktury mechanizmów kluczy wymaganych do szyfrowania HTTP.
Curl wspiera odbiór szyfrowanych danych dzięki swobodnie (darmowo) dostępnym bibliotekom OpenSSL. By pobrać stronę
z serwera HTTPS po prostu uruchom curl w ten sposób:
curl https://that.secure.server.com
11.1 Certyfikaty
W świecie HTTPS, używa się certyfikatów by udowodnić że jesteś tym za kogo się podajesz, łącznie z normalnymi
hasłami. Curl wspiera certyfikaty klienta. Wszystkie certyfikaty są zablokowane hasłem, które musisz podać przed
użyciem certyfikatu przez curl. Hasło może zostać określone w linii poleceń, lub podane interaktywnie gdy zapyta
o nie curl. Certyfikatów na serwerze HTTPS za pomocą curl można użyć tak:
curl -E mycert.pem https://that.secure.server.com
Curl stara się również zweryfikować czy serwer jest tym za kogo się podaje, porównując certyfikat serwera z lokalnie
przechowywanymi podpisami certyfikatów (CA). Niepomyślna weryfikacja spowoduje że curl odmówi połaczenia. Zastosowanie
przełącznika -k spowoduje ignorowanie przez curl niepomyślnej weryfikacji.
Więcej na temat sprawdzania certyfikatów oraz ich podpisów przeczytasz w dokumencie SSLCERTS dostępnym tu:
http://curl.haxx.se/docs/sslcerts.html
12. Żądania niestandardowe
Robiąc "fantazyjne" rzeczy, możliwe że zajdzie potrzeba dodania bądź modyfikacji poszczególnych elementów żądania curl.
Na przykład, możesz zmienić żądanie POST na PROPFIND i wysłać dane jako "Content_Type: text/xml" (zamiast domyślnego
Content-Type) w taki sposób:
curl -d "<xml>" -H "Content-Type: text/xml" -X PROPFIND url.com
Możesz usunąć domyślny nagłówek dołanczając w żądaniu nagłówek z nieprzypisaną zawartością. Przykładowo możesz zruinować zapytanie odcinając zawartość nagłówka Host:
curl -H "Host:" http://mysite.com
W ten sam sposób możesz dodawać dowolne nagłówki. Twój serwer może wymagać nagłoówka "Destination:", możesz go dodać:
curl -H "Destination: http://moo.com/nowhere" http://url.com
13. Web Login
Fakt iż procedura nie jest oparta jedynie o "czyste" HTTP, wciąż sprawia wielu ludziom problemy. W tym rozdziale
zostanie przedstawione w ogromnym uogólnieniu działanie wszystkich formularzy logowania i jak zalogować się za
ich pomocą przy użyciu curl.
Należy zauważyć że by robić to poprawnie w zautomatyzowanym stylu, zapewne nie obędzie się bez skryptów i wielokrotnych
wywołań curl etc.
Po pierwsze, serwery używają głównie cookies by wyśledzić zalogowany status klienta, więc konieczne będzie przechwycenie
cookies, które zostaną do ciebie wysłane w odpowiedzi. Następnie, wiele stron ustawia specjalny cookie na ich stronie
logowania (by upewnić się że znalazłeś się tam poprzez stronę logowania) więc pierwsze co powinieneś zrobić to pobrać
stronę z formularzem logowania, by przechwycić ustawiane na niej cookies.
Niektóre systemy logowania korzystają z różnorodnych kodów javascript i czasmi taki kod jest używany do ustawiania bądź
modyfikacji zawartości cookies. Możliwe że robią to by zapobiegać programowym logowaniom, tak samo jak ten podręcznik opisuje
jak... W każdym razie, jeżeli czytanie kodu nie wystarcza ci by powtórzyć to zachowanie ręcznie, przechwytywanie żądań
HTTP wysyłanych/odbieranych przez twoje przeglądarki i analizowanie przesyłanych cookies jest zazwyczaj praktyczną
metodą by obejść potrzeby javasript.
W aktualnie używanym tagu <form> stosowanym do logowania, wiele stron wypełnia losowo generowane sesje, lub w innym
wypadku potajemnie generowane ukryte tagi i pierwsze co możesz potrzebować to przechwycenie kodu HTML używanego do
formularza logowania, a następnie wydobyć wszystkie ukryte pola by mieć możliwość skonstruowania odpowiednich danych
POST wysyłanych przy logowaniu. Pamiętaj że zawartość tych danych musi być odpowiednio zakodowana (URL encoding), podczas
wysyłania w zwykłym POST.
14. Odpluskwianie
Wiele razy, gdy uruchamiasz curl na jakiejś stronie zauważasz że strona nie odpowiada na twoje żądanie curl tak samo jak
odpowiada na żądanie przeglądarki.
W tym momencie musisz postarać się by twoje żądania bardziej podobne do tych wysyłanych przez przeglądarkę:
* Skorzystaj z opcji --trace--ascii do przechowywania szczegółowych logów pomocnych przy analizie i lepszym zrozumieniu.
* Upewnij się czy sprawdziłeś wszystkie cookies i używasz ich gdy są wymagane (odczytywanie -b i zapisywanie -c)
* Przypisz zmiennej USER-AGENT wartość zgodną z aktualną wersją jednej z popularnych przeglądarek
* Ustaw polecającego w ten sm sposób co przeglądarka
* Jeżeli używasz POST, upewnij się że wysyłasz wszystkie pola i w tej samej kolejności jak zrobiła by to przeglądarka.
Barzo pomocnym narzędziem, by upewnić się że robisz wszystko jak należy jest LiveHTTPHeader które pozwala analizować
wysyłane/odbierane przez Mozilla/Firefox nagłówki (nawet te korzystające z HTTPS).
15. Literatura
RFC 2616 ten dokument musisz koniecznie przeczytać jeżeli chcesz dogłębnie zrozumieć protokół HTTP.
RFC 2396 wyjaśnia składnię URL.
RFC 2109 definiuje jak powinny działać cookies.
RFC 1867 definiuje wysyłanie plików przez HTTP pzry użyciu POST.
http://openssl.org jest stroną domową projektu OpenSSL
http://curl.haxx.se jest stroną domową projektu cURL.
