Понадобилось отправить POST запрос через винапи (WinInet) , и все бы ничего, но в данных был символ '+', который сайт просто порезал (т.к. его надо кодировать). Всегда считал, что вининет должен как бы сам преобразовывать все эти символы, но нет. Еще оказалось, что во всем огромном винапи за 30 лет не удосужились закодить функцию для url_encode данных. Точнее как - есть UrlEscape и InternetCanonicalizeUrl , обе не делают то, что надо (не трогают символ '+'). В итоге, выдрал самописную функцию из карберпа, но мб есть какое-то еще решение? Может какой-то флаг для вининет, чтобы кодировал?
https://en.wikipedia.org/wiki/Percent-encoding Есть прикол - данные которые отправляются в x-www-urlencoded отличаются от текущего стандарта urlencode (последняя часть статьи) и там + является сокращением для пробела в данных. Т.е. сайт его видимо не режет, а превращает в пробел по формату. Странно, что функции лажают, но если надо сделать быстро и объём данных небольшой проще все символы преобразовать в %XX без разбора, сервер обязан это расшифровать как следует. Но можно выкинуть из кодирования все алфавитно-цифровые символы и алгоритм не станет сильно сложным от этого.
да. я взял самописную функцию, и проблема решилась, но непонятно почему в wininet этого нет по дефолту? Эта либа же предназначена для сетевых запросов, в чем удобство если все делать вручную?
Я кажется понял - функции типа InternetCanonicalizeUrl относятся к аргументу именно как к ссылке и ожидают на входе что-то типа "http://site.com/intro.php?param1=...". Т.е. это вообще не то что нужно тут. А у UrlEscape как раз флаг URL_ESCAPE_SEGMENT_ONLY и есть индикатор того, что нет первой части с http:// и надо кодировать все символы.
Ну '+' она все равно не кодирует, даже с этим флагом. Мсдн говорит, что у нее есть флаг URL_ESCAPE_ASCII_URI_COMPONENT ,но увы, только для виндовс 8 и выше. Мб он бы подошел, но не подходит.
В RFC 1738 например прямо сказано, что плюс в URL допускается использовать без кодирования: Скорей всего имеет место какой-то иной стандарт, дополняющий RFC1738, который сервер использует. Гуглёж показал, что дело вероятней всего вот в этом стандартном поле http-заголовка: Эта схема данных плюсы не подразумевает и сервер совершенно справедливо плюсы гасит. Но тут уже полномочия майкрософт всё, надо либо что-то повыше уровнем использовать (ишака через автоматизацию или 'Microsoft.XMLHTTP', чтоб само кодировало), либо самому реализовывать.
У PHP вполне чётко нужная функция описана как раз со всеми вышеописанными приколами: https://www.php.net/manual/ru/function.urlencode.php Короче если полного аналога нет, то проще написать свою функцию. А все эти Url* это как раз по современному стандарту для URL по его RFC, с плюсами-исключениями и попытками трактовать строку как настоящий URL где сперва еще надо найти серверную, локаторную и параметризующую части чтобы понять что надо кодировать, а что нет. Фтопку.