Ситуация такая: Есть виндовый файловый сервер, на котором хранятся файлы с очень длинными имена. При монтировании этой шары на балансировщик, для раздачи статики, периодически сыпались ошибки File name too long.
Проблема вроде ясная и очевидным решением было бы переименовать файлы с длинными именами. Но файлов этих сотни, возможно тысячи. Есть множество мест на сайте, которые ссылаются на эти файлы. Править ссылки вообще не вариант, как и сделать редиректы для файлов. Как уже сказал, таких файлов сотни и возможно тысячи.
Поэтому пришлось придумывать как это победить.
Проблема заключается в кодировке. При монтировании виндовой шары, где файлы названы на русском языке — дефолтная кодировка это utf-8, каждый русский символ которой занимает 2 байта. Ограничение наложенное на длинну имени файла в linux — 256 байт. При этом это завязанно не столько на ФС, сколько на уровне абстракции VFS. Именно в нем этот лимит закреплен жестко. Исходя из того, что кирилистический символ занимает 2 байта в utf-8, максимальная длинна имени файла ограничена 128 символами.
Решение:
1) Монтируем виндовую шару с указанием однобайтовой кирилистической кодировки cp1251 (она же виндовая windows-1251, стандартная виндовая кодировка):
//win-server/files /mnt/files cifs user,ro,credentials=/root/.smbcredentials,vers=2.1,echo_interval=10,iocharset=cp1251 0 0
2) Заставляем nginx (именно он у нас используется) обращаться к файлам на cp1251 кодировке, а не на стандартном utf-8:
Для это используем замечательный модуль от наших азиатских друзей: nginx-module-url.
Пересобираем и устанавливаем nginx c опцией —add-module=/path/to/nginx-module-url, как указана на сайте.
3) Добавляем в нужный нам location перекодировку utf-8 запросов в cp1251:
location /files { url_encoding_convert on; url_encoding_convert_from utf-8; url_encoding_convert_to windows-1251; expires max; root /mnt/; .... }
Всё! Проблема с длинными виндовыми именами в файлах решена! nginx прекрасно читает и передает на скачивание такие файлы.
No comments
RSS / trackback