Пересылка Web-файлов из командной строки. PHP CURL – функции и примеры использования Curl из командной строки

Пересылка Web-файлов из командной строки. PHP CURL – функции и примеры использования Curl из командной строки

В этой статье речь пойдет о таком мощном инструменте как cURL, а также о библиотеке для php, которая предоставляет доступ к этому инструменту — libcurl. Для чего все это нужно? Для связи с сервером по протоколам передачи данных, например, http или ftp. Остальные протоколы нам не особо интересны, если кто-то хочет углубляться в эту тему, то придется уже копать англоязычные ресурсы, а в этой статье будут основы и примеры использования.

Что вообще такое cURL и libcurl? Общие моменты

Итак, библиотека libcurl предоставляет нам возможность передачи данных на сервер, и получения ответов от него. Что нам это дает? Возможность эмуляции поведения пользователя или ! Вы можете получать содержимое страниц для последующего парсинга, можете получать заголовки ответов сервиса и программно авторизироваться на сайтах, делать скрипты постинга сообщений (например, в твиттер или на форумах) или информации. Все ограничивается лишь вашей фантазией!

Установка cURL на Denwer (Денвер). Как начать пользоваться libcurl?

Первое, что мы должны сделать, это установить библиотеку. На локальном компьютере я пользуюсь сборкой Denwer, как и подавляющее большинство начинающих вебмастеров, на которых и рассчитана статья. Опытные пользователи, которые самостоятельно устанавливают связку php+apache+mysql смогут установить и cURL, не мне объяснять им как это делается;) А мы, новички, пользуемся готовыми решениями, чтобы было проще. Поэтому, устанавливаем libcurl следующим образом:

  • Скачиваем готовый пакет расширений «PHP5: дополнительные модули ».
  • Соответственно, устанавливаем его. Ничего сложного, согласитесь:)
  • Открываем в блокноте (я всегда рекомендую Notepad++) файл: X:/webservers/usr/local/php5/php.ini //где X - ваш диск, куда установлен вебсервер

    и убираем точку с запятой в начале сроки:

    ;extension=php_curl.dll

  • Делаем рестарт сервера Денвер.

Готово. Чтобы проверить работоспособность библиотеки можете вызвать функцию phpinfo() и найти там строчку: cURL support enabled. Поздравляю с первой победой.

Описание cURL и первые шаги

Для началом работы с инструментом, его нужно инициализировать. Делается это следующим образом:

$ch = curl_init();

Мы использовали функцию инициализации сессии cURL. При этом, можно задать URL сразу, вот так:

$ch = curl_init("https://сайт");

А можно сделать это потом, в опциях. Порядок установки опций не имеет значения. Делается это другой функцией:

Curl_setopt (resource ch, string option, mixed value)

Первый параметр этой функции, то есть resource ch мы уже создали чуть выше, а вот параметров option и value очень много. Я думаю, что не стоит копипастить сюда их все, а достаточно лишь дать ссылку на подробное описание функции, надеюсь никто не обидится: curl_setopt .

Приведу пример установки опций как раз на примере URL:

$url = "https://сайт"; curl_setopt($ch, CURLOPT_URL,$url);

Еще парочка примеров задания опций: давайте получим заголовок ответа сервера, при этом не будем получать саму страницу:

Curl_setopt($ch, CURLOPT_HEADER, 1); // читать заголовок curl_setopt($ch, CURLOPT_NOBODY, 1); // читать ТОЛЬКО заголовок без тела

Итак, мы инициализировали сессию, задали нужные нам параметры, теперь выполняем получившийся запрос, закрываем сессию и выводим результат:

$result = curl_exec($ch); curl_close($ch); echo $result;

В итоге получаем наш первый полностью рабочий пример использования библиотеки libcurl:

$ch = curl_init(); $url = "https://сайт"; curl_setopt($ch, CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_HEADER, 1); // читать заголовок curl_setopt($ch, CURLOPT_NOBODY, 1); // читать ТОЛЬКО заголовок без тела $result = curl_exec($ch); curl_close($ch); echo $result;

Как оно работает, надеюсь, понятно, ведь мы рассмотрели каждый шаг по отдельности:) В результате мы получаем заголовок HTTP ответа от сервера, который чуть ниже обязательно разберем, чтобы лучше понимать все этапы взаимодействия браузера и сервера:

HTTP/1.1 200 OK Server: nginx/1.2..php 1

Великолепно! Мы получили заголовок ответа от сервера и опробовали библиотеку в действии. Чем это нам полезно? Тем, что теперь вы примерно представляете себе последовательность действий при работе с cURL:

  • Инициализировать сессию (curl_init)
  • Задать нужные нам опции (curl_setopt)
  • Выполнить полученный запрос (curl_exec)
  • Завершить сессию (curl_close)

Структура заголовка HTTP запроса

Для примера я обратился к странице ya.ru и в просмотрел сформированный запрос браузера и полученный от сервера ответ. Вот и они:
Запрос
GET / HTTP/1.1 — Пытаемся получить страницу по адресу /, то есть главную, находящуюся в корне папки. Используем протокол версии 1.1.
User-Agent: Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14 — Представляемся серверу, мы — браузер Опера.
Host: ya.ru — Доменное имя запрашиваемого ресурса.
Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 — Список допустимых форматов ресурса.
Accept-Language: ru-RU,ru;q=0.9,en;q=0.8 — Список поддерживаемых языков.
Accept-Encoding: gzip, deflate — Поддерживаемые способы кодирования.
Cookie: yandexuid=ХХХХХ — Куки, при необходимости.
Connection: Keep-Alive — Просим не разрывать соединение и оставаться на связи.
Ответ
HTTP/1.1 200 Ok — Получаем ответ с кодом 200, значит все ОК.
Server: nginx — Сервер представился — это nginx.
Date: Sun, 10 Mar 2013 14:10:50 GMT — Текущие дата и время на сервере.
Content-Type: text/html; charset=UTF-8 — Тип контента и кодировка.
Connection: close — Сервер не хочет поддерживать с нами постоянного соединения, поэтому сразу же его закрывает. Для следующего запроса будет установлено новое соединение.
Cache-Control: no-cache,no-store,max-age=0,must-revalidate — Управление кэшированием. В данном случае оно отключено.
Expires: Sun, 10 Mar 2013 14:10:50 GMT — Дата предполагаемого истечения срока действия сессии. В нашем случае оно совпадает с временем открытия, так как сервер тут же его закрыл, сразу после обработки.
Last-Modified: Sun, 10 Mar 2013 14:10:50 GMT — Время последней модификации.
Content-Encoding: gzip — Способ кодирования информации.
Полный список всех параметров, которые можно встретить в заголовке HTTP запроса можно посмотреть на википедии .
Теперь вы примерно представляете как общаются между собой ваш браузер и web-сервер. Это очень полезно знать и понимать, ведь мы будем пытаться эмулировать действия браузера с помощью библиотеки libcurl. Идем дальше.

Пример работы с библиотекой

Я считаю, что после того, как некоторые общие моменты уже ясны и вроде бы все понятно, то самое время переходить к практике и на примере уже оттачивать свое мастерство. Лично у меня всегда сразу руки чешутся все попробовать на практике:)

Раз уж cURL так хорош для парсеров, то рассмотрим функцию получения кода страницы по ее адресу. При этом на выходе получим массив с заголовком, содержимым страницы и даже коды ошибок, если что-то пойдет не так.

Function get_web_page($url) { $uagent = "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвращает веб-страницу curl_setopt($ch, CURLOPT_HEADER, 0); // не возвращает заголовки curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // переходит по редиректам curl_setopt($ch, CURLOPT_ENCODING, ""); // обрабатывает все кодировки curl_setopt($ch, CURLOPT_USERAGENT, $uagent); // useragent curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); // таймаут соединения curl_setopt($ch, CURLOPT_TIMEOUT, 120); // таймаут ответа curl_setopt($ch, CURLOPT_MAXREDIRS, 10); // останавливаться после 10-ого редиректа $content = curl_exec($ch); $err = curl_errno($ch); $errmsg = curl_error($ch); $header = curl_getinfo($ch); curl_close($ch); $header["errno"] = $err; $header["errmsg"] = $errmsg; $header["content"] = $content; return $header; }

Входные параметры:
url — адрес страницы или сайта.
Значения выходных параметров (массив с тремя элементами):
header[‘errno’] — если что-то пошло не так, то тут будет код ошибки.
header[‘errmsg’] — здесь при этом будет текст ошибки.
header[‘content’] — собственно сама страница\файл\картинка и т.д.

Используем функцию, например, так:

$result = get_web_page("https://ya.ru"); if (($result["errno"] != 0)||($result["http_code"] != 200)) { echo $result["errmsg"]; } else { $page = $result["content"]; echo $page; }

Все должно пройти без ошибок и вы получите код страницы в переменной $page . Если же попробовать получить несуществующую страницу yaaaaaaaaaaaa.ru, то получим ошибку:

Could not resolve host: yaaaaaaaaaaaa.ru; Host not found

Все обрабатывается корректно и красиво:)
Дальше с кодом страницы можно делать все что угодно, например, парсить регулярками. Но это все в следующих уроках, а пока что остановимся на этом.

Библиотека CURL (Client URLs) позволяет передавать файлы на удаленный компьютер, используя множество Интернет протоколов. Она имеет очень гибкую настройку и позволяют выполнить практически любой удаленный запрос.

CURL поддерживает протоколы HTTP, HTTPS, FTP, FTPS, DICT, TELNET, LDAP, FILE, и GOPHER, так же как HTTP-post, HTTP-put, cookies, FTP-закачкe, продолжение прерванной передачи файлов, пароли, номера портов, сертификаты SSL, Kerberos и прокси.

Используя CURL, web-сервер может выступать полноценным клиентом любого основанного на HTTP протоколе сервисе, к примеру: XML-RPC, SOAP, или WebDAV.

В общем виде использование библиотеки сводиться к четырем шагам:

  1. Создание ресурса CURL c помощью функции curl_init.
  2. Установка параметров c помощью функции curl_setopt.
  3. Выполнение запроса c помощью функции curl_exec.
  4. Освобождение ресурса CURL c помощью функции curl_close.

Простой пример использования CURL

// Иницализация библиотеки curl
if ($ch = @ curl_init ())
{
// Устанавливаем URL запроса
@ curl_setopt ($ch , CURLOPT_URL , "http://server.com/" );
// При значении true CURL включает в вывод заголовки
@
// Куда помещать результат выполнения запроса:
// false - в стандартный поток вывода,
// true - в виде возвращаемого значения функции curl_exec.
@
// Максимальное время ожидания в секундах
@
// Установим значение поля User-agent
@ curl_setopt ($ch , CURLOPT_USERAGENT , "PHP Bot (http://blog.yousoft.ru)" );
// Выполнение запроса
$data = @ curl_exec ($ch );
// Вывести полученные данные
echo $data ;
// Особождение ресурса
@ curl_close ($ch );
}
?>

Пример использования GET запроса

$ch = curl_init ();
// GET запрос указывается в строке URL
curl_setopt ($ch , CURLOPT_URL , "http://server.com/?s=CURL" );
curl_setopt ($ch , CURLOPT_HEADER , false );
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , true );
curl_setopt ($ch , CURLOPT_CONNECTTIMEOUT , 30 );

$data = curl_exec ($ch );
curl_close ($ch );
?>

Посылка GET запроса ничем не отличается от получения страницы. Важно заметить, что строка запроса формируется следующим образом:

Http://server.com/index.php?name1=value1&name2=value2&name3=value3

где http://server.com/index.php - адрес страницы, nameX - название переменной, valueX - значение переменной.

Пример использования POST запроса

$ch = curl_init ();
curl_setopt ($ch , CURLOPT_URL , "http://server.com/index.php" );
curl_setopt ($ch , CURLOPT_HEADER , false );
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , true );
// Нужно явно указать, что будет POST запрос
curl_setopt ($ch , CURLOPT_POST , true );
// Здесь передаются значения переменных
curl_setopt ($ch , CURLOPT_POSTFIELDS , "s=CURL" );
curl_setopt ($ch , CURLOPT_CONNECTTIMEOUT , 30 );
curl_setopt ($ch , CURLOPT_USERAGENT , "PHP Bot (http://mysite.ru)" );
$data = curl_exec ($ch );
curl_close ($ch );
?>

Отправка POST запроса не многим отличается от отправки GET запроса. Все основные шаги остаются такие же. Переменные также задаются парами: name1=value1&name2=value2 .

Пример HTTP-авторизации

// HTTP авторизация
$url = "http://server.com/protected/" ;
$ch = curl_init ();


curl_setopt ($ch , CURLOPT_USERPWD , "myusername:mypassword" );
$result = curl_exec ($ch );
curl_close ($ch );
echo $result ;
?>

Пример FTP-сессии

$fp = fopen (__FILE__ , "r" );
$url = "ftp://username:[email protected]:21/path/to/newfile.php" ;
$ch = curl_init ();
curl_setopt ($ch , CURLOPT_URL , $url );
curl_setopt ($ch , CURLOPT_RETURNTRANSFER , 1 );
curl_setopt ($ch , CURLOPT_UPLOAD , 1 );
curl_setopt ($ch , CURLOPT_INFILE , $fp );
curl_setopt ($ch , CURLOPT_FTPASCII , 1 );
curl_setopt ($ch , CURLOPT_INFILESIZE , filesize (__FILE__ ));
$result = curl_exec ($ch );
curl_close ($ch );
?>

При возникновении проблем в использовании cURL необходимо добавить следующие строки перед вызовом curl_close для получения отчета о последнем выполненном запросе:

print_r (curl_getinfo ($ch ));
echo "cURL error number:" . curl_errno ($ch ). "
" ;
echo "cURL error:" . curl_error ($ch ). "
" ;
curl_close ($ch );
?>

Для чего нужна cURL

  • cURL отлично подходит для имитации действий пользователя в браузере.

Реальный практический пример: вам нужно перезагрузить роутер (модем) для смены IP адреса. Для этого нужно: авторизоваться в роутере, перейти к странице обслуживания и нажать кнопку «Перезагрузка». Если это действие нужно выполнить несколько раз, то процедуру нужно повторить. Согласитесь, делать каждый раз в ручную эту рутину не хочется. cURL позволяет автоматизировать всё это. Буквально несколькими командами cURL можно добиться авторизации и выполнения задания на роутере.

  • cURL удобен для получения данных с веб-сайтов в командной строке.

Ещё один практический пример: мы хотим реализовать показ общей статистики для нескольких сайтов. Если использовать cURL, то это становится вполне тривиальной задачей: с помощью cURL мы проходим аутентификацию на сервисе сбора статистики (если это требуется), затем (опять же командами cURL) получаем необходимые страницы, парсим нужные нам данные; процедура повторяется для всех наших сайтов, затем мы складываем и выводим конечный результат.

Т.е. случаи использования cURL вполне реальные, хотя, в большинстве, cURL нужна программистам, которые используют её для своих программ.

cURL поддерживает множество протоколов и способов авторизации, умеет передавать файлы, правильно работает с кукиз, поддерживает SSL сертификаты, прокси и очень многое другое.

cURL в PHP и командной строке

Мы можем использовать cURL двумя основными способами: в скриптах PHP и в командной строке.

Чтобы включить cURL в PHP на сервере, необходимо в файле php.ini раскоментировать строку

Extension=php_curl.dll

А затем перезагрузить сервер.

На Linux необходимо установить пакет curl.

На Debian, Ubuntu или Linux Mint:

$ sudo apt-get install curl

На Fedora, CentOS или RHEL:

$ sudo yum install curl

Чтобы наглядно было видно разницу в использовании в PHP и в командной строке, будем одни и те же задачи выполнять дважды: сначала в скрипте PHP, а затем в командной строке. Постараемся при этом не запутаться.

Получение данных при помощи cURL

Получение данных при помощи cURL в PHP

Пример на PHP:

Всё очень просто:

$target_url — адрес сайта, который нас интересует. После адреса сайта можно поставить двоеточие и добавить адрес порта (если порт отличается от стандартного).

curl_init — инициализирует новый сеанс и возвращает дискриптор, который в нашем примере присваивается переменной $ch .

Затем мы выполняем запрос cURL функцией curl_exec , которой в качестве параметра передаётся дискриптор.

Всё очень логично, но при выполнении этого скрипта, на нашей странице отобразиться содержимое сайта. А что если мы не хотим отображать содержимое, а хотим записать его в переменную (для последующей обработки или парсинга).

Чуть дополним наш скрипт:

0) { echo "Ошибка curl: " . curl_error($ch); } curl_close($ch); ?>

У нас появилась строчка curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); .

curl_setopt — задаёт опции. Полный список опций можно найти на этой странице: http://php.net/manual/ru/function.curl-setopt.php

$response_data = curl_exec($ch);

Теперь значение скрипта присваивается переменной $response_data, с которой можно проводить дальнейшие операции. Например, можно вывести её содержимое.

If (curl_errno($ch) > 0) { echo "Ошибка curl: " . curl_error($ch); }

служат для отладки, на случай возникновения ошибок.

Получение данных при помощи cURL в командной строке

В командной строке достаточно набрать

Curl mi-al.ru

где вместо mi-al.ru — адрес вашего сайта.

Если нужно скопировать данные в переменную, а не выводить полученный результат на экран, то делаем так:

Temp=`curl mi-al.ru`

При этом всё равно выводятся некие данные:

Чтобы они не выводились, добавляем ключ -s :

Temp=`curl -s mi-al.ru`

Можно посмотреть, что записалось:

Echo $temp | less

Базовая аутентификация и аутентификация HTTP

Аутентификация, проще говоря, это введение имени пользователя и пароля.

Базовая аутентификация — это аутентификация средствами сервера. Для этого создаются два файла: .htaccess и .htpasswd

Содержимое файла.htaccess примерно такое

AuthName "Только для зарегистрированных пользователей!" AuthType Basic require valid-user AuthUserFile /home/freeforum.biz/htdocs/.htpassw

Содержимое файла.htpasswd примерно такое:

Mial:CRdiI.ZrZQRRc

Т.е. логин и хэш пароля.

При попытке получить доступ к запароленной папке, в браузере отобразиться примерно такое окно:

HTTP аутентификация — это тот случай, когда мы вводим логин и пароль в форму на сайте. Именно такая аутентификация используется при входе в почту, на форумы и т. д.

Базовая аутентификация cURL (PHP)

Есть сайт http://62.113.208.29/Update_FED_DAYS/, который требует от нас авторизоваться:

Пробуем наш первоначальный скрипт:

0) { echo "Ошибка curl: " . curl_error($ch); } else { echo $response_data; } curl_close($ch); ?>

Хотя скрипт и считает, что ошибки нет, но выводимый результат нам совсем не нравится:

Добавляем две строки:

Curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_USERPWD, "ru-board:ru-board");

Первой строкой мы задаём тип аутентификации — базовая. Вторая строка содержит имя и пароль через двоеточие (в нашем случае имя и пароль одинаковые — ru-board). Получилось так:

0) { echo "Ошибка curl: " . curl_error($ch); } else { echo $response_data; } curl_close($ch); ?>

Базовая аутентификация cURL (в командной строке)

Этого же самого в командной строке можно добиться одной строчкой:

Curl -u ru-board:ru-board http://62.113.208.29/Update_FED_DAYS/

Я не забыл указать тип аутентификации, просто в cURL базовый тип аутентификации является дефолтным.

В командной строке всё получилось так быстро, что от расстройства я написал вот такую программу. Она подключается к сайту и скачивает самое последнее обновление:

Temp=`curl -s -u ru-board:ru-board http://62.113.208.29/Update_FED_DAYS/ | grep -E -o "Update_FED_201{1}.{2}.{2}.7z" | uniq | tail -n 1`; curl -o $temp -u ru-board:ru-board http://62.113.208.29/Update_FED_DAYS/$temp

Буквально ещё несколькими командами можно добавить:

  • распаковку архива в указанный каталог;
  • запуск обновлений КонсультантПлюс (это обновления для него);
  • можно реализовать проверку — было ли уже скачено последнее доступное обновление или появилось новое;
  • добавить это всё в Cron для ежедневных обновлений.

HTTP аутентификация cURL

HTTP аутентификация cURL в PHP

Нам нужно знать:

  • адрес, куда отправлять данные для аутентификации
  • метод отправки GET или POST
  • логин
  • пароль

Иногда этих данных оказывается недостаточно. Давайте разберёмся.

Адрес, куда нужно отправить данные, можно взять из формы аутентификации. Например:

Мы смотрим на свойство action . Т.е. конечной страницей является login.php . Нам нужен полный адрес, например такой http://188.35.8.64:8080/login.php

Здесь же мы находим и метод отправки: method="post"

Логин и пароль я тоже знаю: admin и qwerasdfzxcv

На всякий случай — это не мой роутер (и я не знаю чей), поэтому если вы хотите досадить именно мне, то не нужно пакостить на этом роутере.

Т.е. на сервер из формы передаётся строка методом POST. Теоретически, наш предыдущий скрипт, в которое мы добавили новую строчку, должен работать. Т.е. должна происходить аутентификация.

0) { echo "Ошибка curl: " . curl_error($ch); } else { } curl_close($ch); ?>

В скрипте новая строка

curl_setopt($ch, CURLOPT_POSTFIELDS, "LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv");

Здесь curl_setopt — уже знакомая нам функция по установлению опций для cURL, CURLOPT_POSTFIELDS — эта имя опции, которую мы устанавливаем. CURLOPT_POSTFIELDS содержит все данные, которые передаются методом POST. Ну и сама строчка LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv — это те самые данные, которые мы передаём.

Если внимательно изучить форму, то можно увидеть, что она содержит также и скрытые поля. А ещё данные могут обрабатываться или дополняться JavaScript"ами. Можно заняться изучением всего этого, но я предпочитаю более простой способ.

Я использую Wireshark. Эта программа предназначена для снифинга (перехвата) трафика. И именно в ней очень удобно смотреть, что же именно передаётся на сайт.

Посмотрите это крошечное видео:

Т.е. с адресом, куда передаются данные, я угадал. А вот передаваемая строка оказалась намного сложнее.

Я вписал верный параметр, а также чуть доработал скрипт, чтобы он не просто авторизовался, но и кое-что получал из роутера:

0) { echo "Ошибка curl: " . curl_error($ch); } else { $target_url2 = "http://188.35.8.64:8080/bsc_wlan.php"; $ch2 = curl_init($target_url2); curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1); $response_data2 = curl_exec($ch2); preg_match("|f.ssid.value = "(.*)";|", $response_data2, $results2); $results2 = str_replace("f.ssid.value = "", "", $results2); $results2 = str_replace("";", "", $results2); echo "Имя wi-fi сети: $results2
"; preg_match("|f_wpa.wpapsk1.value(.*)";|", $response_data2, $results3); $results3 = str_replace("f_wpa.wpapsk1.value", "", $results3); $results3 = str_replace("="", "", $results3); $results3 = str_replace("";", "", $results3); echo "Пароль wi-fi сети: $results3"; } curl_close($ch); ?>

Кстати, если владелец обновит пароль (но не обновит прошивку), то новый пароль всегда можно посмотреть по адресу http://188.35.8.64:8080/model/__show_info.php?REQUIRE_FILE=/var/etc/httpasswd

(Это общеизвестная уязвимость роутеров D-Link DIR-300, D-Link DIR-320, и D-Link DAP-1353).

HTTP аутентификация cURL в командной строке

Полный адрес, а также строку, которую нужно передать, мы уже знаем. Поэтому всё просто:

Curl --data "ACTION_POST=LOGIN&FILECODE=&VERIFICATION_CODE=&LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv&login=Log+In+&VER_CODE=" http://188.35.8.64:8080/login.php

Думаю, всё и так понятно, т. к. эти сроки мы уже рассмотрели. Если кому-то непонятно — спрашивайте в комментариях.

Примером использования cURL для получения и парсинга данных может стать следующий набор команд:

Curl -s --data "ACTION_POST=LOGIN&FILECODE=&VERIFICATION_CODE=&LOGIN_USER=admin&LOGIN_PASSWD=qwerasdfzxcv&login=Log+In+&VER_CODE=" http://188.35.8.64:8080/login.php > /dev/null && echo -e "nn" && echo "Имя сети Wi-Fi" && curl -s http://188.35.8.64:8080/bsc_wlan.php | grep -E "f.ssid.value = "(.)*";" | sed "s/f.ssid.value = "//" | sed "s/";//" && echo "Пароль сети Wi-Fi" && curl -s http://188.35.8.64:8080/bsc_wlan.php | grep -E "f_wpa.wpapsk1.(.)*";" | sed "s/f_wpa.wpapsk1.value//" | sed "s/";//" | sed "s/="//"

Сложные случаи авторизации: AJAX, JQuery, JavaScript и т.п.

Данные заголовок правильнее было бы написать так: «Сложные» случаи авторизации. Т.е. слово «сложные» взять в кавычки. Сложными они видятся только на первый взгляд, когда непонятно: куда происходит отправка, какие имена полей, что именно отправляется и т. д.

Но, на самом деле, все они сводятся к методам POST или GET. Чтобы понять, что именно отправляется, можно сохранить страницу с формой себе на диск и на кнопку отправки повесить функцию показа сформированных для отправки данных. Или ещё проще — как я, Wireshark"ом.

Если данные правильные, а аутентификация не происходит, то нужно копать в следующих направлениях:

  • задать верную строку реферера
  • задать «правильную» строку пользовательского агента.

Всё это можно сделать базовыми методами cURL, но я не буду на этом останавливаться. Урок получился и без того большим, а ведь я ещё хотел показать пару трюков с cURL.

Типсы и триксы cURL

cURL и получение кукиз помимо CURLOPT_COOKIEJAR

Думаю, уже стало понятно, что cURL правильно обрабатывает куки — сохраняет их, использует, когда сервер запрашивает, и т. д. Но иногда куки нужно сохранить. Для этого есть опция CURLOPT_COOKIEJAR, но воспользоваться ей можно не всегда. Этому и посвящён наш первый трюк.

Иногда из-за особенностей настройки PHP на сервере, нам недоступны такие опции как CURLOPT_COOKIEJAR (позволяет сохранить полученные куки в файл) и CURLOPT_COOKIEFILE (позволяет использовать куки из файла). Т.к. они говорят, что используя эти опции мы сможем стянуть любой файл с их сервера. Вот решение этой проблемы:

1) Не используем CURLOPT_FOLLOWLOCATION

2) Используем curl_setopt($ch, CURLOPT_HEADER, 1)

3) Собираем кукизы из заголовка header примерно так:

Preg_match_all("|Set-Cookie: (.*);|U", $content, $results); $cookies = implode(";", $results);

4) Задаём их используя curl_setopt($ch, CURLOPT_COOKIE, $cookies);

Второй совет. Из атакующих мы можем превратиться в жертву. Чтобы не стать жертвой атаки человек-по-середине, делаем так.

Пожалуйста, все, перестаньте устанавливать настройку CURLOPT_SSL_VERIFYPEER на false или 0. Если ваша установка PHP не имеет актуального комплекта корневых сертификатов CA, загрузите один на веб-сайте curl и сохраните его на ваш сервер:

Затем задайте путь в вашем файле php.ini file, например, на Windows:

Curl.cainfo=c:phpcacert.pem

Отключение CURLOPT_SSL_VERIFYPEER позволяет осуществить атаку человек-по-середине (MITM), а это нам не надо!

Ну и последняя на сегодня подсказка. Знаете ли вы, что возможно большое количество асинхронных запросов curl?

Для этого можно использовать curl_multi_init . Подробности и пример кода в официальной документации http://php.net/manual/ru/function.curl-multi-init.php

Про cURL в командной строке

Man curl

Для чтения на русском языке также подготовлена вторая часть урока cURL: " ".

cURL - это специальный инструмент, который предназначен для того, чтобы передавать файлы и данные синтаксисом URL. Данная технология поддерживает множество протоколов, таких как HTTP, FTP, TELNET и многие другие. Изначально cURL было разработано для того, чтобы быть инструментом командной строки. К счастью для нас, библиотека cURL поддерживается языком программирования PHP. В этой статье мы рассмотрим некоторые расширенные функций cURL, а также затронем практическое применение полученных знаний средствами PHP.

Почему cURL?

На самом деле, существует немало альтернативных способов выборки содержания веб-страницы. Во многих случаях, главным образом из-за лени, я использовал простые PHP функции вместо cURL:

$content = file_get_contents("http://www.nettuts.com"); // или $lines = file("http://www.nettuts.com"); // или readfile("http://www.nettuts.com");

Однако данные функции не имеют фактически никакой гибкости и содержат огромное количество недостатков в том, что касается обработки ошибок и т.д. Кроме того, существуют определенные задачи, которые вы просто не можете решить благодаря этим стандартным функциям: взаимодействие с cookie, аутентификация, отправка формы, загрузка файлов и т.д.

cURL - это мощная библиотека, которая поддерживает множество различных протоколов, опций и обеспечивает подробную информацию о URL запросах.

Базовая структура

  • Инициализация
  • Назначение параметров
  • Выполнение и выборка результата
  • Освобождение памяти

// 1. инициализация $ch = curl_init(); // 2. указываем параметры, включая url curl_setopt($ch, CURLOPT_URL, "http://www.nettuts.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); // 3. получаем HTML в качестве результата $output = curl_exec($ch); // 4. закрываем соединение curl_close($ch);

Шаг #2 (то есть, вызов curl_setopt()) будем обсуждать в этой статье намного больше, чем все другие этапы, т.к. на этой стадии происходит всё самое интересное и полезное, что вам необходимо знать. В cURL существует огромное количество различных опций, которые должны быть указаны, для того чтобы иметь возможность сконфигурировать URL-запрос самым тщательным образом. Мы не будем рассматривать весь список целиком, а остановимся только на том, что я посчитаю нужным и полезным для этого урока. Всё остальное вы сможете изучить сами, если эта тема вас заинтересует.

Проверка Ошибки

Вдобавок, вы также можете использовать условные операторы для проверки выполнения операции на успех:

// ... $output = curl_exec($ch); if ($output === FALSE) { echo "cURL Error: " . curl_error($ch); } // ...

Тут прошу отметить для себя очень важный момент: мы должны использовать “=== false” для сравнения, вместо “== false”. Для тех, кто не в курсе, это поможет нам отличать пустой результат от булевого значения false, которое и будет указывать на ошибку.

Получение информации

Ещё одним дополнительным шагом является получение данных о cURL запросе, после того, как он был выполнен.

// ... curl_exec($ch); $info = curl_getinfo($ch); echo "Took " . $info["total_time"] . " seconds for url " . $info["url"]; // …

Возвращаемый массив содержит следующую информацию:

  • “url”
  • “content_type”
  • “http_code”
  • “header_size”
  • “request_size”
  • “filetime”
  • “ssl_verify_result”
  • “redirect_count”
  • “total_time”
  • “namelookup_time”
  • “connect_time”
  • “pretransfer_time”
  • “size_upload”
  • “size_download”
  • “speed_download”
  • “speed_upload”
  • “download_content_length”
  • “upload_content_length”
  • “starttransfer_time”
  • “redirect_time”

Обнаружение перенаправления в зависимости от браузера

В этом первом примере мы напишем код, который сможет обнаружить перенаправления URL, основанные на различных настройках браузера. Например, некоторые веб-сайты перенаправляют браузеры сотового телефона, или любого другого устройства.

Мы собираемся использовать опцию CURLOPT_HTTPHEADER для того, чтобы определить наши исходящие HTTP заголовки, включая название браузера пользователя и доступные языки. В конечном итоге мы сможем определить, какие сайты перенаправляют нас к разным URL.

// тестируем URL $urls = array("http://www.cnn.com", "http://www.mozilla.com", "http://www.facebook.com"); // тестируем браузеры $browsers = array("standard" => array ("user_agent" => "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)", "language" => "en-us,en;q=0.5"), "iphone" => array ("user_agent" => "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A537a Safari/419.3", "language" => "en"), "french" => array ("user_agent" => "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; GTB6; .NET CLR 2.0.50727)", "language" => "fr,fr-FR;q=0.5")); foreach ($urls as $url) { echo "URL: $url\n"; foreach ($browsers as $test_name => $browser) { $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url); // указываем заголовки для браузера curl_setopt($ch, CURLOPT_HTTPHEADER, array("User-Agent: {$browser["user_agent"]}", "Accept-Language: {$browser["language"]}")); // нам не нужно содержание страницы curl_setopt($ch, CURLOPT_NOBODY, 1); // нам необходимо получить HTTP заголовки curl_setopt($ch, CURLOPT_HEADER, 1); // возвращаем результаты вместо вывода curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); // был ли HTTP редирект? if (preg_match("!Location: (.*)!", $output, $matches)) { echo "$test_name: redirects to $matches\n"; } else { echo "$test_name: no redirection\n"; } } echo "\n\n"; }

Сначала мы указываем список URL сайтов, которые будем проверять. Точнее, нам понадобятся адреса данных сайтов. Далее нам необходимо определить настройки браузера, чтобы протестировать каждый из этих URL. После этого мы воспользуемся циклом, в котором пробежимся по всем полученным результатам.

Приём, который мы используем в этом примере для того, чтобы задать настройки cURL, позволит нам получить не содержание страницы, а только HTTP-заголовки (сохраненные в $output). Далее, воспользовавшись простым regex, мы можем определить, присутствовала ли строка “Location:” в полученных заголовках.

Когда вы запустите данный код, то должны будете получить примерно следующий результат:

Создание POST запроса на определённый URL

При формировании GET запроса передаваемые данные могут быть переданы на URL через “строку запроса”. Например, когда Вы делаете поиск в Google, критерий поиска располагаются в адресной строке нового URL:

Http://www.google.com/search?q=ruseller

Для того чтобы сымитировать данный запрос, вам не нужно пользоваться средствами cURL. Если лень вас одолевает окончательно, воспользуйтесь функцией “file_get_contents()”, для того чтобы получить результат.

Но дело в том, что некоторые HTML-формы отправляют POST запросы. Данные этих форм транспортируются через тело HTTP запроса, а не как в предыдущем случае. Например, если вы заполнили форму на форуме и нажали на кнопку поиска, то скорее всего будет совершён POST запрос:

Http://codeigniter.com/forums/do_search/

Мы можем написать PHP скрипт, который может сымитировать этот вид URL запроса. Сначала давайте создадим простой файл для принятия и отображения POST данных. Назовём его post_output.php:

Print_r($_POST);

Затем мы создаем PHP скрипт, чтобы выполнить cURL запрос:

$url = "http://localhost/post_output.php"; $post_data = array ("foo" => "bar", "query" => "Nettuts", "action" => "Submit"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // указываем, что у нас POST запрос curl_setopt($ch, CURLOPT_POST, 1); // добавляем переменные curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

При запуске данного скрипта вы должны получить подобный результат:

Таким образом, POST запрос был отправлен скрипту post_output.php, который в свою очередь, вывел суперглобальный массив $_POST, содержание которого мы получили при помощи cURL.

Загрузка файла

Сначала давайте создадим файл для того, чтобы сформировать его и отправить файлу upload_output.php:

Print_r($_FILES);

А вот и код скрипта, который выполняет указанный выше функционал:

$url = "http://localhost/upload_output.php"; $post_data = array ("foo" => "bar", // файл, который необходимо загрузить "upload" => "@C:/wamp/www/test.zip"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); $output = curl_exec($ch); curl_close($ch); echo $output;

Когда вы хотите загрузить файл, все, что вам нужно сделать, так это передать его как обычную post переменную, предварительно поместив перед ней символ @. При запуске написанного скрипта вы получите следующий результат:

Множественный cURL

Одной из самых сильных сторон cURL является возможность создания "множественных" cURL обработчиков. Это позволяет вам открывать соединение к множеству URL одновременно и асинхронно.

В классическом варианте cURL запроса выполнение скрипта приостанавливается, и происходит ожидание завершения операции URL запроса, после чего работа скрипта может продолжиться. Если вы намереваетесь взаимодействовать с целым множеством URL, это приведёт к довольно-таки значительным затратам времени, поскольку в классическом варианте вы можете работать только с одним URL за один раз. Однако, мы можем исправить данную ситуацию, воспользовавшись специальными обработчиками.

Давайте рассмотрим пример кода, который я взял с php.net:

// создаём несколько cURL ресурсов $ch1 = curl_init(); $ch2 = curl_init(); // указываем URL и другие параметры curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/"); curl_setopt($ch1, CURLOPT_HEADER, 0); curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/"); curl_setopt($ch2, CURLOPT_HEADER, 0); //создаём множественный cURL обработчик $mh = curl_multi_init(); //добавляем несколько обработчиков curl_multi_add_handle($mh,$ch1); curl_multi_add_handle($mh,$ch2); $active = null; //выполнение do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } //закрытие curl_multi_remove_handle($mh, $ch1); curl_multi_remove_handle($mh, $ch2); curl_multi_close($mh);

Идея состоит в том, что вы можете использовать множественные cURL обработчики. Используя простой цикл, вы можете отследить, какие запросы ещё не выполнились.

В этом примере есть два основных цикла. Первый цикл do-while вызывает функцию curl_multi_exec(). Эта функция не блокируемая. Она выполняется с той скоростью, с которой может, и возвращает состояние запроса. Пока возвращенное значение является константой ‘CURLM_CALL_MULTI_PERFORM’, это означает, что работа ещё не завершена (например, в данный момент происходит отправка http заголовков в URL); Именно поэтому мы продолжаем проверять это возвращаемое значение, пока не получим другой результат.

В следующем цикле мы проверяем условие, пока переменная $active = "true". Она является вторым параметром для функции curl_multi_exec(). Значение данной переменной будет равно "true", до тех пор, пока какое-то из существующих изменений является активным. Далее мы вызываем функцию curl_multi_select(). Её выполнение "блокируется", пока существует хоть одно активное соединение, до тех пор, пока не будет получен ответ. Когда это произойдёт, мы возвращаемся в основной цикл, чтобы продолжить выполнение запросов.

А теперь давайте применим полученные знания на примере, который будет реально полезным для большого количества людей.

Проверяем ссылки в WordPress

Представьте себе блог с огромным количеством постов и сообщений, в каждом из которых есть ссылки на внешние интернет ресурсы. Некоторые из этих ссылок по различным причинам могли бы уже быть «мертвыми». Возможно, страница была удалена или сайт вовсе не работает.

Мы собираемся создать скрипт, который проанализирует все ссылки и найдёт незагружающиеся веб-сайты и страницы 404, после чего предоставит нам подробнейший отчёт.

Сразу же скажу, что это не пример создания плагина для WordPress. Это всего на всего хороший полигон для наших испытаний.

Давайте же наконец начнём. Сначала мы должны сделать выборку всех ссылок из базы данных:

// конфигурация $db_host = "localhost"; $db_user = "root"; $db_pass = ""; $db_name = "wordpress"; $excluded_domains = array("localhost", "www.mydomain.com"); $max_connections = 10; // инициализация переменных $url_list = array(); $working_urls = array(); $dead_urls = array(); $not_found_urls = array(); $active = null; // подключаемся к MySQL if (!mysql_connect($db_host, $db_user, $db_pass)) { die("Could not connect: " . mysql_error()); } if (!mysql_select_db($db_name)) { die("Could not select db: " . mysql_error()); } // выбираем все опубликованные посты, где есть ссылки $q = "SELECT post_content FROM wp_posts WHERE post_content LIKE "%href=%" AND post_status = "publish" AND post_type = "post""; $r = mysql_query($q) or die(mysql_error()); while ($d = mysql_fetch_assoc($r)) { // делаем выборку ссылок при помощи регулярных выражений if (preg_match_all("!href=\"(.*?)\"!", $d["post_content"], $matches)) { foreach ($matches as $url) { $tmp = parse_url($url); if (in_array($tmp["host"], $excluded_domains)) { continue; } $url_list = $url; } } } // убираем дубликаты $url_list = array_values(array_unique($url_list)); if (!$url_list) { die("No URL to check"); }

Сначала мы формируем конфигурационные данные для взаимодействия с базой данных, далее пишем список доменов, которые не будут участвовать в проверке ($excluded_domains). Также мы определяем число, характеризующее количество максимальных одновременных соединений, которые мы будем использовать в нашем скрипте ($max_connections). Затем мы присоединяемся к базе данных, выбираем посты, которые содержат ссылки, и накапливаем их в массив ($url_list).

Следующий код немного сложен, так что разберитесь в нём от начала до конца:

// 1. множественный обработчик $mh = curl_multi_init(); // 2. добавляем множество URL for ($i = 0; $i < $max_connections; $i++) { add_url_to_multi_handle($mh, $url_list); } // 3. инициализация выполнения do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 4. основной цикл while ($active && $mrc == CURLM_OK) { // 5. если всё прошло успешно if (curl_multi_select($mh) != -1) { // 6. делаем дело do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); // 7. если есть инфа? if ($mhinfo = curl_multi_info_read($mh)) { // это значит, что запрос завершился // 8. извлекаем инфу $chinfo = curl_getinfo($mhinfo["handle"]); // 9. мёртвая ссылка? if (!$chinfo["http_code"]) { $dead_urls = $chinfo["url"]; // 10. 404? } else if ($chinfo["http_code"] == 404) { $not_found_urls = $chinfo["url"]; // 11. рабочая } else { $working_urls = $chinfo["url"]; } // 12. чистим за собой curl_multi_remove_handle($mh, $mhinfo["handle"]); // в случае зацикливания, закомментируйте данный вызов curl_close($mhinfo["handle"]); // 13. добавляем новый url и продолжаем работу if (add_url_to_multi_handle($mh, $url_list)) { do { $mrc = curl_multi_exec($mh, $active); } while ($mrc == CURLM_CALL_MULTI_PERFORM); } } } } // 14. завершение curl_multi_close($mh); echo "==Dead URLs==\n"; echo implode("\n",$dead_urls) . "\n\n"; echo "==404 URLs==\n"; echo implode("\n",$not_found_urls) . "\n\n"; echo "==Working URLs==\n"; echo implode("\n",$working_urls); function add_url_to_multi_handle($mh, $url_list) { static $index = 0; // если у нас есть ещё url, которые нужно достать if ($url_list[$index]) { // новый curl обработчик $ch = curl_init(); // указываем url curl_setopt($ch, CURLOPT_URL, $url_list[$index]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_NOBODY, 1); curl_multi_add_handle($mh, $ch); // переходим на следующий url $index++; return true; } else { // добавление новых URL завершено return false; } }

Тут я попытаюсь изложить всё по полочкам. Числа в списке соответствуют числам в комментарии.

  1. 1. Создаём множественный обработчик;
  2. 2. Функцию add_url_to_multi_handle() мы напишем чуть позже. Каждый раз, когда она будет вызываться, начнётся обработка нового url. Первоначально, мы добавляем 10 ($max_connections) URL;
  3. 3. Для того чтобы начать работу, мы должны запустить функцию curl_multi_exec(). До тех пор, пока она будет возвращать CURLM_CALL_MULTI_PERFORM, нам ещё есть, что делать. Это нам нужно, главным образом, для того, чтобы создать соединения;
  4. 4. Далее следует основной цикл, который будет выполняться до тех пор, пока у нас есть хоть одно активное соединение;
  5. 5. curl_multi_select() зависает в ожидании, пока поиск URL не завершится;
  6. 6. И снова мы должны заставить cURL выполнить некоторую работу, а именно, сделать выборку данных возвращаемого ответа;
  7. 7. Тут происходит проверка информации. В результате выполнения запроса будет возвращён массив;
  8. 8. В возвращенном массиве присутствует cURL обработчик. Его мы и будем использовать для того, чтобы выбрать информацию об отдельном cURL запросе;
  9. 9. Если ссылка была мертва, или время выполнения скрипта вышло, то нам не следует искать никакого http кода;
  10. 10. Если ссылка возвратила нам страницу 404, то http код будет содержать значение 404;
  11. 11. В противном случае, перед нами находится рабочая ссылка. (Вы можете добавить дополнительные проверки на код ошибки 500 и т.д...);
  12. 12. Далее мы удаляем cURL обработчик, потому что больше в нём не нуждаемся;
  13. 13. Теперь мы можем добавить другой url и запустить всё то, о чём говорили до этого;
  14. 14. На этом шаге скрипт завершает свою работу. Мы можем удалить всё, что нам не нужно и сформировать отчет;
  15. 15. В конце концов, напишем функцию, которая будет добавлять url в обработчик. Статическая переменная $index будет увеличиваться каждый раз, когда данная функция будет вызвана.

Я использовал данный скрипт на своем блоге (с некоторыми неработающими ссылками, которые добавил нарочно для того, чтобы протестировать его работу) и получил следующий результат:

В моём случае, скрипту потребовалось чуть меньше чем 2 секунды, чтобы пробежаться по 40 URL. Увеличение производительности является существенным при работе с еще большим количеством URL адресов. Если вы открываете десять соединений одновременно, то скрипт может выполниться в десять раз быстрее.

Пару слов о других полезных опциях cURL

HTTP Аутентификация

Если на URL адресе есть HTTP аутентификация, то вы без труда можете воспользоваться следующим скриптом:

$url = "http://www.somesite.com/members/"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // указываем имя и пароль curl_setopt($ch, CURLOPT_USERPWD, "myusername:mypassword"); // если перенаправление разрешено curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // то сохраним наши данные в cURL curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, 1); $output = curl_exec($ch); curl_close($ch);

FTP загрузка

В PHP также существует библиотека для работы с FTP, но вам ничего не мешает и тут воспользоваться средствами cURL:

// открываем файл $file = fopen("/path/to/file", "r"); // в url должно быть следующее содержание $url = "ftp://username:[email protected]:21/path/to/new/file"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_UPLOAD, 1); curl_setopt($ch, CURLOPT_INFILE, $fp); curl_setopt($ch, CURLOPT_INFILESIZE, filesize("/path/to/file")); // указывам ASCII мод curl_setopt($ch, CURLOPT_FTPASCII, 1); $output = curl_exec($ch); curl_close($ch);

Используем Прокси

Вы можете выполнить свой URL запрос через прокси:

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://www.example.com"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // указываем адрес curl_setopt($ch, CURLOPT_PROXY, "11.11.11.11:8080"); // если необходимо предоставить имя пользователя и пароль curl_setopt($ch, CURLOPT_PROXYUSERPWD,"user:pass"); $output = curl_exec($ch); curl_close ($ch);

Функции обратного вызова

Также существует возможность указать функцию, которая будет срабатывать ещё до завершения работы cURL запроса. Например, пока содержание ответа загружается, вы можете начать использовать данные, не дожидаясь полной загрузки.

$ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"http://net.tutsplus.com"); curl_setopt($ch, CURLOPT_WRITEFUNCTION,"progress_function"); curl_exec($ch); curl_close ($ch); function progress_function($ch,$str) { echo $str; return strlen($str); }

Подобная функция ДОЛЖНА возвращать длину строки, что является обязательным требованием.

Заключение

Сегодня мы познакомились с тем, как можно применить библиотеку cURL в своих корыстных целях. Я надеюсь, что вам понравилась данная статья.

Спасибо! Удачного дня!

Нам часто приходится загружать различные файлы из интернета, например, исполняемые файлы программ, файлы скриптов, архивы с исходниками. Но не всегда это нужно делать через браузер. Во многих ситуациях гораздо проще выполнить все действия через терминал. Поскольку таким образом вы можете автоматизировать процесс. С другой стороны, веб-мастерам время от времени приходится тестировать доступность веб-сайтов, проверять отправляемые и получаемые заголовки и многое другое.

Для решения таких задач и задач подобного круга можно воспользоваться утилитой curl. Она позволяет решить намного более широкий круг задач, среди которых даже имитация действий пользователя на сайте. В этой статье мы рассмотрим как пользоваться curl, что это такое и зачем нужна эта программа.

На самом деле, curl - это больше чем просто утилита командной строки для Linux или Windows. Это набор библиотек, в которых реализуются базовые возможности работы с URL страницами и передачи файлов. Библиотека поддерживает работу с протоколами: FTP, FTPS, HTTP, HTTPS, TFTP, SCP, SFTP, Telnet, DICT, LDAP, а также POP3, IMAP и SMTP. Она отлично подходит для имитации действий пользователя на страницах и других операций с URL адресами.

Поддержка библиотеки curl была добавлена в множество различных языков программирования и платформ. Утилита curl - это независимая обвертка для этой библиотеки. Именно на этой утилите мы и остановимся в этой статье.

Команда curl

Перед тем как перейти к описанию того как может использоваться команда curl linux, давайте разберем саму утилиту и ее основные опции, которые нам понадобятся. Синтаксис утилиты очень прост:

$ curl опции ссылка

Теперь рассмотрим основные опции:

  • -# - отображать простой прогресс-бар во время загрузки;
  • -0 - использовать протокол http 1.0;
  • -1 - использовать протокол шифрования tlsv1;
  • -2 - использовать sslv2;
  • -3 - использовать sslv3;
  • -4 - использовать ipv4;
  • -6 - использовать ipv6;
  • -A - указать свой USER_AGENT;
  • -b - сохранить Cookie в файл;
  • -c - отправить Cookie на сервер из файла;
  • -C - продолжить загрузку файла с места разрыва или указанного смещения;
  • -m - максимальное время ожидания ответа от сервера;
  • -d - отправить данные методом POST;
  • -D - сохранить заголовки, возвращенные сервером в файл;
  • -e - задать поле Referer-uri, указывает с какого сайта пришел пользователь;
  • -E - использовать внешний сертификат SSL;
  • -f - не выводить сообщения об ошибках;
  • -F - отправить данные в виде формы;
  • -G - если эта опция включена, то все данные, указанные в опции -d будут передаваться методом GET;
  • -H - передать заголовки на сервер;
  • -I - получать только HTTP заголовок, а все содержимое страницы игнорировать;
  • -j - прочитать и отправить cookie из файла;
  • -J - удалить заголовок из запроса;
  • -L - принимать и обрабатывать перенаправления;
  • -s - максимальное количество перенаправлений с помощью Location;
  • -o - выводить контент страницы в файл;
  • -O - сохранять контент в файл с именем страницы или файла на сервере;
  • -p - использовать прокси;
  • --proto - указать протокол, который нужно использовать;
  • -R - сохранять время последнего изменения удаленного файла;
  • -s - выводить минимум информации об ошибках;
  • -S - выводить сообщения об ошибках;
  • -T - загрузить файл на сервер;
  • -v - максимально подробный вывод;
  • -y - минимальная скорость загрузки;
  • -Y - максимальная скорость загрузки;
  • -z - скачать файл, только если он был модифицирован позже указанного времени;
  • -V - вывести версию.

Это далеко не все параметры curl linux, но здесь перечислено все основное, что вам придется использовать.

Как пользоваться curl?

Мы рассмотрели все, что касается теории работы с утилитой curl, теперь пришло время перейти к практике, и рассмотреть примеры команды curl.

Самая частая задача - это . Скачать файл очень просто. Для этого достаточно передать утилите в параметрах имя файла или html страницы:

curl https://raw.githubusercontent.com/curl/curl/master/README.md

Но тут вас ждет одна неожиданность, все содержимое файла будет отправлено на стандартный вывод. Чтобы записать его в какой-либо файл используйте:

curl -o readme.txt https://raw.githubusercontent.com/curl/curl/master/README.md

А если вы хотите, чтобы полученный файл назывался так же, как и файл на сервере, используйте опцию -O:

curl -O https://raw.githubusercontent.com/curl/curl/master/README.md

curl -# -C - -O https://cdn.kernel.org/pub/linux/kernel/v4.x/testing/linux-4.11-rc7.tar.xz

Если нужно, одной командой можно скачать несколько файлов:

curl -O https://raw.githubusercontent.com/curl/curl/master/README.md -O https://raw.githubusercontent.com/curl/curl/master/README

Еще одна вещь, которая может быть полезной администратору - это загрузка файла, только если он был изменен:

curl -z 21-Dec-17 https://raw.githubusercontent.com/curl/curl/master/README.md -O https://raw.githubusercontent.com/curl/curl/master/README

Ограничение скорости

Вы можете ограничить скорость загрузки до необходимого предела, чтобы не перегружать сеть с помощью опции -Y:

curl --limit-rate 50K -O https://cdn.kernel.org/pub/linux/kernel/v4.x/testing/linux-4.11-rc7.tar.xz

Здесь нужно указать количество килобайт в секунду, которые можно загружать. Также вы можете разорвать соединение если скорости недостаточно, для этого используйте опцию -Y:

curl -Y 100 -O https://raw.githubusercontent.com/curl/curl/master/README.md

Передача файлов

curl -T login.txt ftp://speedtest.tele2.net/upload/

Или проверим отправку файла по HTTP, для этого существует специальный сервис:

curl -T ~/login.txt http://posttestserver.com/post.php

В ответе утилита сообщит где вы можете найти загруженный файл.

Отправка данных POST

Вы можете отправлять не только файлы, но и любые данные методом POST. Напомню, что этот метод используется для отправки данных различных форм. Для отправки такого запроса используйте опцию -d. Для тестирования будем пользоваться тем же сервисом:

curl -d "field1=val&fileld2=val1"http://posttestserver.com/post.php

Если вас не устраивает такой вариант отправки, вы можете сделать вид, что отправили форму. Для этого есть опция -F:

curl -F "password=@pass;type=text/plain" http://posttestserver.com/post.php

Здесь мы передаем формой поле password, с типом обычный текст, точно так же вы можете передать несколько параметров.

Передача и прием куки

Куки или Cookie используются сайтами для хранения некой информации на стороне пользователя. Это может быть необходимо, например, для аутентификации. Вы можете принимать и передавать Cookie с помощью curl. Чтобы сохранить полученные Cookie в файл используйте опцию -c:

curl -c cookie.txt http://posttestserver.com/post.php

Затем можно отправить cookie curl обратно:

curl -b cookie.txt http://posttestserver.com/post.php

Передача и анализ заголовков

Не всегда нам обязательно нужно содержимое страницы. Иногда могут быть интересны только заголовки. Чтобы вывести только их есть опция -I:

curl -I https://сайт

А опция -H позволяет или несколько на сервер, например, можно передать заголовок If-Modified-Since чтобы страница возвращалась только если она была изменена:

Аутентификация curl

Если на сервере требуется аутентификация одного из распространенных типов, например, HTTP Basic или FTP, то curl очень просто может справиться с такой задачей. Для указания данных аутентификации просто укажите их через двоеточие в опции -u:

curl -u ftpuser:ftppass -T - ftp://ftp.testserver.com/myfile_1.txt

Точно так же будет выполняться аутентификация на серверах HTTP.

Использование прокси

Если вам нужно использовать прокси сервер для загрузки файлов, то это тоже очень просто. Достаточно задать адрес прокси сервера в опции -x:

curl -x proxysever.test.com:3128 http://google.co.in

Выводы

В этой статье мы рассмотрели как пользоваться curl, зачем нужна эта утилита и основные ее возможности. Несмотря на свою схожесть с , они очень сильно отличаются. Команда curl linux предназначена больше для анализа и имитации различных действий на сервере, тогда как wget больше подходит для загрузки файлов и краулинга сайтов.