Итак, возникла следующая задача — определить, когда curl
получил вменяемые данные от http-сервера, а когда нет. В общем, и самом распространенном случае, задача сводится к тому, чтобы определить, отдал ли нам сервер запрашиваемый файл, или отобразил «страница не найдена».
Впрочем, это работает и для других возможных кодов ответа.
Ясно, что сервер, на наш запрос GET
может ответить, как возвратив нам запрашиваемую страницу, так и отправив код, например, 404 (не найдено)
, и возвратив страницу-заглушку для этого случая. Так вот, на уровне скрипта bash или скрипта php необходимо проанализировать ответ сервера, чтобы не выдать пользователю вместо ожидаемых данных, всяческую лабуду. Далее я рассматриваю исключительно консольную Linux-утилиту curl
. Для php, синтаксис, по-моему, отличается.
Есть страница, которую мы хотим получить: http://example.org/page.html
, сохранить ее в файл page.html
и есть curl
, команда будет такая:
curl -o "page.html" http://example.org/page.html
Если страница на месте, то мы получим ее, и ничего анализировать не требуется.
Если же нет, то от большинства web-серверов мы получим страницу-заглушку, например такую, но никакой ошибки при этом.
Как же быть:
Проверяем код ошибки самого curl
, если нет связи с сетью, URL неправильный, или задан неподдерживаемый curl
протокол, если так, то мы получим соответствующий код возврата, наподобие:
curl: (1) Protocol htt not supported or disabled in libcurl
А вот если адрес правильный, и никакой ошибки в адресе или соединении нет, то код возврата не сработает, нам самим придется думать дальше.
Надо получить код ответа HTTP!
Сделать это можно, если получить отдельно заголовки ответа сервера, и после их проанализировать. Благо, для этого никакого страшного колдунства не требуется, достаточно указать утилите curl
опцию -D
(т.е. dump
) и файл, куда выгружать заголовки.
Покажу это на примере конкретного скрипта:
#!/bin/bash HEADERDUMP="/tmp/headerdump.txt" SAVEFILE="/tmp/httpfile" HTTPSTATUS="" curl -o $SAVEFILE $1 -D $HEADERDUMP >/dev/null 2>/dev/null EXITCODE=$? if [ $EXITCODE -ne 0 ]; then echo "CURL error $EXITCODE" else HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'` if [ "$HTTPSTATUS" == "200" ];then echo "OK" else echo "HTTP error $HTTPSTATUS" fi fi
заводим 3 переменные
HEADERDUMP="/tmp/headerdump.txt"
— файл, в который будем получать заголовки
SAVEFILE="/tmp/httpfile"
— файл с сервера, который мы хотим получить
HTTPSTATUS=""
— переменная для статуса (состояния) HTTP
curl -o $SAVEFILE $1 -D $HEADERDUM
пытаемся скачать нужный файл (получить страницу):
-o
«имя_файла» — куда сохранять результат
$1
— внутренняя переменная, первый параметр скрипта, при вызове его с командной строки. В своем скрипте надо заменить на свой случай.
можно добавить >/dev/null 2>/dev/null
— для красоты, чтоб не вылезали сообщения о процессе и ошибках.
-D <файл>
— файл, куда будем копировать заголовки
Файл headerdump.txt
выглядит примерно так:
HTTP/1.1 200 OK
Server: nginx/1.12.2
Date: Fri, 30 Mar 2018 00:17:23 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.6.33
Link:
Set-Cookie: quick_chat_alias=Anon_240883; path=/
Upgrade: h2,h2c
Vary: Accept-Encoding,User-Agent
В первой строке — интересующая нас информация. Версия протокола (не интересно), код ответа (вот он) и информационное сообщение (не особо надо).
Вычленяем код:
HTTPSTATUS=`cat $HEADERDUMP|head -1|awk '{print $2}'`
1. Берем первую строчку (head -1
)
2. Сохраняем в переменную 2-е значение после пробела (разделитель пробел): awk '{print $2}'
Дальше можно анализировать:
if [ "$HTTPSTATUS" == "200" ];then echo "OK" else echo "HTTP error $HTTPSTATUS" fi
Также, впрочем, можно поступить и для анализа запросов POST, вот тестовый скрипт php для отладки подобных возможностей и скрипт bash
Пример с запросом GET
Пример с запросом GET на Гитхаб
Пример с запросом POST
Пример с запросом POST на Гитхаб
Pingback: Linux, curl, обнаружение и анализ ошибок HTTP. Улучшаем скрипт. | Персональный блог Толика Панкова