Urlencode и winapi ?

Тема в разделе "WASM.WIN32", создана пользователем M0rg0t, 26 мар 2022.

  1. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.550
    Понадобилось отправить POST запрос через винапи (WinInet) , и все бы ничего, но в данных был символ '+', который сайт просто порезал (т.к. его надо кодировать). Всегда считал, что вининет должен как бы сам преобразовывать все эти символы, но нет. Еще оказалось, что во всем огромном винапи за 30 лет не удосужились закодить функцию для url_encode данных. Точнее как - есть UrlEscape и InternetCanonicalizeUrl , обе не делают то, что надо (не трогают символ '+').

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

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    266
    https://en.wikipedia.org/wiki/Percent-encoding
    Есть прикол - данные которые отправляются в x-www-urlencoded отличаются от текущего стандарта urlencode (последняя часть статьи) и там + является сокращением для пробела в данных. Т.е. сайт его видимо не режет, а превращает в пробел по формату.
    Странно, что функции лажают, но если надо сделать быстро и объём данных небольшой проще все символы преобразовать в %XX без разбора, сервер обязан это расшифровать как следует.
    Но можно выкинуть из кодирования все алфавитно-цифровые символы и алгоритм не станет сильно сложным от этого.
     
    Последнее редактирование: 27 мар 2022
  3. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.550
    да.

    я взял самописную функцию, и проблема решилась, но непонятно почему в wininet этого нет по дефолту? Эта либа же предназначена для сетевых запросов, в чем удобство если все делать вручную?
     
  4. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    266
    Я кажется понял - функции типа InternetCanonicalizeUrl относятся к аргументу именно как к ссылке и ожидают на входе что-то типа "http://site.com/intro.php?param1=...". Т.е. это вообще не то что нужно тут.
    А у UrlEscape как раз флаг URL_ESCAPE_SEGMENT_ONLY и есть индикатор того, что нет первой части с http:// и надо кодировать все символы.
     
  5. M0rg0t

    M0rg0t Well-Known Member

    Публикаций:
    0
    Регистрация:
    18 окт 2010
    Сообщения:
    1.550
    Ну '+' она все равно не кодирует, даже с этим флагом.

    Мсдн говорит, что у нее есть флаг URL_ESCAPE_ASCII_URI_COMPONENT ,но увы, только для виндовс 8 и выше. Мб он бы подошел, но не подходит.
     
  6. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.786
    В RFC 1738 например прямо сказано, что плюс в URL допускается использовать без кодирования:
    Скорей всего имеет место какой-то иной стандарт, дополняющий RFC1738, который сервер использует. Гуглёж показал, что дело вероятней всего вот в этом стандартном поле http-заголовка:
    Эта схема данных плюсы не подразумевает и сервер совершенно справедливо плюсы гасит. Но тут уже полномочия майкрософт всё, надо либо что-то повыше уровнем использовать (ишака через автоматизацию или 'Microsoft.XMLHTTP', чтоб само кодировало), либо самому реализовывать.
     
    Последнее редактирование: 28 мар 2022
    M0rg0t нравится это.
  7. aa_dav

    aa_dav Active Member

    Публикаций:
    0
    Регистрация:
    24 дек 2008
    Сообщения:
    266
    У PHP вполне чётко нужная функция описана как раз со всеми вышеописанными приколами: https://www.php.net/manual/ru/function.urlencode.php
    Короче если полного аналога нет, то проще написать свою функцию.
    А все эти Url* это как раз по современному стандарту для URL по его RFC, с плюсами-исключениями и попытками трактовать строку как настоящий URL где сперва еще надо найти серверную, локаторную и параметризующую части чтобы понять что надо кодировать, а что нет. Фтопку.