На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Winhttp и русские символы
    Доброго времени суток! Разрабатываю приложение, которое общается с сервером по протоколу http. Все реализовано на Winhttp.
    При отправке запроса GET или POST, не важно, где имеются только, английские символы, вопросов не возникает, все проходит.
    А тут понадобилось отправлять запросы, где есть русские символы, вот тут и проблема.
    Есть запрос вида:
    ExpandedWrap disabled
      /lms/Do?name=Главная+страница&doaction=Go&id=0&type=StudentStartPage

    Если просматривать через Wireshark, то браузер отправляет запрос вида:
    ExpandedWrap disabled
      /lms/Do?name=%D0%93%D0%BB%D0%B0%D0%B2%D0%BD%D0%B0%D1%8F+%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0&doaction=Go&id=0&type=StudentStartPage

    Собственно и вопрос, как программно из первого получить второе???

    Да, на MSDN по функции WinHttpOpenRequest() есть такой флаг WINHTTP_FLAG_ESCAPE_PERCENT, но что-то я не врубаюсь, как подставлять параметры в эту функцию с этим флагом....
      Цитата Игорь98 @
      по протоколу http

      Протокол работает только на строках с 7 байтными символами.

      Для передачи других данных (двоичных, или, кириллических символов, может даже, юникод и т.д.) используют два распространённых подхода:

      1. Передача 16-ричного кода символа (ASCII) с префиксом %
      2. Передача данных в кодировке base64

      Вы выбрали первый путь. Он достигается довольно просто, ваши символы представляются в HEX последовательности из двух байт, далее, последовательность переводится в строку, и к каждому элементу добавляется знак % слева.

      Реализовать можно через библиотеку (смотреть функции преобразования url), либо самописным велосипедом. Тут раз, тут два.
      Сообщение отредактировано: VisualProg -
        Цитата
        Реализовать можно через библиотеку (смотреть функции преобразования url)

        А в самой библиотеке Winhttp, не предусмотрена ли определенная функция для таких действий?
          Цитата VisualProg @
          1. Передача 16-ричного кода символа (ASCII) с префиксом %

          utf8 там передается
            Цитата
            utf8 там передается


            Не пойму, где передается? У меня сейчас вот так, есть функция которая формирует запрос:

            ExpandedWrap disabled
              BOOL WINAPI SDO_HTTP::MakeRequest_GET(TCHAR *sVerb)
              {
                  BOOL bResult = FALSE;
                  SDO_HTTP::hRequest = nullptr;
               
                  SDO_HTTP::hRequest = WinHttpOpenRequest(SDO_HTTP::hConnect, _T("GET"), sVerb, nullptr, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_ESCAPE_PERCENT);
               
                  if(SDO_HTTP::hRequest)
                  {
                      if(SDO_HTTP::bSetCookie)
                      {
                          WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_HTTP::sCookie, -1, 0x00);
                      }
               
                      WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_UPG_IN, -1, 0x00);
                      WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_ACCEPT, -1, 0x00);
                      WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_ACCEPT_EN, -1, 0x00);
                      WinHttpAddRequestHeaders(SDO_HTTP::hRequest, SDO_ACCEPT_LN, -1, 0x00);
               
                      bResult = TRUE;
                  }
                  else
                  {
                      SDO_HTTP::hRequest = nullptr;
                  }
               
                  return bResult;
              }


            В sVerb, я передаю "/lms/Do?s=%s&name=Главная+страница&doaction=Go&id=0&type=StudentStartPage"
            Но, что-то он в utf8 ничего не преобразовывает...
            На выходе вот такая хрень: GET /lms/Do?s=933MuHPS2MxvUqQkQ4Mc&name=..............+................&doaction=Go&id=0&type=StudentStartPage HTTP/1.1
              Ну, есть ещё WinHttpCreateUrl().

              Добавлено
              Цитата Игорь98 @
              В sVerb, я передаю "/lms/Do?s=%s&name=Главная+страница&doaction=Go&id=0&type=StudentStartPage"
              Но, что-то он в utf8 ничего не преобразовывает...
              Заметь, русское "Главная+страница" в УРЛе должно быть правильно преобразовано компилятором в L"Главная+страница", если у тебя юникод. Обычно для этого достаточно, чтобы сырец был в CP1251, и компилятор это правильно понял. Именно компилятором, т.к. он преобразует строки твоего .cpp в строковые литералы TCHAR[].
                Цитата shm @
                utf8 там передается

                Есть куча условностей, хотя, в чистом виде, скорее всего можно передать UTF-8, но, в том же хидере, 100% не получится засунуть символы на вроде ":" в значение параметра/атрибута. Например, если в char попытаться впихнуть символ больший 7 битного, точно навернётся js-совский соккет. Хотя, опять же, возможно, требуется шаманить с указанием версии протокола http и зависит от браузера и версии js на нём.

                В случае с сервером - всё диктует непосредственно сервер. Там может быть полноценная 8 битная кодировка, но, это уже должен был нам рассказать автор вопроса.

                Я всего лишь привёл гарантированный способ передачи данных по хттп :(

                Добавлено
                Цитата Игорь98 @
                А в самой библиотеке Winhttp, не предусмотрена ли определенная функция для таких действий?

                Я более чем уверен что предусмотрена.
                Сообщение отредактировано: VisualProg -
                  Нативной поддержки utf-8 в WinHTTP не будет.

                  Игорь98, что за траблы, понятия не имею. У меня работает:
                  ExpandedWrap disabled
                    #include <windows.h>
                    #include <winhttp.h>
                    #include <iostream>
                    #include <locale>
                    #include <vector>
                    #include <string>
                     
                    template <typename T, size_t N>
                    constexpr size_t sizeOf(T (&arg)[N])
                    {
                      using traits = std::char_traits<T>;
                     
                      return N - (arg[N-1] == traits::to_char_type(static_cast<traits::int_type>('\0')));
                    }
                     
                    int main()
                    {
                      URL_COMPONENTS urlComp;
                      wchar_t        urlStr[] = L"domain.рф/lms/Do?s=%s",
                                     urlExtra[]=L"&name=Главная+страница&doaction=Go&id=0&type=StudentStartPage";
                      DWORD urlLen = 0;
                     
                      std::wcout.imbue(std::locale("russian_russia.OCP"));
                     
                      ZeroMemory(&urlComp, sizeof(urlComp));
                      urlComp.dwStructSize = sizeof(urlComp);
                     
                      urlComp.nScheme       = INTERNET_SCHEME_HTTP;
                      urlComp.lpszHostName  = urlStr;
                      urlComp.lpszExtraInfo = urlExtra;
                      urlComp.dwHostNameLength  = sizeOf(urlStr);
                      urlComp.dwExtraInfoLength = sizeOf(urlExtra);
                     
                      WinHttpCreateUrl( &urlComp, ICU_ESCAPE, NULL, &urlLen);
                      std::vector<wchar_t> newUrl(urlLen);
                     
                      if (!WinHttpCreateUrl( &urlComp, ICU_ESCAPE, &newUrl.front(), &urlLen))
                        std::wcerr << L"WinHttpCreateUrl(): error is " << GetLastError() << std::endl;
                      else                                                      
                        std::wcout << L"Old URL: " << L"http://" + std::wstring(urlStr) + urlExtra << "\nNew URL: " << &newUrl.front() << std::endl;
                    }
                  Сообщение отредактировано: Qraizer -
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0406 ]   [ 17 queries used ]   [ Generated: 28.03.24, 13:54 GMT ]