Blog. Just Blog

Отправка POST- и GET-запросов на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Отправка POST- и GET-запросов на Ассемблере
Отправка POST- и GET-запросов на Ассемблере

В наше время интернет-технологий профессиональные приложения должны уметь работать с удаленными сервисами. Хороший пример был в недавней статье про оптимизацию изображений. Тут есть все: отправка файла через POST-запрос и получение ответа в виде текстового JSON, а затем скачивание изображения по прямой ссылке через GET-запрос. Давайте реализуем работу с POST- и GET-запросами на Ассемблере, а чтобы польза от работы получилась не только теоретической, но и практической, это будет пример с оптимизацией графических файлов через API сервиса TinyPNG.

Для начала немного констант, о которых не знает FASM. Это не COM, так что огромных портянок с интерфейсами тут не будет.
  1. WINHTTP_ACCESS_TYPE_NO_PROXY = 1
  2. WINHTTP_NO_PROXY_NAME = 0
  3. WINHTTP_NO_PROXY_BYPASS = 0
  4. WINHTTP_NO_REFERER = 0
  5. WINHTTP_DEFAULT_ACCEPT_TYPES = 0
  6. WINHTTP_FLAG_SECURE = 0x00800000
  7.  
  8. INTERNET_DEFAULT_HTTPS_PORT = 443
  9. INTERNET_DEFAULT_HTTP_PORT  = 80
  10.  
  11. WINHTTP_OPTION_SECURITY_FLAGS = 31
  12. WINHTTP_NO_CLIENT_CERT_CONTEXT = 0
Условно весь код можно разделить на три части: подготовка соединения, отправка запроса и получение результата.
  1.         ; Открыть сессию работы с интернетом
  2.         invoke  WinHttpOpen,szUA,\
  3.                 WINHTTP_ACCESS_TYPE_NO_PROXY,\
  4.                 WINHTTP_NO_PROXY_NAME,\
  5.                 WINHTTP_NO_PROXY_BYPASS,\
  6.                 0
  7.         or      eax,eax
  8.         jz      loc_exit
  9.  
  10.         mov     [hSession],eax
  11.  
  12.         ; Соединение с удаленным сервером
  13.         invoke  WinHttpConnect,[hSession],\
  14.                 szServer,\
  15.                 INTERNET_DEFAULT_HTTPS_PORT,\
  16.                 0
  17.         or      eax,eax
  18.         jz      loc_close_session
  19.  
  20.         mov     [hConnect],eax
С помощью функции WinHttpOpen настраивается строка User-Agent, которая будет в дальнейшем использоваться, а также выбираются параметры для прокси, если таковые будут задействованы. Функция WinHttpConnect открывает соединение с удаленным сервером по заданному протоколу, в нашем случае это HTTPS.
  1.         ; Подготовить POST-запрос для отправки файла
  2.         invoke  WinHttpOpenRequest,[hConnect],\
  3.                 szPOST,szUrl,NULL,\
  4.                 WINHTTP_NO_REFERER,\
  5.                 WINHTTP_DEFAULT_ACCEPT_TYPES,\
  6.                 WINHTTP_FLAG_SECURE
  7.         or      eax,eax
  8.         jz      loc_close_connect
  9.  
  10.         mov     [hRequest],eax
  11.  
  12.         ; Настроить опции для запроса
  13.         mov     [dOptions],WINHTTP_NO_CLIENT_CERT_CONTEXT
  14.         invoke  WinHttpSetOption,[hRequest],\
  15.                 WINHTTP_OPTION_SECURITY_FLAGS,\
  16.                 dOptions,\
  17.                 4
  18.         or      eax,eax
  19.         jz      loc_close_request
  20.  
  21.         ; Прочитать исходный файл в память
  22.         ; [pMem] -> указатель на память с данными отправляемого файла
  23.         ; [dFSize] -> размер отправляемых данных
  24.  
  25.         ; Отправить в запросе содержимое файла
  26.         invoke  WinHttpSendRequest,[hRequest],\
  27.                 szHeaders,-1,\
  28.                 [pMem],[dFSize],[dFSize],\
  29.                 0
  30.         or      eax,eax
  31.         jz      loc_close_request
Для GET-запроса код будет чуть другой, поскольку все данные передаются в параметрах:
  1.         ; Выполнить GET-запрос
  2.         invoke  WinHttpSendRequest,[hRequest],\
  3.                 szHeaders,-1,\
  4.                 0,0,0,\
  5.                 0
  6.         or      eax,eax
  7.         jz      loc_close_request
Функция WinHttpOpenRequest определяет URL и тип запроса (POST, GET, PUT, DELETE и т.д.). Дополнительные опции устанавливаются функцией WinHttpSetOption, это могут быть, например, предпочтительная кодировка, действие в случае неправильного сертификата, таймаут запроса и еще множество других параметров, о которых подробно написано в документации. За непосредственную отправку запроса отвечает функция WinHttpSendRequest, где определяются передаваемые в запросе данные и можно настроить дополнительные HTTP-заголовки, например, куки, авторизацию, реферы и все остальное, что требуется.
  1.         ; Получить результат запроса
  2.         invoke  WinHttpReceiveResponse,[hRequest],NULL
  3.         or      eax,eax
  4.         jz      loc_close_request
  5. @@:
  6.         ; Читать данные до победного результата
  7.         invoke  WinHttpReadData,[hRequest],buff,BUFF_SIZE,tmp
  8.  
  9.         ; buff -> прочитанная порция данных
  10.         ; [tmp] -> размер прочитанных данных
  11.  
  12.         ; Все данные получены?
  13.         cmp     [tmp],BUFF_SIZE
  14.         je      @b
После отправки запроса обычно требуется получить какой-то результат. Для этого система оповещается, что приложение готово прочитать данные из соединения, за это отвечает функция WinHttpReceiveResponse. Сами данные читаются при помощи функции WinHttpReadData. Читать их можно сразу за один проход или же выкачивать постепенно, если объем получаемых данных значительный. Все зависит от решаемой задачи. Все последующие запросы к этому же серверу выполняются с шага 2, повторно инициализировать сессию и открывать соединение с сервером не требуется.
  1. loc_close_request:
  2.         ; Завершить запрос к серверу
  3.         invoke  WinHttpCloseHandle,[hRequest]
  4. loc_close_connect:
  5.         ; Закрыть соединение
  6.         invoke  WinHttpCloseHandle,[hConnect]
  7. loc_close_session:
  8.         ; Завершить сессию
  9.         invoke  WinHttpCloseHandle,[hSession]
Когда все запросы будут выполнены и данные получены, необходимо закрыть соединения и завершить сессию.

В приложении пример программы с исходным текстом, которая отправляет файл с изображением на сервер TinyPNG и получает оптимизированную картинку. Если все сделано правильно, то будут созданы файлы response.dat с JSON-данными ответа и оптимизированное изображение optimized.png. ВАЖНО! Для корректной работы с сервисом TinyPNG в файле tinypng.key должна быть записана строка авторизации в формате base64("api:ваш_ключ") и в кодировке UTF-16 без BOM. Также можете просто внести ее в исходник перед компиляцией. По понятным причинам свой ключ я тут выкладывать не собираюсь.

Пример программы с исходным текстом (FASM)Пример программы с исходным текстом (FASM)

POST.GET.Request.Demo.zip (89,353 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 901 | Комментариев: 2

Метки: Assembler, сеть
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (12.03.2023 в 18:11):
Именно так, решил новые функции поосваивать.
morgot (12.03.2023 в 17:26):
Спасибо! А почему winhttp, а не wininet? Для разнообразия? Я использовал его, но как-то больше привык к вининет.
Кстати, winhttp тоже доступен через СОМ.

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0075 сек.) / Память: 4.5 Mb
Наверх