Выбор веб-клиента для общения с ЖЖ из скрипта, PowerShell, моделирование

Jan 19, 2023 19:23

Начало:
1. Общение с ЖЖ из скрипта по протоколу HTTP(S), ч.1: документация
2. Общение с ЖЖ из скрипта по протоколу HTTP(S), ч.2: URL-адрес входа, интерфейсы

Почему не подходит браузер

Большинство пользователей использует в качестве веб-клиента обычный браузер. Попробуем обратиться к ЖЖ по интерфейсам «flat» и «XML-RPC» из браузера. Для этого введем в адресную строку браузера соответствующие URL-адреса входа:

1.

https://www.livejournal.com/interface/flat



Получили следующий результат в окне браузера:

errmsg
Client error: No mode specified.
success
FAIL

В предыдущем посте я описывал формат этой строки, полученной от веб-приложения «LiveJournal». В блоке кода выше мы получили два параметра с именами «errmsg» и «success». Перепишем их в более понятном формате:

errmsg = "Client error: No mode specified."
success = "FAIL"

Второй параметр с названием «success» (по-русски «успех») может принимать два значения: «OK» (если полученный запрос обработан веб-приложением «LiveJournal» успешно) и «FAIL» (обработка полученного запроса веб-приложением «LiveJournal» завершилась неудачей; наш случай). В первом параметре с названием «errmsg» описана причина неудачи: в запросе от веб-клиента (браузера) не определен параметр с названием «mode».

Как я описывал в предыдущем посте, веб-клиент должен поместить названия и значения параметров запроса в тело HTTP-запроса. Но как это сделать в браузере?

По умолчанию вы не можете в браузере напрямую задать содержимое тела HTTP-запроса. Вы можете лишь задать в адресной строке браузера URL-адрес, по которому браузер отправит HTTP-запрос. Для простого перехода на указанный пользователем в адресной строке браузера URL-адрес браузер отправляет HTTP-запрос по методу «GET»; в таком HTTP-запросе вообще нет тела HTTP-запроса. При отправке данных HTML-формы на веб-сервер браузер отправляет HTTP-запрос по методу «POST», в котором присутствует тело HTTP-запроса, автоматически заполняемое данными из HTML-формы (тело HTTP-запроса в данном случае заполняется браузером, вы можете лишь менять данные в HTML-форме).

Таким образом, браузер по умолчанию не дает нам достаточного контроля над HTTP-запросом, чтобы работать с ЖЖ по интерфейсу «flat» (или по интерфейсу «XML-RPC»). Возможно, существуют какие-то браузерные расширения, дающие необходимые возможности, но я предпочитаю не иметь дела с браузерными расширениями, так как они бывают небезопасны.

2.

https://www.livejournal.com/interface/xmlrpc

На этот URL-адрес, введенный в адресной строке браузера, я получил от веб-приложения «LiveJournal» HTTP-ответ с кодом состояния 200 (запрос обработан успешно), но в этом HTTP-ответе отсутствовало тело (content). Окно браузера осталось пустым. Причина отсутствия ответа на запрос в теле HTTP-ответа, думаю, та же, что и в случае с HTTP-запросом по интерфейсу «flat», описанному выше: в запросе не переданы нужные параметры (для данного интерфейса они должны были быть в формате XML).

Тексты отправленного HTTP-запроса и полученного HTTP-ответа в браузере можно просмотреть в инструменте «Network» инструментов разработчика (в моем браузере инструменты разработчика для текущей вкладки браузера вызываются клавишей «F12» с клавиатуры).

Командлет «Invoke-WebRequest» программы-оболочки «PowerShell»

В принципе, существует множество подходящих веб-клиентов. Выбор зависит от языка программирования, на котором вы хотите писать свой скрипт (программу) для общения с ЖЖ. Мне сейчас интересен язык программирования «PowerShell» и одноименная программа-оболочка. Я работаю в операционной системе «Windows 10» и использую программу-оболочку «PowerShell» версии 7. В этой программе-оболочке существует известный командлет «Invoke-WebRequest» для формирования и отправки HTTP-запросов и получения HTTP-ответов прямо из командной строки. Для задач посложнее на языке «PowerShell» можно написать скрипт. Таким образом, для общения с ЖЖ из скрипта я выбираю этот инструмент.

Повторим вышеописанный опыт с браузером в программе-оболочке «PowerShell»:

PS C:\> $Response = Invoke-WebRequest -URI "https://www.livejournal.com/interface/flat"
PS C:\> $Response.Content
errmsg
Client error: No mode specified.
success
FAIL



Ответ мы получили тот же, что и в браузере. Однако, в отличие от браузера в командлете «Invoke-WebRequest» мы можем прямо формировать разные части HTTP-запроса (в том числе и тело HTTP-запроса) через параметры этого командлета. Разных параметров у него довольно много.

Что получает веб-приложение от командлета «Invoke-WebRequest»

Как я понял, у командлета «Invoke-WebRequest» есть небольшой недостаток: мы не видим итогового текста отправляемого HTTP-запроса, хоть и можем формировать отдельные его части (HTTP-ответ полностью доступен, в блоке кода выше он сохранен в переменной $Response). Конечно, в скрипте на языке «PowerShell» мне доступны классы платформы «.NET» вроде «System.Net.HttpWebRequest» или «System.Net.Http.HttpClient», которые дают более свободный доступ к тексту HTTP-запроса, но пока что я решил обойтись командлетом «Invoke-WebRequest».

Хорошо, мы не можем видеть, в каком виде командлет «Invoke-WebRequest» отправляет HTTP-запрос. Но, ведь, я могу зайти с другой стороны пары клиент-сервер, то есть со стороны веб-сервера, и посмотреть, что получает веб-сервер (это и будет то, что отправил командлет «Invoke-WebRequest»).

Недавно я начал работать с веб-севером «IIS» версии 10 и с интерпретатором PHP у себя на компьютере локально. Я решил написать простую модель веб-приложения на языке PHP, которая будет получать HTTP-запрос от веб-клиента и сохранять его в текстовом файле (после этого я смогу просмотреть текст этого HTTP-запроса). Вот что у меня получилось:

$header_value) {
$request .= $header_name.": ".$header_value."\n";
}
$request .= "\n".file_get_contents('php://input');
file_put_contents('testFolder\test.txt', $request);

Следует отметить, что веб-приложение на языке PHP не может сразу получить исходный текст HTTP-запроса от веб-клиента, так как сначала его получает веб-сервер (в моем случае «IIS») и сразу разделяет на куски. В итоге веб-приложению доступны только эти куски. Поэтому в коде выше пришлось собирать HTTP-запрос из этих кусков обратно в исходный текст. Напомню, $_SERVER - это предопределенная встроенная переменная-массив.

Я поместил код из блока кода выше в файл «test.php», который перед этим создал у себя на рабочем столе (это важно: владельцем созданного таким образом файла записывается текущая учетная запись пользователя компьютера). После этого я переместил этот файл в папку «C:\inetpub\wwwroot\» своего локального сайта (для перемещения файла в эту папку требуются права администратора компьютера). Так как моя учетная запись пользователя является владельцем файла «test.php», то я могу его редактировать из редактора «VS Code» (или другого текстового редактора) прямо в папке «C:\inetpub\wwwroot\» из-под своей учетной записи, не поднимая права доступа до прав администратора компьютера.

Если теперь запустить веб-приложение «test.php», то оно не сможет создать папку «testFolder» и файл «test.txt» в этой папке, так как не имеет нужных прав доступа. Напомню, веб-сервер «IIS» версии 10 устроен так, что веб-приложение «test.php» запускается от встроенной учетной записи соответствующего пула приложений (у меня это учетная запись «DefaultAppPool»). Чтобы веб-приложение «test.php» могло создать вышеуказанные папку и файл, у учетной записи «DefaultAppPool» должны быть соответствующие права доступа.

Папку «C:\inetpub\wwwroot\testFolder» я создал вручную (понадобились права администратора компьютера), а затем дал полный доступ к этой папке, ее подпапкам и файлам встроенной учетной записи «DefaultAppPool». Как это сделать, я подробно описывал в отдельном посте.

Теперь отправляем HTTP-запрос веб-приложению «test.php» с помощью командлета «Invoke-WebRequest»:

PS C:\> $Response = Invoke-WebRequest -URI "https://localhost/test.php"

В результате этой команды у меня в папке «C:\inetpub\wwwroot\testFolder» появился файл «test.txt» со следующим содержимым:

GET /test.php HTTP/1.1
Content-Type:
Content-Length: 0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Microsoft Windows 10.0.19045; ru-RU) PowerShell/7.3.1
Host: localhost

Это текст HTTP-запроса, полученный веб-приложением «test.php» от командлета «Invoke-WebRequest». Тут можно видеть, как этот командлет формирует HTTP-запрос по умолчанию (в параметрах этого командлета я указал только URL-адрес, остальное он сформировал сам; эти умолчания можно изменить с помощью других параметров этого командлета). Кстати, видно, что по умолчанию тело HTTP-запроса отсутствует. Теперь можно начать экспериментировать с командлетом «Invoke-WebRequest» более подробно.

Продолжение следует.

Инструмент, Образование, Сайтостроение, Программирование, ЖЖ

Previous post Next post
Up