Indy, AResponseInfo.ServeFile, кирилица в названии файла

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение GAMER » 16.04.2019 14:14:28

Код: Выделить всё
        AResponseInfo.ServeFile(AContext, '1111рр22.png');

рр - кириличные.
Файл такой существует.
ServeFile с кирилицей вообще работает?
Посмотрел исходники.
В модуле IdStackwindows
в коде
Код: Выделить всё
LFileHandle := CreateFile(
    {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(AFileName){$ENDIF},
    GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);

  if LFileHandle <> INVALID_HANDLE_VALUE then     

Срабатывает INVALID_HANDLE_VALUE. Думаю, что причина в PChar(AFileName)?
Кто как отрабатывает загрузку файлов с кирилицей и пробелами?
Аватара пользователя
GAMER
энтузиаст
 
Сообщения: 627
Зарегистрирован: 06.08.2008 13:41:07
Откуда: Ужгород-Днепр, Украина

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение Дож » 16.04.2019 14:19:29

Я конвертирую utf-8 в wide char и вызываю W функции.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение GAMER » 16.04.2019 14:39:05

В своем коде или подправляете Инди?
Аватара пользователя
GAMER
энтузиаст
 
Сообщения: 627
Зарегистрирован: 06.08.2008 13:41:07
Откуда: Ужгород-Днепр, Украина

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение Лекс Айрин » 16.04.2019 14:43:14

GAMER, конечно в своем. Поправлять код пакетов верный способ все испортить.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение Дож » 16.04.2019 14:56:33

А, да, сорри, я про свой код.

Будет ли PChar и String маппироваться в PAnsiChar/AnsiString или в PWideChar/WideString определяется переключателем {$MODESWITCH UnicodeStrings}.

Тут говорится, что для того, чтобы Indy передавал в виндовые вызовы юникод, он ждёт дефайна UNICODE.

Чтобы понять какую именно ошибку выдаёт CreateFile (действительно ли это ERROR_BAD_PATHNAME) нужно смотреть что возвращает GetLastError.

В строке AResponseInfo.ServeFile(AContext, '1111рр22.png'); кодировка строковой литералы (и, соответственно, тип и неявные преобразования) определяется опцией CODEPAGE текущего исходника.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение GAMER » 17.04.2019 13:09:17

Дож писал(а):Тут говорится, что для того, чтобы Indy передавал в виндовые вызовы юникод, он ждёт дефайна UNICODE.

прошу прощения, но я не понял где єтот дефайн прописать?
Аватара пользователя
GAMER
энтузиаст
 
Сообщения: 627
Зарегистрирован: 06.08.2008 13:41:07
Откуда: Ужгород-Днепр, Украина

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение Дож » 17.04.2019 13:39:04

Глобально на весь проект, либо для indy модулей.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение GAMER » 17.04.2019 13:59:24

Код: Выделить всё
program rocket2mess;

{$mode objfpc}{$H+}
//{$MODESWITCH UnicodeStrings}
{$DEFINE UNICODE} 

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset     


Делал так, и через модесвич - не сработало
А эти дефайны срабатывают в модулях, которые подключаются?
Аватара пользователя
GAMER
энтузиаст
 
Сообщения: 627
Зарегистрирован: 06.08.2008 13:41:07
Откуда: Ужгород-Днепр, Украина

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение Дож » 17.04.2019 14:14:55

Нет, дефайны, объявленные в файле, действуют только локально на этот файл.

Нужно установить его в настройках проекта (либо опцией -d если в командной строке, либо в настройках сборки Indy если он собирается отдельно от основного проекта).
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение GAMER » 24.04.2019 13:21:32

И так, борьба продолжается.
1. Сделал через -d UNICODE в проекте. Код при дефайнах меняется, значит параметр отрабатывает, но не компилируется из-за других ошибок в Инди.
2. Начал разбирать код. Увидел, что в IdStackWindows в коде
Код: Выделить всё
function ServeFile(ASocket: TIdStackSocketHandle; const AFileName: string): Int64;
var
  LFileHandle: THandle;
  LSize: LARGE_INTEGER;
  {$IFDEF STRING_UNICODE_MISMATCH}
  LTemp: TIdPlatformString;
  {$ENDIF}
begin
  Result := 0;

  {$IFDEF STRING_UNICODE_MISMATCH}
  LTemp := TIdPlatformString(AFileName); // explicit convert to Ansi/Unicode
  {$ENDIF}

  LFileHandle := CreateFile(
    {$IFDEF STRING_UNICODE_MISMATCH}PIdPlatformChar(LTemp){$ELSE}PChar(UTF8toWinCP(AFileName)){$ENDIF}, <--- здесь
    GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);

если имя файла преобразовать через UTF8toWinCP(), то файл находит.
В своем коде конвертировать имя файла нельзя, так как по пути отработки в модуле iDIOHundlerSocket
Код: Выделить всё
function TIdIOHandlerSocket.WriteFile(const AFile: String;
  AEnableTransferFile: Boolean): Int64;
//TODO: There is a way in linux to dump a file to a socket as well. use it.
  {$IFDEF WIN32_OR_WIN64}
var
  LOldErrorMode : Integer;
  {$ENDIF}
begin
  Result := 0;
  {$IFDEF WIN32_OR_WIN64}
  LOldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
  try
  {$ENDIF}
  if FileExists(AFile) then begin  <---- здесь
    if Assigned(GServeFileProc) and (not WriteBufferingActive)
     {and (Intercept = nil)} and AEnableTransferFile 

FileExists(AFile) после преобразования не находит.
Но проблема еще не решена, так как коряво подставляеться общая информация в заголовок ответа сервера. Разбираюсь дальше.
Или у кого-то есть заведомо-рабочий код без изменений кода Инди?

Добавлено спустя 2 часа 17 минут 50 секунд:
Решил проблему по другому.
Так как проблема с уникодом єто не так проблема Инди, как проблема стандартов веба, то решил работать с файлами в виде Percent-encoding. На диске храню в таком виде, и пересылаю в таком виде. А саму информацию о файле отдаю уже в юникоде.
Аватара пользователя
GAMER
энтузиаст
 
Сообщения: 627
Зарегистрирован: 06.08.2008 13:41:07
Откуда: Ужгород-Днепр, Украина

Re: Indy, AResponseInfo.ServeFile, кирилица в названии файла

Сообщение Makhaon » 30.04.2019 12:24:31

Лекс Айрин писал(а):GAMER, конечно в своем. Поправлять код пакетов верный способ все испортить.

Это заблуждение. По собственному опыту правок. Правьте инди.
Или у кого-то есть заведомо-рабочий код без изменений кода Инди?

Быстрее будет самому что-то поправить.
Makhaon
новенький
 
Сообщения: 38
Зарегистрирован: 08.08.2018 15:23:24


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7

Рейтинг@Mail.ru