#inno-setup #winhttprequest
#inno-setup #winhttprequest
Вопрос:
Основываясь на некотором вопросе SO, который я видел ранее, я использую WinHttpRequest
внутри Inno Setup для выполнения GET
запроса к веб-серверу ( localhost:8000
прямо сейчас). Минимальный приведенный ниже код, запрос направлен на встроенный сервер отладки Django ( python manage.py runserver
).
procedure InitializeWizard();
var
WinHttpReq: Variant;
url: string;
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER: integer;
begin
url := 'http://localhost:8000/odbc/test/';
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER := 0;
WinHttpReq := CreateOleObject('WinHttp.WinHttpRequest.5.1');
WinHttpReq.Open('GET', url, false);
WinHttpReq.SetRequestHeader('Accept','application/json');
WinHttpReq.SetCredentials('username','password',HTTPREQUEST_SETCREDENTIALS_FOR_SERVER);
WinHttpReq.Send();
MsgBox(WinHttpReq.Status, mbInformation, MB_OK);
MsgBox(WinHttpReq.ResponseText, mbInformation, MB_OK);
end;
Это дает мне 403, учетные данные для аутентификации не предоставлены.
Напротив, этот код в библиотеке запросов Python работает успешно.
>> import requests
>> r = requests.get('http://localhost:8000/odbc/test/', auth=('username','password'))
>> r.status_code
200
Я неправильно понимаю, как работает WinHttpRequest
объект? Потому что Wireshark подтверждает, что Authorization: Basic *hashstring*
заголовок был отправлен в заголовке с запросами Python, но не в WinHttpRequest
случае. Вероятным обходным путем было бы самостоятельно установить заголовок для WinHttpRequest
объекта, но мне просто любопытно, делаю ли я что-то не так.
Суть захвата пакетов:https://gist.github.com/anonymous/597468ba76b59dae4a8d7809ee1c6feb
Скриншоты Wireshark:
Комментарии:
1. Работает для меня (на сервере Apache) — 1) Есть ли у вас какие-либо специальные символы в имени пользователя / пароле? 2) Можете ли вы попытаться перехватить HTTP-трафик, используя, например, Wireshark, как для установочного кода Inno, так и для кода Python? И опубликовать их здесь? Или, по крайней мере, журналы веб-сервера для обоих.
2. Добавлены скриншоты wireshark capture. Есть ли лучший формат для публикации записей wireshark?
3. Когда вы остановите захват, вы можете сохранить трафик в файл. Обратите внимание, что
WinHttpRequest
отправляет два HTTP-запроса. В первый раз без аутентификации, а затем после получения 401 он отправляет второй запрос с авторизацией. Поэтому нам нужно просмотреть оба запроса, включая ответы с сервера.4. Добавлена суть. Я не вижу, откуда вы видите два запроса
WinHttpRequest
.5. Их нет в ваших записях, потому что ваш сервер не отправляет
WWW-Authenticate
заголовок. Но я вижу их, когда тестирую ваш код на своем сервере (Apache). Если я настрою свой сервер так, чтобы он вел себя так же, как ваш (безWWW-Authenticate
заголовка), я получаю то же поведение, что и вы (только один запрос, безAuthenticate
заголовка).
Ответ №1:
Я предполагаю, что это несовместимость между WinHttpRequest
и вашим «сервером отладки Django».
WinHttpRequest
Отправляет Authenticate
заголовок только после запроса сервером с WWW-Authenticate
заголовком.
В ответе 403 от вашего сервера такого заголовка нет. Следовательно, WinHttpRequest
не отправляет Authorization
заголовок.
Решения:
-
Заставьте ваш сервер возвращать
WWW-Authenticate
заголовок (и в идеале статус 401 — хотя это не требуетсяWinHttpRequest
). -
Отправьте
Authenticate
заголовок явно с помощью:WinHttpReq.SetRequestHeader('Authorization', 'Basic ???');